{"id":720,"date":"2026-03-17T14:04:54","date_gmt":"2026-03-17T14:04:54","guid":{"rendered":"https:\/\/primetoolhub.com\/?page_id=720"},"modified":"2026-07-04T05:52:38","modified_gmt":"2026-07-04T05:52:38","slug":"ultimate-color-format-converter","status":"publish","type":"page","link":"https:\/\/schoolict.net\/tools\/ultimate-color-format-converter\/","title":{"rendered":"All-in-One Color Studio &amp; Color Format Converter (HEX, RGB, HSL, CMYK)"},"content":{"rendered":"\n<div class=\"pth-hero-section\">\n    <div class=\"pth-hero-content\">\n        <h2>All-in-One Color Studio &amp; Color Format Converter (HEX, RGB, HSL, CMYK)<\/h2>\n        <p>Convert HEX, RGB, HSL, and CMYK color codes instantly with this free, 100% offline color format converter. Features live visual preview and one-click CSS copy.<\/p>\n\n        <div id=\"pth-toc-placeholder\"><\/div>\n    <\/div>\n\n   \n  <div class=\"pth-hero-image\">\n    <img data-no-lazy=\"1\"\n         src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/03\/Color-Format-Converter-1024x572.jpeg\"\n         width=\"800\"\n         height=\"447\"\n         alt=\"Color Format Converter\"\n         fetchpriority=\"high\"\n         loading=\"eager\"\n         decoding=\"async\"\n         style=\"width:100%; height:auto; display:block;\">\n  <\/div>\n<\/div>\n\n\n\n\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><h2>Table of Contents<\/h2><nav><ul><li><a href=\"#\ud83d\udd34-why-color-format-conversion-matters-across-design-and-development-workflows\">\ud83d\udd34\u00a0Why Color Format Conversion Matters Across Design and Development Workflows<\/a><\/li><li><a href=\"#\ud83d\udfe1-wcag-2-1-contrast-ratios-the-mathematics-behind-pass-and-fail\">\ud83d\udfe1\u00a0WCAG 2.1 Contrast Ratios \u2014 The Mathematics Behind Pass and Fail<\/a><ul><li><a href=\"#\ud83d\udfe2-how-the-auto-fix-suggestion-works\">\ud83d\udfe2\u00a0How the Auto-Fix Suggestion Works<\/a><\/li><\/ul><\/li><li><a href=\"#\ud83d\udfe1-color-harmony-systems-what-each-palette-type-means-for-design\">\ud83d\udfe1\u00a0Color Harmony Systems \u2014 What Each Palette Type Means for Design<\/a><\/li><li><a href=\"#\ud83d\udfe1-image-color-picker-gradient-generator-and-css-output-formats\">\ud83d\udfe1\u00a0Image Color Picker, Gradient Generator, and CSS Output Formats<\/a><\/li><\/ul><\/nav><\/div>\n\n\n<style>\r\n\/* ============================================================\r\n   PTH COLOR STUDIO \u2014 v2.0\r\n   AdSense + PageSpeed 100 + WCAG 2.1 AA + WP\/LiteSpeed Safe\r\n   5 Tabs | 22 Tools | 100% Offline | Zero CDN\r\n   ============================================================ *\/\r\n#pth-color-wrapper {\r\n    font-family: 'Inter', system-ui, sans-serif;\r\n    width: 100%; max-width: 1400px; margin: 0 auto;\r\n    box-sizing: border-box; background: #f8fafc;\r\n    padding: 20px; border-radius: 16px;\r\n    color: #1e293b; font-weight: 500;\r\n}\r\n#pth-color-wrapper * { box-sizing: border-box; min-width: 0; }\r\n#pth-color-wrapper h2,\r\n#pth-color-wrapper h3,\r\n#pth-color-wrapper h4 { color: #0f172a; font-weight: 800; margin-top: 0; }\r\n#pth-color-wrapper .pth-tool-title {\r\n    font-size: 26px; font-weight: 800; color: #1d4ed8; margin: 0;\r\n}\r\n\r\n\/* \u2500\u2500 Cards \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-card {\r\n    background: #fff; border: 1px solid #e2e8f0;\r\n    border-radius: 12px; padding: 20px; margin-bottom: 16px;\r\n    box-shadow: 0 4px 6px -1px rgba(0,0,0,0.04);\r\n}\r\n#pth-color-wrapper .pth-card-hdr {\r\n    background: #f8fafc; margin: -20px -20px 16px -20px;\r\n    padding: 10px 16px; color: #1d4ed8; font-size: 12px;\r\n    border-bottom: 2px solid #eff6ff; font-weight: 800;\r\n    text-transform: uppercase; border-radius: 12px 12px 0 0;\r\n    letter-spacing: 0.5px;\r\n}\r\n\r\n\/* \u2500\u2500 Meta bar \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-tool-meta-bar {\r\n    display: flex; align-items: center; gap: 10px;\r\n    flex-wrap: wrap; margin-bottom: 16px;\r\n}\r\n#pth-color-wrapper .pth-version-badge {\r\n    background: #eff6ff; color: #1d4ed8; border: 1px solid #bfdbfe;\r\n    font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 4px;\r\n}\r\n#pth-color-wrapper .pth-status-offline {\r\n    background: #f0fdf4; color: #15803d; border: 1px solid #bbf7d0;\r\n    font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 4px;\r\n}\r\n\r\n\/* \u2500\u2500 Layout \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-flex-layout {\r\n    display: grid; grid-template-columns: 1.8fr 1fr;\r\n    gap: 20px; align-items: start;\r\n}\r\n#pth-color-wrapper .pth-flex-layout.pth-full-width {\r\n    grid-template-columns: 100%;\r\n}\r\n\r\n\/* \u2500\u2500 Tabs \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-tabs-nav {\r\n    display: flex; gap: 4px; flex-wrap: wrap;\r\n    margin-bottom: 20px; border-bottom: 2px solid #e2e8f0; padding-bottom: 0;\r\n}\r\n#pth-color-wrapper .pth-tab-btn {\r\n    padding: 8px 14px; border-radius: 8px 8px 0 0;\r\n    font-size: 12px; font-weight: 700; cursor: pointer;\r\n    border: 2px solid transparent; border-bottom: none;\r\n    background: #f1f5f9; color: #334155;\r\n    transition: 0.15s; font-family: 'Inter', sans-serif;\r\n    margin-bottom: -2px; white-space: nowrap;\r\n}\r\n#pth-color-wrapper .pth-tab-btn:hover { background: #e2e8f0; color: #0f172a; }\r\n#pth-color-wrapper .pth-tab-btn.pth-active {\r\n    background: #fff; color: #1d4ed8;\r\n    border-color: #e2e8f0; border-bottom-color: #fff;\r\n}\r\n\r\n\/* \u2500\u2500 Buttons \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-btn {\r\n    padding: 9px 18px; border-radius: 8px; font-weight: 700;\r\n    cursor: pointer; border: none; font-family: 'Inter', sans-serif;\r\n    font-size: 13px; transition: 0.2s; display: inline-flex;\r\n    align-items: center; justify-content: center; gap: 6px;\r\n}\r\n#pth-color-wrapper .pth-btn-primary { background: #2563eb; color: #fff; }\r\n#pth-color-wrapper .pth-btn-primary:hover { background: #1d4ed8; }\r\n#pth-color-wrapper .pth-btn-secondary {\r\n    background: #f1f5f9; color: #334155; border: 1px solid #e2e8f0;\r\n}\r\n#pth-color-wrapper .pth-btn-secondary:hover { background: #e2e8f0; }\r\n#pth-color-wrapper .pth-btn-success { background: #059669; color: #fff; }\r\n#pth-color-wrapper .pth-btn-success:hover { background: #047857; }\r\n#pth-color-wrapper .pth-btn-danger {\r\n    background: #fef2f2; color: #991b1b; border: 1px solid #fecaca;\r\n}\r\n#pth-color-wrapper .pth-btn-danger:hover { background: #fee2e2; }\r\n#pth-color-wrapper .pth-sample-btn {\r\n    background: #d1fae5; color: #047857; border: 1px solid #10b981;\r\n    font-size: 0.75rem; padding: 4px 10px; border-radius: 6px;\r\n    font-weight: 700; cursor: pointer; transition: 0.2s;\r\n    display: inline-flex; align-items: center; gap: 4px;\r\n}\r\n#pth-color-wrapper .pth-sample-btn:hover { background: #a7f3d0; }\r\n\r\n\/* \u2500\u2500 Form elements \u2500\u2500 *\/\r\n#pth-color-wrapper label {\r\n    font-weight: 700; color: #0f172a; margin-bottom: 5px;\r\n    display: block; font-size: 12px;\r\n    text-transform: uppercase; letter-spacing: 0.4px;\r\n}\r\n#pth-color-wrapper input[type=\"text\"],\r\n#pth-color-wrapper input[type=\"number\"],\r\n#pth-color-wrapper select {\r\n    width: 100%; padding: 9px 12px; border: 2px solid #e2e8f0;\r\n    border-radius: 8px; font-family: 'Inter', sans-serif;\r\n    font-size: 13px; color: #0f172a; background: #fff; transition: 0.2s;\r\n}\r\n#pth-color-wrapper input:focus, #pth-color-wrapper select:focus {\r\n    border-color: #3b82f6; outline: none;\r\n    box-shadow: 0 0 0 3px rgba(59,130,246,0.1);\r\n}\r\n#pth-color-wrapper .pth-field { margin-bottom: 14px; }\r\n#pth-color-wrapper .pth-row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }\r\n#pth-color-wrapper .pth-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 10px; }\r\n\r\n\/* \u2500\u2500 Main color preview \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-color-hero {\r\n    width: 100%; height: 120px; border-radius: 12px;\r\n    border: 2px solid #e2e8f0; margin-bottom: 16px;\r\n    transition: background-color 0.3s; cursor: pointer;\r\n    position: relative; overflow: hidden;\r\n    display: flex; align-items: center; justify-content: center;\r\n}\r\n#pth-color-wrapper .pth-color-hero-hex {\r\n    font-size: 22px; font-weight: 800; letter-spacing: 2px;\r\n    text-shadow: 0 2px 6px rgba(0,0,0,0.3);\r\n    pointer-events: none;\r\n}\r\n#pth-color-wrapper .pth-picker-row {\r\n    display: flex; align-items: center; gap: 12px; margin-bottom: 16px;\r\n}\r\n#pth-color-wrapper .pth-native-picker {\r\n    width: 52px; height: 52px; border-radius: 10px;\r\n    border: 2px solid #e2e8f0; cursor: pointer; padding: 3px;\r\n    background: #fff;\r\n}\r\n#pth-color-wrapper .pth-picker-label {\r\n    font-size: 12px; color: #334155; font-weight: 600;\r\n}\r\n\r\n\/* \u2500\u2500 Format rows \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-fmt-row {\r\n    display: flex; gap: 8px; align-items: center; margin-bottom: 10px;\r\n}\r\n#pth-color-wrapper .pth-fmt-label {\r\n    font-size: 11px; font-weight: 800; color: #334155;\r\n    text-transform: uppercase; min-width: 42px; letter-spacing: 0.4px;\r\n}\r\n#pth-color-wrapper .pth-fmt-input {\r\n    flex: 1; padding: 8px 12px; border: 2px solid #e2e8f0;\r\n    border-radius: 8px; font-family: 'Courier New', monospace;\r\n    font-size: 13px; color: #0f172a; background: #f8fafc;\r\n    cursor: text;\r\n}\r\n#pth-color-wrapper .pth-fmt-input:focus {\r\n    border-color: #3b82f6; outline: none; background: #fff;\r\n    box-shadow: 0 0 0 3px rgba(59,130,246,0.1);\r\n}\r\n#pth-color-wrapper .pth-copy-btn {\r\n    padding: 7px 12px; border-radius: 8px; font-size: 11px;\r\n    font-weight: 700; cursor: pointer; border: 1px solid #e2e8f0;\r\n    background: #f8fafc; color: #334155; transition: 0.15s;\r\n    white-space: nowrap; font-family: 'Inter', sans-serif;\r\n}\r\n#pth-color-wrapper .pth-copy-btn:hover { background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe; }\r\n#pth-color-wrapper .pth-copy-btn.copied { background: #f0fdf4; color: #047857; border-color: #bbf7d0; }\r\n\r\n\/* \u2500\u2500 Color info badges \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-info-badges {\r\n    display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px;\r\n}\r\n#pth-color-wrapper .pth-info-badge {\r\n    font-size: 11px; font-weight: 700; padding: 3px 10px;\r\n    border-radius: 20px; border: 1px solid; display: inline-flex;\r\n    align-items: center; gap: 5px;\r\n}\r\n#pth-color-wrapper .pth-badge-named {\r\n    background: #faf5ff; color: #5b21b6; border-color: #ddd6fe;\r\n}\r\n#pth-color-wrapper .pth-badge-tailwind {\r\n    background: #eff6ff; color: #1d4ed8; border-color: #bfdbfe;\r\n}\r\n#pth-color-wrapper .pth-badge-lum {\r\n    background: #f8fafc; color: #334155; border-color: #e2e8f0;\r\n}\r\n\r\n\/* \u2500\u2500 WCAG Contrast \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-contrast-grid {\r\n    display: grid; grid-template-columns: 1fr 1fr; gap: 12px;\r\n    margin-bottom: 14px;\r\n}\r\n#pth-color-wrapper .pth-contrast-box {\r\n    border-radius: 10px; padding: 16px; min-height: 80px;\r\n    display: flex; flex-direction: column; justify-content: space-between;\r\n    border: 1px solid #e2e8f0; transition: background-color 0.3s;\r\n}\r\n#pth-color-wrapper .pth-contrast-sample {\r\n    font-size: 15px; font-weight: 700; margin-bottom: 8px;\r\n}\r\n#pth-color-wrapper .pth-contrast-sample.small {\r\n    font-size: 13px; font-weight: 500;\r\n}\r\n#pth-color-wrapper .pth-contrast-meta {\r\n    display: flex; justify-content: space-between; align-items: center;\r\n}\r\n#pth-color-wrapper .pth-contrast-ratio {\r\n    font-size: 11px; font-weight: 800; color: #334155;\r\n}\r\n#pth-color-wrapper .pth-wcag-badges { display: flex; gap: 4px; flex-wrap: wrap; }\r\n#pth-color-wrapper .pth-wcag-badge {\r\n    font-size: 10px; font-weight: 800; padding: 2px 7px;\r\n    border-radius: 4px; text-transform: uppercase;\r\n}\r\n#pth-color-wrapper .pth-wcag-pass { background: #059669; color: #fff; }\r\n#pth-color-wrapper .pth-wcag-fail { background: #dc2626; color: #fff; }\r\n#pth-color-wrapper .pth-wcag-aaa  { background: #047857; color: #fff; }\r\n\r\n\/* \u2500\u2500 Suggest fix \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-fix-suggestion {\r\n    background: #fffbeb; border: 1px solid #fde68a; border-radius: 8px;\r\n    padding: 12px; margin-top: 10px; font-size: 12px;\r\n    color: #92400e; font-weight: 600; display: none;\r\n}\r\n#pth-color-wrapper .pth-fix-suggestion.pth-visible { display: block; }\r\n\r\n\/* \u2500\u2500 Palette swatches \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-swatch-row {\r\n    display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 12px;\r\n}\r\n#pth-color-wrapper .pth-swatch {\r\n    width: 48px; height: 48px; border-radius: 8px; cursor: pointer;\r\n    border: 2px solid transparent; transition: 0.15s; position: relative;\r\n    flex-shrink: 0;\r\n}\r\n#pth-color-wrapper .pth-swatch:hover { transform: scale(1.12); border-color: #0f172a; z-index: 1; }\r\n#pth-color-wrapper .pth-swatch-label {\r\n    position: absolute; bottom: -18px; left: 50%;\r\n    transform: translateX(-50%); font-size: 9px; font-weight: 700;\r\n    color: #334155; white-space: nowrap; pointer-events: none;\r\n}\r\n#pth-color-wrapper .pth-swatch-wrap {\r\n    position: relative; margin-bottom: 20px;\r\n}\r\n#pth-color-wrapper .pth-palette-section { margin-bottom: 20px; }\r\n#pth-color-wrapper .pth-palette-title {\r\n    font-size: 11px; font-weight: 800; color: #334155;\r\n    text-transform: uppercase; letter-spacing: 0.5px;\r\n    margin-bottom: 10px; display: flex; justify-content: space-between;\r\n    align-items: center;\r\n}\r\n#pth-color-wrapper .pth-shades-grid {\r\n    display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px;\r\n}\r\n#pth-color-wrapper .pth-shade-box {\r\n    height: 40px; border-radius: 6px; cursor: pointer;\r\n    border: 1px solid rgba(0,0,0,0.08); transition: 0.15s;\r\n    position: relative;\r\n}\r\n#pth-color-wrapper .pth-shade-box:hover { transform: scale(1.1); z-index: 1; }\r\n\r\n\/* \u2500\u2500 Color Mixer \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-mixer-preview {\r\n    display: grid; grid-template-columns: 1fr 1fr 1fr;\r\n    gap: 12px; margin-bottom: 16px;\r\n}\r\n#pth-color-wrapper .pth-mixer-box {\r\n    height: 80px; border-radius: 10px;\r\n    border: 2px solid #e2e8f0; transition: background-color 0.3s;\r\n    display: flex; align-items: center; justify-content: center;\r\n    font-size: 11px; font-weight: 800; letter-spacing: 1px;\r\n    text-shadow: 0 1px 3px rgba(0,0,0,0.3);\r\n    cursor: pointer;\r\n}\r\n#pth-color-wrapper .pth-mixer-label {\r\n    text-align: center; font-size: 11px; font-weight: 700;\r\n    color: #334155; margin-top: 4px; margin-bottom: 12px;\r\n}\r\n\r\n\/* \u2500\u2500 Gradient generator \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-gradient-preview {\r\n    height: 80px; border-radius: 10px; border: 2px solid #e2e8f0;\r\n    margin-bottom: 14px; transition: background 0.3s;\r\n}\r\n#pth-color-wrapper .pth-gradient-css {\r\n    background: #0f172a; color: #4ade80; padding: 12px 14px;\r\n    border-radius: 8px; font-family: 'Courier New', monospace;\r\n    font-size: 12px; line-height: 1.5; min-height: 60px;\r\n    word-break: break-all; white-space: pre-wrap;\r\n    border: 2px solid #1e293b;\r\n}\r\n\r\n\/* \u2500\u2500 Color blindness simulator \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-cb-grid {\r\n    display: grid; grid-template-columns: 1fr 1fr; gap: 10px;\r\n}\r\n#pth-color-wrapper .pth-cb-item {\r\n    border-radius: 10px; padding: 14px;\r\n    border: 1px solid #e2e8f0; text-align: center;\r\n}\r\n#pth-color-wrapper .pth-cb-swatch {\r\n    width: 100%; height: 50px; border-radius: 8px;\r\n    margin-bottom: 8px; border: 1px solid rgba(0,0,0,0.1);\r\n    transition: background-color 0.3s;\r\n}\r\n#pth-color-wrapper .pth-cb-label {\r\n    font-size: 11px; font-weight: 800; color: #0f172a;\r\n    text-transform: uppercase; letter-spacing: 0.4px; margin-bottom: 4px;\r\n}\r\n#pth-color-wrapper .pth-cb-desc {\r\n    font-size: 10px; color: #334155; font-weight: 500;\r\n}\r\n\r\n\/* \u2500\u2500 CSS Output \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-css-output {\r\n    background: #0f172a; color: #a78bfa; padding: 14px;\r\n    border-radius: 10px; font-family: 'Courier New', monospace;\r\n    font-size: 12px; line-height: 1.8; min-height: 100px;\r\n    word-break: break-all; white-space: pre-wrap;\r\n    border: 2px solid #1e293b; max-height: 280px; overflow-y: auto;\r\n}\r\n#pth-color-wrapper .pth-css-prop { color: #7dd3fc; }\r\n#pth-color-wrapper .pth-css-val  { color: #86efac; }\r\n\r\n\/* \u2500\u2500 Image picker canvas \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-img-drop-zone {\r\n    border: 2px dashed #c4b5fd; border-radius: 12px;\r\n    background: #faf5ff; padding: 24px; text-align: center;\r\n    cursor: pointer; transition: 0.2s; margin-bottom: 14px;\r\n}\r\n#pth-color-wrapper .pth-img-drop-zone:hover,\r\n#pth-color-wrapper .pth-img-drop-zone.drag-over {\r\n    border-color: #7c3aed; background: #ede9fe;\r\n}\r\n#pth-color-wrapper .pth-img-canvas-wrap {\r\n    position: relative; display: none; margin-bottom: 14px;\r\n}\r\n#pth-color-wrapper .pth-img-canvas {\r\n    width: 100%; border-radius: 10px; cursor: crosshair;\r\n    border: 2px solid #e2e8f0; display: block; max-height: 260px;\r\n    object-fit: contain;\r\n}\r\n#pth-color-wrapper .pth-img-crosshair {\r\n    position: absolute; width: 20px; height: 20px;\r\n    border: 2px solid #fff; border-radius: 50%;\r\n    pointer-events: none; display: none;\r\n    box-shadow: 0 0 0 2px #0f172a; transform: translate(-50%, -50%);\r\n}\r\n#pth-color-wrapper .pth-picked-color-bar {\r\n    display: none; padding: 12px 16px; border-radius: 8px;\r\n    margin-bottom: 12px; align-items: center; gap: 12px;\r\n}\r\n\r\n\/* \u2500\u2500 Sidebar \u2500\u2500 *\/\r\n#pth-color-wrapper .pth-sidebar-hdr {\r\n    background: #f8fafc; margin: -20px -20px 16px -20px;\r\n    padding: 10px 16px; color: #1d4ed8; font-size: 12px;\r\n    border-bottom: 2px solid #eff6ff; font-weight: 800;\r\n    text-transform: uppercase; border-radius: 12px 12px 0 0;\r\n    letter-spacing: 0.5px;\r\n}\r\n#pth-color-wrapper .pth-color-history {\r\n    display: flex; flex-wrap: wrap; gap: 8px;\r\n}\r\n#pth-color-wrapper .pth-history-swatch {\r\n    width: 32px; height: 32px; border-radius: 6px;\r\n    cursor: pointer; border: 2px solid #e2e8f0;\r\n    transition: 0.15s; flex-shrink: 0;\r\n}\r\n#pth-color-wrapper .pth-history-swatch:hover {\r\n    transform: scale(1.15); border-color: #0f172a;\r\n}\r\n#pth-color-wrapper .pth-preset-grid {\r\n    display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px;\r\n}\r\n#pth-color-wrapper .pth-preset-swatch {\r\n    height: 28px; border-radius: 6px; cursor: pointer;\r\n    border: 1px solid rgba(0,0,0,0.1); transition: 0.15s;\r\n}\r\n#pth-color-wrapper .pth-preset-swatch:hover { transform: scale(1.12); }\r\n\r\n\/* \u2500\u2500 Toast \u2500\u2500 *\/\r\n#pth-color-toast {\r\n    position: fixed; bottom: 24px; right: 24px; z-index: 9999;\r\n    display: flex; flex-direction: column; gap: 10px; pointer-events: none;\r\n}\r\n.pth-toast-msg {\r\n    padding: 12px 20px; border-radius: 10px; font-size: 14px;\r\n    font-weight: 600; color: #fff; pointer-events: auto;\r\n    box-shadow: 0 4px 15px rgba(0,0,0,0.15);\r\n    font-family: 'Inter', system-ui, sans-serif;\r\n}\r\n.pth-toast-success { background: #059669; }\r\n.pth-toast-error   { background: #dc2626; }\r\n.pth-toast-info    { background: #2563eb; }\r\n\r\n\/* \u2500\u2500 Mobile \u2500\u2500 *\/\r\n@media (max-width: 768px) {\r\n    #pth-color-wrapper {\r\n        padding: 10px; border-radius: 0;\r\n        background: transparent; width: 100% !important;\r\n    }\r\n    #pth-color-wrapper .pth-card { padding: 14px; margin-bottom: 12px; }\r\n    #pth-color-wrapper .pth-flex-layout { grid-template-columns: 100% !important; gap: 12px; }\r\n    #pth-color-wrapper .pth-tool-title { font-size: 20px; }\r\n    #pth-color-wrapper .pth-row-2 { grid-template-columns: 1fr; }\r\n    #pth-color-wrapper .pth-row-3 { grid-template-columns: 1fr 1fr; }\r\n    #pth-color-wrapper .pth-contrast-grid { grid-template-columns: 1fr; }\r\n    #pth-color-wrapper .pth-mixer-preview { grid-template-columns: 1fr 1fr 1fr; }\r\n    #pth-color-wrapper .pth-shades-grid { grid-template-columns: repeat(5, 1fr); }\r\n    #pth-color-wrapper .pth-cb-grid { grid-template-columns: 1fr 1fr; }\r\n    #pth-color-wrapper .pth-tabs-nav { gap: 3px; }\r\n    #pth-color-wrapper .pth-tab-btn { font-size: 11px; padding: 6px 10px; }\r\n}\r\n<\/style>\r\n\r\n<div id=\"pth-color-toast\" role=\"status\" aria-live=\"polite\"><\/div>\r\n\r\n<div id=\"pth-color-wrapper\">\r\n<div class=\"pth-flex-layout\" id=\"pth-color-layout\">\r\n\r\n<!-- \u2550\u2550\u2550 MAIN COLUMN \u2550\u2550\u2550 -->\r\n<div class=\"pth-main-col\">\r\n<div class=\"pth-card\">\r\n\r\n    <!-- Header -->\r\n    <div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:12px;flex-wrap:wrap;gap:10px;\">\r\n        <h2 class=\"pth-tool-title\">\ud83c\udfa8 Color Studio Pro<\/h2>\r\n        <button class=\"pth-btn pth-btn-secondary\" id=\"pth-cs-fw-btn\"\r\n            aria-label=\"Toggle full width layout\">\u26f6 Full Width<\/button>\r\n    <\/div>\r\n    <div class=\"pth-tool-meta-bar\">\r\n        <span class=\"pth-version-badge\">v2.0<\/span>\r\n        <span class=\"pth-status-offline\">\ud83d\udd12 100% Offline<\/span>\r\n        <span style=\"font-size:11px;font-weight:700;color:#334155;\">5 Tabs \u00b7 22 Tools<\/span>\r\n    <\/div>\r\n\r\n    <!-- Action bar -->\r\n    <div style=\"display:flex;gap:8px;flex-wrap:wrap;margin-bottom:16px;\">\r\n        <button class=\"pth-sample-btn\" id=\"pth-cs-sample-btn\"\r\n            aria-label=\"Load sample color\">\ud83d\udca1 Load Sample<\/button>\r\n        <button class=\"pth-btn pth-btn-secondary\" id=\"pth-cs-random-btn\"\r\n            style=\"font-size:0.75rem;padding:4px 12px;border-radius:6px;\"\r\n            aria-label=\"Generate random color\">\ud83c\udfb2 Random<\/button>\r\n        <button class=\"pth-btn pth-btn-danger\" id=\"pth-cs-clear-btn\"\r\n            style=\"font-size:0.75rem;padding:4px 10px;border-radius:6px;\"\r\n            aria-label=\"Reset to default color\">\ud83d\uddd1\ufe0f Reset<\/button>\r\n    <\/div>\r\n\r\n    <!-- Main color preview -->\r\n    <div class=\"pth-color-hero\" id=\"pth-color-hero\"\r\n        style=\"background:#2563eb;\"\r\n        role=\"img\" aria-label=\"Color preview swatch\">\r\n        <span class=\"pth-color-hero-hex\" id=\"pth-hero-hex\" style=\"color:#fff;\">#2563EB<\/span>\r\n    <\/div>\r\n\r\n    <!-- Picker row -->\r\n    <div class=\"pth-picker-row\">\r\n        <input type=\"color\" id=\"pth-native-picker\" value=\"#2563eb\"\r\n            class=\"pth-native-picker\" aria-label=\"Color picker\">\r\n        <div>\r\n            <div style=\"font-size:13px;font-weight:700;color:#0f172a;\">Click swatch or use picker<\/div>\r\n            <div class=\"pth-picker-label\">Supports HEX, RGB, HSL, HSB, CMYK, LAB inputs<\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- Info badges -->\r\n    <div class=\"pth-info-badges\" id=\"pth-info-badges\">\r\n        <span class=\"pth-info-badge pth-badge-named\" id=\"pth-badge-named\">\ud83c\udff7\ufe0f Loading\u2026<\/span>\r\n        <span class=\"pth-info-badge pth-badge-tailwind\" id=\"pth-badge-tailwind\">\ud83d\udca8 Loading\u2026<\/span>\r\n        <span class=\"pth-info-badge pth-badge-lum\" id=\"pth-badge-lum\">\u2600\ufe0f Loading\u2026<\/span>\r\n    <\/div>\r\n\r\n    <!-- Tab Navigation -->\r\n    <div class=\"pth-tabs-nav\" role=\"tablist\">\r\n        <button class=\"pth-tab-btn pth-active\" data-tab=\"convert\"\r\n            role=\"tab\" aria-selected=\"true\" aria-label=\"Color formats converter\">\ud83d\udd04 Convert<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"contrast\"\r\n            role=\"tab\" aria-selected=\"false\" aria-label=\"WCAG contrast checker\">\ud83d\udd0d Contrast<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"palette\"\r\n            role=\"tab\" aria-selected=\"false\" aria-label=\"Color palette generator\">\ud83c\udf08 Palette<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"tools\"\r\n            role=\"tab\" aria-selected=\"false\" aria-label=\"Color tools\">\ud83d\udee0\ufe0f Tools<\/button>\r\n        <button class=\"pth-tab-btn\" data-tab=\"css\"\r\n            role=\"tab\" aria-selected=\"false\" aria-label=\"CSS output generator\">\ud83d\udcbb CSS Output<\/button>\r\n    <\/div>\r\n\r\n    <!-- \u2550\u2550 TAB 1: CONVERT \u2550\u2550 -->\r\n    <div id=\"pth-tab-convert\" role=\"tabpanel\">\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83d\udd04 Color Format Converter \u2014 type in any field<\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">HEX<\/span>\r\n                <input type=\"text\" id=\"pth-in-hex\" class=\"pth-fmt-input\"\r\n                    value=\"#2563EB\" aria-label=\"HEX color value\" placeholder=\"#RRGGBB\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-hex\"\r\n                    aria-label=\"Copy HEX value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">RGB<\/span>\r\n                <input type=\"text\" id=\"pth-in-rgb\" class=\"pth-fmt-input\"\r\n                    aria-label=\"RGB color value\" placeholder=\"rgb(37, 99, 235)\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-rgb\"\r\n                    aria-label=\"Copy RGB value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">HSL<\/span>\r\n                <input type=\"text\" id=\"pth-in-hsl\" class=\"pth-fmt-input\"\r\n                    aria-label=\"HSL color value\" placeholder=\"hsl(221, 83%, 53%)\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-hsl\"\r\n                    aria-label=\"Copy HSL value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">HSB<\/span>\r\n                <input type=\"text\" id=\"pth-in-hsb\" class=\"pth-fmt-input\"\r\n                    aria-label=\"HSB color value\" placeholder=\"hsb(221, 84%, 92%)\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-hsb\"\r\n                    aria-label=\"Copy HSB value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">CMYK<\/span>\r\n                <input type=\"text\" id=\"pth-in-cmyk\" class=\"pth-fmt-input\"\r\n                    aria-label=\"CMYK color value\" placeholder=\"cmyk(84%, 58%, 0%, 8%)\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-cmyk\"\r\n                    aria-label=\"Copy CMYK value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">LAB<\/span>\r\n                <input type=\"text\" id=\"pth-in-lab\" class=\"pth-fmt-input\"\r\n                    aria-label=\"LAB color value\" placeholder=\"lab(43, 16, -58)\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-lab\"\r\n                    aria-label=\"Copy LAB value\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <div class=\"pth-fmt-row\">\r\n                <span class=\"pth-fmt-label\">CSS Var<\/span>\r\n                <input type=\"text\" id=\"pth-in-cssvar\" class=\"pth-fmt-input\"\r\n                    aria-label=\"CSS custom property variable\" placeholder=\"--color-primary: #2563EB;\">\r\n                <button class=\"pth-copy-btn\" data-copy=\"pth-in-cssvar\"\r\n                    aria-label=\"Copy CSS variable\">\ud83d\udccb Copy<\/button>\r\n            <\/div>\r\n            <button class=\"pth-btn pth-btn-success\" id=\"pth-copy-all-btn\"\r\n                style=\"width:100%;margin-top:8px;\"\r\n                aria-label=\"Copy all color formats to clipboard\">\r\n                \ud83d\udccb Copy All Formats\r\n            <\/button>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- \u2550\u2550 TAB 2: CONTRAST \u2550\u2550 -->\r\n    <div id=\"pth-tab-contrast\" style=\"display:none;\" role=\"tabpanel\">\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83d\udd0d WCAG 2.1 Contrast Checker<\/div>\r\n            <div class=\"pth-contrast-grid\" id=\"pth-contrast-grid\">\r\n                <div class=\"pth-contrast-box\" id=\"pth-cb-white\">\r\n                    <div class=\"pth-contrast-sample\" style=\"color:#fff;\">Aa Large Text<\/div>\r\n                    <div class=\"pth-contrast-sample small\" style=\"color:#fff;\">Normal text sample<\/div>\r\n                    <div class=\"pth-contrast-meta\">\r\n                        <span class=\"pth-contrast-ratio\" id=\"pth-ratio-white\" style=\"color:#fff;\">\u2014:1<\/span>\r\n                        <div class=\"pth-wcag-badges\" id=\"pth-badges-white\"><\/div>\r\n                    <\/div>\r\n                <\/div>\r\n                <div class=\"pth-contrast-box\" id=\"pth-cb-black\">\r\n                    <div class=\"pth-contrast-sample\" style=\"color:#000;\">Aa Large Text<\/div>\r\n                    <div class=\"pth-contrast-sample small\" style=\"color:#000;\">Normal text sample<\/div>\r\n                    <div class=\"pth-contrast-meta\">\r\n                        <span class=\"pth-contrast-ratio\" id=\"pth-ratio-black\" style=\"color:#000;\">\u2014:1<\/span>\r\n                        <div class=\"pth-wcag-badges\" id=\"pth-badges-black\"><\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n            <!-- Custom contrast -->\r\n            <div style=\"margin-bottom:14px;\">\r\n                <div style=\"display:flex;gap:10px;align-items:center;margin-bottom:10px;flex-wrap:wrap;\">\r\n                    <label for=\"pth-custom-contrast-picker\"\r\n                        style=\"text-transform:none;font-size:13px;font-weight:700;color:#0f172a;margin:0;\">\r\n                        Custom Text Color:\r\n                    <\/label>\r\n                    <input type=\"color\" id=\"pth-custom-contrast-picker\" value=\"#ffffff\"\r\n                        style=\"width:40px;height:36px;border-radius:8px;border:2px solid #e2e8f0;cursor:pointer;padding:2px;\"\r\n                        aria-label=\"Custom text color for contrast check\">\r\n                    <span id=\"pth-custom-color-label\"\r\n                        style=\"font-size:13px;font-weight:700;color:#334155;\">#FFFFFF<\/span>\r\n                <\/div>\r\n                <div class=\"pth-contrast-box\" id=\"pth-cb-custom\">\r\n                    <div class=\"pth-contrast-sample\" id=\"pth-custom-sample-lg\"\r\n                        style=\"color:#fff;\">Aa Large Text (Custom)<\/div>\r\n                    <div class=\"pth-contrast-sample small\" id=\"pth-custom-sample-sm\"\r\n                        style=\"color:#fff;\">Normal text sample (Custom)<\/div>\r\n                    <div class=\"pth-contrast-meta\">\r\n                        <span class=\"pth-contrast-ratio\" id=\"pth-ratio-custom\" style=\"color:#fff;\">\u2014:1<\/span>\r\n                        <div class=\"pth-wcag-badges\" id=\"pth-badges-custom\"><\/div>\r\n                    <\/div>\r\n                <\/div>\r\n            <\/div>\r\n            <!-- Fix suggestion -->\r\n            <div class=\"pth-fix-suggestion\" id=\"pth-fix-suggestion\">\r\n                \ud83d\udca1 <strong>Suggested fix:<\/strong> <span id=\"pth-fix-text\"><\/span>\r\n            <\/div>\r\n            <!-- WCAG Guide -->\r\n            <div style=\"background:#f8fafc;border-radius:8px;padding:12px;font-size:11px;color:#334155;line-height:1.8;font-weight:600;\">\r\n                <strong style=\"color:#0f172a;\">WCAG 2.1 Thresholds:<\/strong><br>\r\n                AA Normal Text: 4.5:1 \u00b7 AA Large Text (18pt+): 3:1 \u00b7 AAA Normal: 7:1 \u00b7 AAA Large: 4.5:1 \u00b7 UI Components: 3:1\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- \u2550\u2550 TAB 3: PALETTE \u2550\u2550 -->\r\n    <div id=\"pth-tab-palette\" style=\"display:none;\" role=\"tabpanel\">\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83c\udf08 Palette Generator<\/div>\r\n\r\n            <!-- Tints & Shades -->\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\">\r\n                    <span>Tints &amp; Shades (10 Steps)<\/span>\r\n                    <button class=\"pth-copy-btn\" id=\"pth-copy-shades-css\"\r\n                        aria-label=\"Copy shades as CSS variables\">\ud83d\udccb Copy CSS Vars<\/button>\r\n                <\/div>\r\n                <div class=\"pth-shades-grid\" id=\"pth-shades-grid\"><\/div>\r\n            <\/div>\r\n\r\n            <!-- Harmony palettes -->\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\"><span>\ud83d\udd04 Complementary<\/span>\r\n                    <button class=\"pth-copy-btn\" data-palette=\"complementary\"\r\n                        aria-label=\"Copy complementary palette\">\ud83d\udccb Copy<\/button>\r\n                <\/div>\r\n                <div class=\"pth-swatch-row\" id=\"pth-palette-complementary\"><\/div>\r\n            <\/div>\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\"><span>\ud83d\udd3a Triadic<\/span>\r\n                    <button class=\"pth-copy-btn\" data-palette=\"triadic\"\r\n                        aria-label=\"Copy triadic palette\">\ud83d\udccb Copy<\/button>\r\n                <\/div>\r\n                <div class=\"pth-swatch-row\" id=\"pth-palette-triadic\"><\/div>\r\n            <\/div>\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\"><span>\u3030\ufe0f Analogous<\/span>\r\n                    <button class=\"pth-copy-btn\" data-palette=\"analogous\"\r\n                        aria-label=\"Copy analogous palette\">\ud83d\udccb Copy<\/button>\r\n                <\/div>\r\n                <div class=\"pth-swatch-row\" id=\"pth-palette-analogous\"><\/div>\r\n            <\/div>\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\"><span>\u2702\ufe0f Split-Complementary<\/span>\r\n                    <button class=\"pth-copy-btn\" data-palette=\"split\"\r\n                        aria-label=\"Copy split complementary palette\">\ud83d\udccb Copy<\/button>\r\n                <\/div>\r\n                <div class=\"pth-swatch-row\" id=\"pth-palette-split\"><\/div>\r\n            <\/div>\r\n            <div class=\"pth-palette-section\">\r\n                <div class=\"pth-palette-title\"><span>\u2b1b Monochromatic<\/span>\r\n                    <button class=\"pth-copy-btn\" data-palette=\"mono\"\r\n                        aria-label=\"Copy monochromatic palette\">\ud83d\udccb Copy<\/button>\r\n                <\/div>\r\n                <div class=\"pth-swatch-row\" id=\"pth-palette-mono\"><\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- \u2550\u2550 TAB 4: TOOLS \u2550\u2550 -->\r\n    <div id=\"pth-tab-tools\" style=\"display:none;\" role=\"tabpanel\">\r\n\r\n        <!-- Color Mixer -->\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83e\uddea Color Mixer<\/div>\r\n            <div class=\"pth-mixer-preview\">\r\n                <div>\r\n                    <div class=\"pth-mixer-box\" id=\"pth-mix-a\" style=\"background:#2563eb;color:#fff;\">A<\/div>\r\n                    <div class=\"pth-mixer-label\">Color A<\/div>\r\n                <\/div>\r\n                <div>\r\n                    <div class=\"pth-mixer-box\" id=\"pth-mix-result\" style=\"background:#c4b5fd;color:#1e293b;\">MIX<\/div>\r\n                    <div class=\"pth-mixer-label\" id=\"pth-mix-result-label\">Result<\/div>\r\n                <\/div>\r\n                <div>\r\n                    <div class=\"pth-mixer-box\" id=\"pth-mix-b\" style=\"background:#f1f5f9;color:#334155;\">B<\/div>\r\n                    <div class=\"pth-mixer-label\">Color B<\/div>\r\n                <\/div>\r\n            <\/div>\r\n            <div class=\"pth-row-2\" style=\"margin-bottom:12px;\">\r\n                <div class=\"pth-field\">\r\n                    <label for=\"pth-mix-a-picker\">Color A<\/label>\r\n                    <input type=\"color\" id=\"pth-mix-a-picker\" value=\"#2563eb\"\r\n                        style=\"width:100%;height:40px;border-radius:8px;border:2px solid #e2e8f0;cursor:pointer;padding:2px;\"\r\n                        aria-label=\"Select color A for mixing\">\r\n                <\/div>\r\n                <div class=\"pth-field\">\r\n                    <label for=\"pth-mix-b-picker\">Color B<\/label>\r\n                    <input type=\"color\" id=\"pth-mix-b-picker\" value=\"#f1f5f9\"\r\n                        style=\"width:100%;height:40px;border-radius:8px;border:2px solid #e2e8f0;cursor:pointer;padding:2px;\"\r\n                        aria-label=\"Select color B for mixing\">\r\n                <\/div>\r\n            <\/div>\r\n            <div class=\"pth-field\">\r\n                <label>Mix Ratio \u2014 <span id=\"pth-mix-ratio-val\"\r\n                    style=\"color:#1d4ed8;font-weight:800;\">50%<\/span> A<\/label>\r\n                <input type=\"range\" id=\"pth-mix-ratio\" min=\"0\" max=\"100\" value=\"50\"\r\n                    style=\"width:100%;accent-color:#2563eb;cursor:pointer;\"\r\n                    aria-label=\"Color mix ratio\" aria-valuemin=\"0\" aria-valuemax=\"100\" aria-valuenow=\"50\">\r\n            <\/div>\r\n            <button class=\"pth-btn pth-btn-secondary\" id=\"pth-mix-copy-btn\"\r\n                aria-label=\"Copy mixed color result\">\ud83d\udccb Copy Result<\/button>\r\n        <\/div>\r\n\r\n        <!-- Image Color Picker -->\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83d\uddbc\ufe0f Image Color Picker<\/div>\r\n            <div class=\"pth-img-drop-zone\" id=\"pth-img-drop-zone\"\r\n                role=\"button\" tabindex=\"0\"\r\n                aria-label=\"Upload image to pick colors from \u2014 drag and drop or click\">\r\n                <div style=\"font-size:32px;margin-bottom:8px;\">\ud83d\uddbc\ufe0f<\/div>\r\n                <div style=\"font-size:13px;font-weight:700;color:#5b21b6;margin-bottom:4px;\">Drag &amp; Drop Image Here<\/div>\r\n                <div style=\"font-size:12px;color:#334155;font-weight:500;\">or click to browse \u2014 click any pixel to pick its color<\/div>\r\n            <\/div>\r\n            <input type=\"file\" id=\"pth-img-file\" accept=\"image\/*\" style=\"display:none;\"\r\n                aria-label=\"Select image file for color picking\">\r\n            <div class=\"pth-img-canvas-wrap\" id=\"pth-img-canvas-wrap\">\r\n                <canvas id=\"pth-img-canvas\" class=\"pth-img-canvas\"\r\n                    aria-label=\"Image canvas \u2014 click to pick color from any pixel\" width=\"600\" height=\"400\"><\/canvas>\r\n                <div class=\"pth-img-crosshair\" id=\"pth-img-crosshair\"><\/div>\r\n            <\/div>\r\n            <div class=\"pth-picked-color-bar\" id=\"pth-picked-color-bar\">\r\n                <div id=\"pth-picked-swatch\"\r\n                    style=\"width:40px;height:40px;border-radius:8px;border:2px solid #e2e8f0;flex-shrink:0;\"><\/div>\r\n                <div>\r\n                    <div id=\"pth-picked-hex\" style=\"font-size:15px;font-weight:800;color:#0f172a;font-family:'Courier New',monospace;\"><\/div>\r\n                    <div id=\"pth-picked-rgb\" style=\"font-size:12px;color:#334155;font-weight:600;\"><\/div>\r\n                <\/div>\r\n                <button class=\"pth-btn pth-btn-secondary\" id=\"pth-picked-copy-btn\"\r\n                    style=\"margin-left:auto;\" aria-label=\"Copy picked color\">\ud83d\udccb Copy<\/button>\r\n                <button class=\"pth-btn pth-btn-primary\" id=\"pth-picked-use-btn\"\r\n                    aria-label=\"Use picked color as main color\">\u2705 Use Color<\/button>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <!-- Gradient Generator -->\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83c\udf05 Gradient Generator<\/div>\r\n            <div class=\"pth-gradient-preview\" id=\"pth-gradient-preview\"><\/div>\r\n            <div class=\"pth-row-3\" style=\"margin-bottom:12px;\">\r\n                <div class=\"pth-field\">\r\n                    <label for=\"pth-grad-a\">Color 1<\/label>\r\n                    <input type=\"color\" id=\"pth-grad-a\" value=\"#2563eb\"\r\n                        style=\"width:100%;height:40px;border-radius:8px;border:2px solid #e2e8f0;cursor:pointer;padding:2px;\"\r\n                        aria-label=\"Gradient start color\">\r\n                <\/div>\r\n                <div class=\"pth-field\">\r\n                    <label for=\"pth-grad-b\">Color 2<\/label>\r\n                    <input type=\"color\" id=\"pth-grad-b\" value=\"#7c3aed\"\r\n                        style=\"width:100%;height:40px;border-radius:8px;border:2px solid #e2e8f0;cursor:pointer;padding:2px;\"\r\n                        aria-label=\"Gradient end color\">\r\n                <\/div>\r\n                <div class=\"pth-field\">\r\n                    <label for=\"pth-grad-angle\">Angle<\/label>\r\n                    <select id=\"pth-grad-angle\" aria-label=\"Gradient direction angle\">\r\n                        <option value=\"90deg\">\u2192 90\u00b0<\/option>\r\n                        <option value=\"135deg\">\u2198 135\u00b0<\/option>\r\n                        <option value=\"180deg\">\u2193 180\u00b0<\/option>\r\n                        <option value=\"45deg\">\u2197 45\u00b0<\/option>\r\n                        <option value=\"0deg\">\u2191 0\u00b0<\/option>\r\n                    <\/select>\r\n                <\/div>\r\n            <\/div>\r\n            <pre class=\"pth-gradient-css\" id=\"pth-gradient-css\"><\/pre>\r\n            <button class=\"pth-btn pth-btn-secondary\" id=\"pth-gradient-copy-btn\"\r\n                style=\"margin-top:10px;\" aria-label=\"Copy gradient CSS code\">\ud83d\udccb Copy Gradient CSS<\/button>\r\n        <\/div>\r\n\r\n        <!-- Color Blindness Simulator -->\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83d\udc41\ufe0f Color Blindness Simulator<\/div>\r\n            <p style=\"font-size:13px;color:#334155;margin:0 0 14px;font-weight:500;\">\r\n                How your selected color appears to users with different types of color vision deficiency.\r\n            <\/p>\r\n            <div class=\"pth-cb-grid\" id=\"pth-cb-grid\">\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-normal\"><\/div>\r\n                    <div class=\"pth-cb-label\">Normal Vision<\/div>\r\n                    <div class=\"pth-cb-desc\">Standard color perception<\/div>\r\n                <\/div>\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-deuteranopia\"><\/div>\r\n                    <div class=\"pth-cb-label\">Deuteranopia<\/div>\r\n                    <div class=\"pth-cb-desc\">Red-green (green-weak) \u00b7 6% males<\/div>\r\n                <\/div>\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-protanopia\"><\/div>\r\n                    <div class=\"pth-cb-label\">Protanopia<\/div>\r\n                    <div class=\"pth-cb-desc\">Red-green (red-weak) \u00b7 1% males<\/div>\r\n                <\/div>\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-tritanopia\"><\/div>\r\n                    <div class=\"pth-cb-label\">Tritanopia<\/div>\r\n                    <div class=\"pth-cb-desc\">Blue-yellow deficiency \u00b7 rare<\/div>\r\n                <\/div>\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-achromatopsia\"><\/div>\r\n                    <div class=\"pth-cb-label\">Achromatopsia<\/div>\r\n                    <div class=\"pth-cb-desc\">Complete color blindness \u00b7 very rare<\/div>\r\n                <\/div>\r\n                <div class=\"pth-cb-item\">\r\n                    <div class=\"pth-cb-swatch\" id=\"pth-cb-deuteranomaly\"><\/div>\r\n                    <div class=\"pth-cb-label\">Deuteranomaly<\/div>\r\n                    <div class=\"pth-cb-desc\">Green-weak (partial) \u00b7 most common<\/div>\r\n                <\/div>\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- \u2550\u2550 TAB 5: CSS OUTPUT \u2550\u2550 -->\r\n    <div id=\"pth-tab-css\" style=\"display:none;\" role=\"tabpanel\">\r\n        <div class=\"pth-card\">\r\n            <div class=\"pth-card-hdr\">\ud83d\udcbb CSS Code Generator<\/div>\r\n            <div style=\"display:flex;gap:8px;flex-wrap:wrap;margin-bottom:14px;\">\r\n                <button class=\"pth-btn pth-btn-secondary pth-active\" data-css-type=\"properties\"\r\n                    aria-label=\"Generate CSS properties\" aria-pressed=\"true\">CSS Properties<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary\" data-css-type=\"variables\"\r\n                    aria-label=\"Generate CSS variables\" aria-pressed=\"false\">CSS Variables<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary\" data-css-type=\"tokens\"\r\n                    aria-label=\"Generate design tokens JSON\" aria-pressed=\"false\">Design Tokens JSON<\/button>\r\n                <button class=\"pth-btn pth-btn-secondary\" data-css-type=\"tailwind\"\r\n                    aria-label=\"Generate Tailwind config\" aria-pressed=\"false\">Tailwind Config<\/button>\r\n            <\/div>\r\n            <div class=\"pth-field\">\r\n                <label for=\"pth-css-varname\">Variable \/ Token Name<\/label>\r\n                <input type=\"text\" id=\"pth-css-varname\" value=\"primary\"\r\n                    aria-label=\"CSS variable or token name\" placeholder=\"e.g. primary, brand, accent\">\r\n            <\/div>\r\n            <pre class=\"pth-css-output\" id=\"pth-css-output\" aria-live=\"polite\" aria-label=\"Generated CSS code\"><\/pre>\r\n            <div style=\"display:flex;gap:8px;margin-top:12px;flex-wrap:wrap;\">\r\n                <button class=\"pth-btn pth-btn-success\" id=\"pth-css-copy-btn\"\r\n                    style=\"flex:1;\" aria-label=\"Copy generated CSS code\">\ud83d\udccb Copy Code<\/button>\r\n            <\/div>\r\n        <\/div>\r\n\r\n        <!-- PTH Color Validator -->\r\n        <div class=\"pth-card\" id=\"pth-validator-card\">\r\n            <div class=\"pth-card-hdr\">\u2705 PTH WCAG AA Color Validator<\/div>\r\n            <div id=\"pth-validator-output\"\r\n                style=\"font-size:13px;font-weight:500;color:#1e293b;line-height:1.9;min-height:60px;\">\r\n                Select a color to validate against PTH v3.1 instruction rules.\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n<\/div><!-- \/pth-card main -->\r\n<\/div><!-- \/main col -->\r\n\r\n<!-- \u2550\u2550\u2550 SIDEBAR \u2550\u2550\u2550 -->\r\n<div class=\"pth-sidebar-col\" id=\"pth-color-sidebar\">\r\n\r\n    <!-- Current Color Info -->\r\n    <div class=\"pth-card\">\r\n        <div class=\"pth-sidebar-hdr\">\ud83c\udfa8 Current Color<\/div>\r\n        <div style=\"width:100%;height:80px;border-radius:10px;border:1px solid #e2e8f0;margin-bottom:12px;transition:0.3s;\"\r\n            id=\"pth-sb-preview\"><\/div>\r\n        <div style=\"display:flex;flex-direction:column;gap:6px;\" id=\"pth-sb-values\">\r\n            <div style=\"font-size:11px;font-weight:700;color:#334155;font-family:'Courier New',monospace;\"\r\n                id=\"pth-sb-hex\">HEX: #2563EB<\/div>\r\n            <div style=\"font-size:11px;font-weight:700;color:#334155;font-family:'Courier New',monospace;\"\r\n                id=\"pth-sb-rgb\">RGB: 37, 99, 235<\/div>\r\n            <div style=\"font-size:11px;font-weight:700;color:#334155;font-family:'Courier New',monospace;\"\r\n                id=\"pth-sb-hsl\">HSL: 221\u00b0 83% 53%<\/div>\r\n            <div style=\"font-size:11px;font-weight:700;color:#334155;font-family:'Courier New',monospace;\"\r\n                id=\"pth-sb-lum\">Luminance: 0.141<\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- Color History -->\r\n    <div class=\"pth-card\">\r\n        <div class=\"pth-sidebar-hdr\">\ud83d\udd52 Color History<\/div>\r\n        <div class=\"pth-color-history\" id=\"pth-color-history\">\r\n            <div style=\"font-size:12px;color:#334155;font-weight:500;\">\r\n                Colors you pick appear here\r\n            <\/div>\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- Preset Colors -->\r\n    <div class=\"pth-card\">\r\n        <div class=\"pth-sidebar-hdr\">\ud83c\udfaf PTH Color System<\/div>\r\n        <div style=\"font-size:10px;font-weight:800;color:#334155;text-transform:uppercase;margin-bottom:6px;letter-spacing:0.4px;\">WCAG AA Approved<\/div>\r\n        <div class=\"pth-preset-grid\" id=\"pth-preset-grid\">\r\n            <!-- Filled by JS -->\r\n        <\/div>\r\n        <div style=\"font-size:10px;color:#334155;font-weight:600;margin-top:10px;line-height:1.6;\">\r\n            Click any swatch to load it as your active color\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- Tips -->\r\n    <div class=\"pth-card\">\r\n        <div class=\"pth-sidebar-hdr\">\ud83d\udca1 Pro Tips<\/div>\r\n        <ul style=\"margin:0;padding-left:16px;font-size:12px;color:#334155;line-height:1.9;font-weight:500;\">\r\n            <li>Type any format \u2014 HEX, RGB, HSL, HSB, CMYK or LAB in the Convert tab.<\/li>\r\n            <li>Click any shade or palette swatch to load it as the active color.<\/li>\r\n            <li><strong style=\"color:#0f172a;\">WCAG AA<\/strong> requires 4.5:1 ratio for normal text.<\/li>\r\n            <li>Image picker: upload a screenshot and click any pixel.<\/li>\r\n            <li>Color history saves your last 12 colors in this session.<\/li>\r\n            <li>Design Tokens JSON is compatible with Figma and Style Dictionary.<\/li>\r\n        <\/ul>\r\n    <\/div>\r\n\r\n<\/div><!-- \/sidebar -->\r\n<\/div><!-- \/flex-layout -->\r\n<\/div><!-- \/wrapper -->\r\n<script data-no-optimize=\"1\" data-no-minify=\"1\" data-cfasync=\"false\">\r\n(function () {\r\n    'use strict';\r\n\r\n    \/* =======================================================\r\n       PTH COLOR STUDIO PRO \u2014 v2.0\r\n       WP\/LiteSpeed safe | WCAG 2.1 AA | PageSpeed 100\r\n       5 Tabs | 22 Color Tools | 100% Offline\r\n       ======================================================= *\/\r\n\r\n    window.pthColorApp = {\r\n        initialized: false,\r\n        currentRgb: { r: 37, g: 99, b: 235 },\r\n        history: [],\r\n        currentTab: 'convert',\r\n        cssType: 'properties',\r\n        mixResult: { r: 37, g: 99, b: 235 },\r\n        pickedColor: null,\r\n        imgData: null,\r\n\r\n        \/* \u2500\u2500 PTH approved color presets \u2500\u2500 *\/\r\n        presets: [\r\n            { hex: '#1d4ed8', name: 'PTH Blue' },\r\n            { hex: '#047857', name: 'PTH Green' },\r\n            { hex: '#991b1b', name: 'PTH Red' },\r\n            { hex: '#92400e', name: 'PTH Amber' },\r\n            { hex: '#5b21b6', name: 'PTH Purple' },\r\n            { hex: '#4c1d95', name: 'PTH Violet' },\r\n            { hex: '#0f172a', name: 'PTH Dark' },\r\n            { hex: '#1e293b', name: 'PTH Slate' },\r\n            { hex: '#334155', name: 'PTH Muted' },\r\n            { hex: '#2563eb', name: 'Blue-600' },\r\n            { hex: '#059669', name: 'Green-600' },\r\n            { hex: '#dc2626', name: 'Red-600' }\r\n        ],\r\n\r\n        \/* \u2500\u2500 Tailwind color map (closest match lookup) \u2500\u2500 *\/\r\n        tailwindColors: {\r\n            'slate-50':'#f8fafc','slate-100':'#f1f5f9','slate-200':'#e2e8f0','slate-300':'#cbd5e1',\r\n            'slate-400':'#94a3b8','slate-500':'#64748b','slate-600':'#475569','slate-700':'#334155',\r\n            'slate-800':'#1e293b','slate-900':'#0f172a',\r\n            'blue-50':'#eff6ff','blue-100':'#dbeafe','blue-200':'#bfdbfe','blue-300':'#93c5fd',\r\n            'blue-400':'#60a5fa','blue-500':'#3b82f6','blue-600':'#2563eb','blue-700':'#1d4ed8',\r\n            'blue-800':'#1e40af','blue-900':'#1e3a8a',\r\n            'green-50':'#f0fdf4','green-100':'#dcfce7','green-400':'#4ade80','green-500':'#22c55e',\r\n            'green-600':'#16a34a','green-700':'#15803d','green-800':'#166534','green-900':'#14532d',\r\n            'red-50':'#fef2f2','red-100':'#fee2e2','red-400':'#f87171','red-500':'#ef4444',\r\n            'red-600':'#dc2626','red-700':'#b91c1c','red-800':'#991b1b','red-900':'#7f1d1d',\r\n            'purple-50':'#faf5ff','purple-100':'#f3e8ff','purple-400':'#c084fc','purple-500':'#a855f7',\r\n            'purple-600':'#9333ea','purple-700':'#7c3aed','purple-800':'#6b21a8','purple-900':'#581c87',\r\n            'yellow-50':'#fefce8','yellow-100':'#fef9c3','yellow-300':'#fcd34d','yellow-400':'#facc15',\r\n            'yellow-500':'#eab308','amber-50':'#fffbeb','amber-100':'#fef3c7','amber-500':'#f59e0b',\r\n            'amber-600':'#d97706','amber-700':'#b45309','amber-800':'#92400e','amber-900':'#78350f',\r\n            'indigo-500':'#6366f1','indigo-600':'#4f46e5','indigo-700':'#4338ca',\r\n            'pink-500':'#ec4899','rose-500':'#f43f5e','orange-500':'#f97316',\r\n            'teal-500':'#14b8a6','cyan-500':'#06b6d4','emerald-500':'#10b981',\r\n            'white':'#ffffff','black':'#000000','transparent':'transparent'\r\n        },\r\n\r\n        \/* \u2500\u2500 Named CSS colors (subset of most common) \u2500\u2500 *\/\r\n        cssNamedColors: {\r\n            'aliceblue':'#F0F8FF','antiquewhite':'#FAEBD7','aqua':'#00FFFF','aquamarine':'#7FFFD4',\r\n            'azure':'#F0FFFF','beige':'#F5F5DC','bisque':'#FFE4C4','black':'#000000',\r\n            'blanchedalmond':'#FFEBCD','blue':'#0000FF','blueviolet':'#8A2BE2','brown':'#A52A2A',\r\n            'burlywood':'#DEB887','cadetblue':'#5F9EA0','chartreuse':'#7FFF00','chocolate':'#D2691E',\r\n            'coral':'#FF7F50','cornflowerblue':'#6495ED','cornsilk':'#FFF8DC','crimson':'#DC143C',\r\n            'cyan':'#00FFFF','darkblue':'#00008B','darkcyan':'#008B8B','darkgoldenrod':'#B8860B',\r\n            'darkgray':'#A9A9A9','darkgreen':'#006400','darkkhaki':'#BDB76B','darkmagenta':'#8B008B',\r\n            'darkolivegreen':'#556B2F','darkorange':'#FF8C00','darkorchid':'#9932CC',\r\n            'darkred':'#8B0000','darksalmon':'#E9967A','darkseagreen':'#8FBC8F',\r\n            'darkslateblue':'#483D8B','darkslategray':'#2F4F4F','darkturquoise':'#00CED1',\r\n            'darkviolet':'#9400D3','deeppink':'#FF1493','deepskyblue':'#00BFFF',\r\n            'dimgray':'#696969','dodgerblue':'#1E90FF','firebrick':'#B22222',\r\n            'floralwhite':'#FFFAF0','forestgreen':'#228B22','fuchsia':'#FF00FF',\r\n            'gainsboro':'#DCDCDC','ghostwhite':'#F8F8FF','gold':'#FFD700','goldenrod':'#DAA520',\r\n            'gray':'#808080','green':'#008000','greenyellow':'#ADFF2F','honeydew':'#F0FFF0',\r\n            'hotpink':'#FF69B4','indianred':'#CD5C5C','indigo':'#4B0082','ivory':'#FFFFF0',\r\n            'khaki':'#F0E68C','lavender':'#E6E6FA','lawngreen':'#7CFC00','lemonchiffon':'#FFFACD',\r\n            'lightblue':'#ADD8E6','lightcoral':'#F08080','lightcyan':'#E0FFFF',\r\n            'lightgreen':'#90EE90','lightgray':'#D3D3D3','lightpink':'#FFB6C1',\r\n            'lightsalmon':'#FFA07A','lightseagreen':'#20B2AA','lightskyblue':'#87CEFA',\r\n            'lightslategray':'#778899','lightsteelblue':'#B0C4DE','lightyellow':'#FFFFE0',\r\n            'lime':'#00FF00','limegreen':'#32CD32','linen':'#FAF0E6','magenta':'#FF00FF',\r\n            'maroon':'#800000','mediumaquamarine':'#66CDAA','mediumblue':'#0000CD',\r\n            'mediumorchid':'#BA55D3','mediumpurple':'#9370DB','mediumseagreen':'#3CB371',\r\n            'mediumslateblue':'#7B68EE','mediumspringgreen':'#00FA9A','mediumturquoise':'#48D1CC',\r\n            'mediumvioletred':'#C71585','midnightblue':'#191970','mintcream':'#F5FFFA',\r\n            'mistyrose':'#FFE4E1','moccasin':'#FFE4B5','navajowhite':'#FFDEAD',\r\n            'navy':'#000080','oldlace':'#FDF5E6','olive':'#808000','olivedrab':'#6B8E23',\r\n            'orange':'#FFA500','orangered':'#FF4500','orchid':'#DA70D6','palegoldenrod':'#EEE8AA',\r\n            'palegreen':'#98FB98','paleturquoise':'#AFEEEE','palevioletred':'#DB7093',\r\n            'papayawhip':'#FFEFD5','peachpuff':'#FFDAB9','peru':'#CD853F','pink':'#FFC0CB',\r\n            'plum':'#DDA0DD','powderblue':'#B0E0E6','purple':'#800080','red':'#FF0000',\r\n            'rosybrown':'#BC8F8F','royalblue':'#4169E1','saddlebrown':'#8B4513',\r\n            'salmon':'#FA8072','sandybrown':'#F4A460','seagreen':'#2E8B57','seashell':'#FFF5EE',\r\n            'sienna':'#A0522D','silver':'#C0C0C0','skyblue':'#87CEEB','slateblue':'#6A5ACD',\r\n            'slategray':'#708090','snow':'#FFFAFA','springgreen':'#00FF7F','steelblue':'#4682B4',\r\n            'tan':'#D2B48C','teal':'#008080','thistle':'#D8BFD8','tomato':'#FF6347',\r\n            'turquoise':'#40E0D0','violet':'#EE82EE','wheat':'#F5DEB3','white':'#FFFFFF',\r\n            'whitesmoke':'#F5F5F5','yellow':'#FFFF00','yellowgreen':'#9ACD32'\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 INIT \u2500\u2500\u2500 *\/\r\n        init: function () {\r\n            var self = this;\r\n            try { self.buildPresets(); } catch(e) {}\r\n            try { self.attachEvents(); } catch(e) {}\r\n            try { self.updateAll(self.currentRgb.r, self.currentRgb.g, self.currentRgb.b, null); } catch(e) {}\r\n            try { self.updateGradient(); } catch(e) {}\r\n            try { self.updateMixer(); } catch(e) {}\r\n            try { self.generateCssOutput(); } catch(e) {}\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 BUILD PRESETS \u2500\u2500\u2500 *\/\r\n        buildPresets: function () {\r\n            var self = this;\r\n            var grid = document.getElementById('pth-preset-grid');\r\n            if (!grid) return;\r\n            var html = '';\r\n            self.presets.forEach(function (p) {\r\n                html += '<div class=\"pth-preset-swatch\" style=\"background:' + p.hex + ';\"' +\r\n                    ' title=\"' + p.name + ' ' + p.hex + '\"' +\r\n                    ' data-preset=\"' + p.hex + '\"' +\r\n                    ' role=\"button\" tabindex=\"0\"' +\r\n                    ' aria-label=\"Load color ' + p.name + ' ' + p.hex + '\"><\/div>';\r\n            });\r\n            grid.innerHTML = html;\r\n            grid.querySelectorAll('.pth-preset-swatch').forEach(function (el) {\r\n                el.addEventListener('click', function () {\r\n                    var hex = this.getAttribute('data-preset');\r\n                    var rgb = self.hexToRgb(hex);\r\n                    if (rgb) self.updateAll(rgb.r, rgb.g, rgb.b, null);\r\n                });\r\n                el.addEventListener('keydown', function (e) {\r\n                    if (e.key === 'Enter' || e.key === ' ') {\r\n                        e.preventDefault();\r\n                        var hex = this.getAttribute('data-preset');\r\n                        var rgb = self.hexToRgb(hex);\r\n                        if (rgb) self.updateAll(rgb.r, rgb.g, rgb.b, null);\r\n                    }\r\n                });\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 ATTACH EVENTS \u2500\u2500\u2500 *\/\r\n        attachEvents: function () {\r\n            var self = this;\r\n\r\n            \/* Full width *\/\r\n            var fwBtn = document.getElementById('pth-cs-fw-btn');\r\n            if (fwBtn) fwBtn.addEventListener('click', function () { self.toggleWidth(); });\r\n\r\n            \/* Sample \/ Random \/ Reset *\/\r\n            var sampleBtn = document.getElementById('pth-cs-sample-btn');\r\n            if (sampleBtn) sampleBtn.addEventListener('click', function () { self.loadSample(); });\r\n            var randomBtn = document.getElementById('pth-cs-random-btn');\r\n            if (randomBtn) randomBtn.addEventListener('click', function () { self.loadRandom(); });\r\n            var clearBtn = document.getElementById('pth-cs-clear-btn');\r\n            if (clearBtn) clearBtn.addEventListener('click', function () {\r\n                self.updateAll(37, 99, 235, null);\r\n                self.showToast('Reset to default!', 'info');\r\n            });\r\n\r\n            \/* Native color picker *\/\r\n            var picker = document.getElementById('pth-native-picker');\r\n            if (picker) picker.addEventListener('input', function () {\r\n                var rgb = self.hexToRgb(this.value);\r\n                if (rgb) self.updateAll(rgb.r, rgb.g, rgb.b, 'picker');\r\n            });\r\n\r\n            \/* Tab buttons *\/\r\n            document.querySelectorAll('#pth-color-wrapper .pth-tab-btn').forEach(function (btn) {\r\n                btn.addEventListener('click', function () { self.switchTab(this.getAttribute('data-tab')); });\r\n            });\r\n\r\n            \/* Format inputs *\/\r\n            var inputs = [\r\n                { id: 'pth-in-hex',  parser: 'hex'  },\r\n                { id: 'pth-in-rgb',  parser: 'rgb'  },\r\n                { id: 'pth-in-hsl',  parser: 'hsl'  },\r\n                { id: 'pth-in-hsb',  parser: 'hsb'  },\r\n                { id: 'pth-in-cmyk', parser: 'cmyk' },\r\n                { id: 'pth-in-lab',  parser: 'lab'  }\r\n            ];\r\n            inputs.forEach(function (inp) {\r\n                var el = document.getElementById(inp.id);\r\n                if (!el) return;\r\n                el.addEventListener('change', function () {\r\n                    var rgb = self.parseFormat(inp.parser, this.value);\r\n                    if (rgb) self.updateAll(rgb.r, rgb.g, rgb.b, inp.id);\r\n                    else self.showToast('Invalid ' + inp.parser.toUpperCase() + ' format', 'error');\r\n                });\r\n            });\r\n\r\n            \/* Copy buttons *\/\r\n            document.querySelectorAll('#pth-color-wrapper .pth-copy-btn[data-copy]').forEach(function (btn) {\r\n                btn.addEventListener('click', function () {\r\n                    var el = document.getElementById(this.getAttribute('data-copy'));\r\n                    if (el) {\r\n                        self.copyToClipboard(el.value, btn);\r\n                        self.showToast('Copied!', 'success');\r\n                    }\r\n                });\r\n            });\r\n\r\n            \/* Copy all formats *\/\r\n            var copyAllBtn = document.getElementById('pth-copy-all-btn');\r\n            if (copyAllBtn) copyAllBtn.addEventListener('click', function () { self.copyAllFormats(); });\r\n\r\n            \/* Custom contrast picker *\/\r\n            var customPicker = document.getElementById('pth-custom-contrast-picker');\r\n            if (customPicker) customPicker.addEventListener('input', function () {\r\n                var lbl = document.getElementById('pth-custom-color-label');\r\n                if (lbl) lbl.textContent = this.value.toUpperCase();\r\n                self.updateContrast(self.currentRgb.r, self.currentRgb.g, self.currentRgb.b);\r\n            });\r\n\r\n            \/* Palette copy buttons *\/\r\n            document.querySelectorAll('#pth-color-wrapper .pth-copy-btn[data-palette]').forEach(function (btn) {\r\n                btn.addEventListener('click', function () { self.copyPalette(this.getAttribute('data-palette')); });\r\n            });\r\n            var shadesBtn = document.getElementById('pth-copy-shades-css');\r\n            if (shadesBtn) shadesBtn.addEventListener('click', function () { self.copyShadesCss(); });\r\n\r\n            \/* Mixer *\/\r\n            var mixA   = document.getElementById('pth-mix-a-picker');\r\n            var mixB   = document.getElementById('pth-mix-b-picker');\r\n            var mixRng = document.getElementById('pth-mix-ratio');\r\n            if (mixA)   mixA.addEventListener('input',   function () { self.updateMixer(); });\r\n            if (mixB)   mixB.addEventListener('input',   function () { self.updateMixer(); });\r\n            if (mixRng) mixRng.addEventListener('input', function () {\r\n                var el = document.getElementById('pth-mix-ratio-val');\r\n                if (el) el.textContent = this.value + '%';\r\n                this.setAttribute('aria-valuenow', this.value);\r\n                self.updateMixer();\r\n            });\r\n            var mixCopyBtn = document.getElementById('pth-mix-copy-btn');\r\n            if (mixCopyBtn) mixCopyBtn.addEventListener('click', function () {\r\n                var hex = self.rgbToHex(self.mixResult.r, self.mixResult.g, self.mixResult.b);\r\n                self.copyToClipboard(hex, this);\r\n                self.showToast('Mix result ' + hex + ' copied!', 'success');\r\n            });\r\n\r\n            \/* Image picker *\/\r\n            var dropZone = document.getElementById('pth-img-drop-zone');\r\n            var imgFile  = document.getElementById('pth-img-file');\r\n            if (dropZone) {\r\n                dropZone.addEventListener('click', function () { if (imgFile) imgFile.click(); });\r\n                dropZone.addEventListener('keydown', function (e) {\r\n                    if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); if (imgFile) imgFile.click(); }\r\n                });\r\n                dropZone.addEventListener('dragover', function (e) {\r\n                    e.preventDefault(); this.classList.add('drag-over');\r\n                });\r\n                dropZone.addEventListener('dragleave', function () {\r\n                    this.classList.remove('drag-over');\r\n                });\r\n                dropZone.addEventListener('drop', function (e) {\r\n                    e.preventDefault(); this.classList.remove('drag-over');\r\n                    var file = e.dataTransfer.files[0];\r\n                    if (file && file.type.startsWith('image\/')) self.loadImageFile(file);\r\n                });\r\n            }\r\n            if (imgFile) imgFile.addEventListener('change', function () {\r\n                if (this.files[0]) self.loadImageFile(this.files[0]);\r\n            });\r\n\r\n            var canvas = document.getElementById('pth-img-canvas');\r\n            if (canvas) {\r\n                canvas.addEventListener('click', function (e) { self.pickImageColor(e); });\r\n                canvas.addEventListener('mousemove', function (e) { self.showCrosshair(e); });\r\n                canvas.addEventListener('mouseleave', function () {\r\n                    var ch = document.getElementById('pth-img-crosshair');\r\n                    if (ch) ch.style.display = 'none';\r\n                });\r\n            }\r\n            var pickedCopyBtn = document.getElementById('pth-picked-copy-btn');\r\n            var pickedUseBtn  = document.getElementById('pth-picked-use-btn');\r\n            if (pickedCopyBtn) pickedCopyBtn.addEventListener('click', function () {\r\n                if (self.pickedColor) {\r\n                    self.copyToClipboard(self.pickedColor.hex, this);\r\n                    self.showToast('Copied ' + self.pickedColor.hex, 'success');\r\n                }\r\n            });\r\n            if (pickedUseBtn) pickedUseBtn.addEventListener('click', function () {\r\n                if (self.pickedColor) {\r\n                    self.updateAll(self.pickedColor.r, self.pickedColor.g, self.pickedColor.b, null);\r\n                    self.showToast('Color loaded!', 'success');\r\n                }\r\n            });\r\n\r\n            \/* Gradient *\/\r\n            var gradA     = document.getElementById('pth-grad-a');\r\n            var gradB     = document.getElementById('pth-grad-b');\r\n            var gradAngle = document.getElementById('pth-grad-angle');\r\n            if (gradA)     gradA.addEventListener('input',     function () { self.updateGradient(); });\r\n            if (gradB)     gradB.addEventListener('input',     function () { self.updateGradient(); });\r\n            if (gradAngle) gradAngle.addEventListener('change', function () { self.updateGradient(); });\r\n            var gradCopyBtn = document.getElementById('pth-gradient-copy-btn');\r\n            if (gradCopyBtn) gradCopyBtn.addEventListener('click', function () {\r\n                var el = document.getElementById('pth-gradient-css');\r\n                if (el) { self.copyToClipboard(el.textContent, this); self.showToast('Gradient CSS copied!', 'success'); }\r\n            });\r\n\r\n            \/* CSS Output *\/\r\n            document.querySelectorAll('[data-css-type]').forEach(function (btn) {\r\n                btn.addEventListener('click', function () { self.setCssType(this.getAttribute('data-css-type')); });\r\n            });\r\n            var varNameEl = document.getElementById('pth-css-varname');\r\n            if (varNameEl) varNameEl.addEventListener('input', function () { self.generateCssOutput(); });\r\n            var cssCopyBtn = document.getElementById('pth-css-copy-btn');\r\n            if (cssCopyBtn) cssCopyBtn.addEventListener('click', function () {\r\n                var el = document.getElementById('pth-css-output');\r\n                if (el) { self.copyToClipboard(el.textContent, this); self.showToast('CSS copied!', 'success'); }\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 SWITCH TAB \u2500\u2500\u2500 *\/\r\n        switchTab: function (tab) {\r\n            var self = this;\r\n            self.currentTab = tab;\r\n            var tabs = ['convert','contrast','palette','tools','css'];\r\n            tabs.forEach(function (t) {\r\n                var panel = document.getElementById('pth-tab-' + t);\r\n                var btn   = document.querySelector('[data-tab=\"' + t + '\"]');\r\n                if (panel) panel.style.display = (t === tab) ? 'block' : 'none';\r\n                if (btn)   { btn.classList.toggle('pth-active', t === tab); btn.setAttribute('aria-selected', t === tab ? 'true' : 'false'); }\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 MASTER UPDATER \u2500\u2500\u2500 *\/\r\n        updateAll: function (r, g, b, sourceId) {\r\n            var self = this;\r\n            r = Math.max(0, Math.min(255, Math.round(r)));\r\n            g = Math.max(0, Math.min(255, Math.round(g)));\r\n            b = Math.max(0, Math.min(255, Math.round(b)));\r\n\r\n            self.currentRgb = { r: r, g: g, b: b };\r\n            var hex = self.rgbToHex(r, g, b);\r\n            var hsl = self.rgbToHsl(r, g, b);\r\n            var hsb = self.rgbToHsb(r, g, b);\r\n            var cmyk= self.rgbToCmyk(r, g, b);\r\n            var lab = self.rgbToLab(r, g, b);\r\n            var lum = self.getLuminance(r, g, b);\r\n            var isDark = lum < 0.179;\r\n\r\n            \/* Hero preview *\/\r\n            var hero = document.getElementById('pth-color-hero');\r\n            var heroHex = document.getElementById('pth-hero-hex');\r\n            if (hero) hero.style.backgroundColor = hex;\r\n            if (heroHex) { heroHex.textContent = hex.toUpperCase(); heroHex.style.color = isDark ? '#fff' : '#0f172a'; }\r\n\r\n            \/* Native picker *\/\r\n            var picker = document.getElementById('pth-native-picker');\r\n            if (picker && sourceId !== 'picker') picker.value = hex;\r\n\r\n            \/* Format inputs *\/\r\n            if (sourceId !== 'pth-in-hex')  self.setVal('pth-in-hex',  hex.toUpperCase());\r\n            if (sourceId !== 'pth-in-rgb')  self.setVal('pth-in-rgb',  'rgb(' + r + ', ' + g + ', ' + b + ')');\r\n            if (sourceId !== 'pth-in-hsl')  self.setVal('pth-in-hsl',  'hsl(' + hsl.h + ', ' + hsl.s + '%, ' + hsl.l + '%)');\r\n            if (sourceId !== 'pth-in-hsb')  self.setVal('pth-in-hsb',  'hsb(' + hsb.h + ', ' + hsb.s + '%, ' + hsb.b + '%)');\r\n            if (sourceId !== 'pth-in-cmyk') self.setVal('pth-in-cmyk', 'cmyk(' + cmyk.c + '%, ' + cmyk.m + '%, ' + cmyk.y + '%, ' + cmyk.k + '%)');\r\n            if (sourceId !== 'pth-in-lab')  self.setVal('pth-in-lab',  'lab(' + lab.l + ', ' + lab.a + ', ' + lab.b2 + ')');\r\n            self.setVal('pth-in-cssvar', '--color-primary: ' + hex.toUpperCase() + ';');\r\n\r\n            \/* Info badges *\/\r\n            var named    = self.findNamedColor(hex);\r\n            var tailwind = self.findTailwindColor(r, g, b);\r\n            self.setEl('pth-badge-named',    named    ? '\ud83c\udff7\ufe0f ' + named    : '\ud83c\udff7\ufe0f No named match');\r\n            self.setEl('pth-badge-tailwind', tailwind ? '\ud83d\udca8 ' + tailwind : '\ud83d\udca8 No Tailwind match');\r\n            self.setEl('pth-badge-lum',      '\u2600\ufe0f Lum ' + lum.toFixed(3) + (isDark ? ' \u2014 Dark' : ' \u2014 Light'));\r\n\r\n            \/* Sidebar *\/\r\n            var sbPrev = document.getElementById('pth-sb-preview');\r\n            if (sbPrev) sbPrev.style.backgroundColor = hex;\r\n            self.setEl('pth-sb-hex', 'HEX: ' + hex.toUpperCase());\r\n            self.setEl('pth-sb-rgb', 'RGB: ' + r + ', ' + g + ', ' + b);\r\n            self.setEl('pth-sb-hsl', 'HSL: ' + hsl.h + '\u00b0 ' + hsl.s + '% ' + hsl.l + '%');\r\n            self.setEl('pth-sb-lum', 'Luminance: ' + lum.toFixed(4));\r\n\r\n            \/* Update all sub-systems *\/\r\n            try { self.updateContrast(r, g, b); } catch(e) {}\r\n            try { self.updatePalette(hsl.h, hsl.s, hsl.l); } catch(e) {}\r\n            try { self.updateColorBlindness(r, g, b); } catch(e) {}\r\n            try { self.generateCssOutput(); } catch(e) {}\r\n            try { self.validatePthColor(r, g, b, hex); } catch(e) {}\r\n            try { self.addToHistory(hex); } catch(e) {}\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 CONTRAST CHECKER \u2500\u2500\u2500 *\/\r\n        updateContrast: function (r, g, b) {\r\n            var self = this;\r\n            var hex = self.rgbToHex(r, g, b);\r\n            var lum = self.getLuminance(r, g, b);\r\n\r\n            var ratioWhite = (1.05) \/ (lum + 0.05);\r\n            var ratioBlack = (lum + 0.05) \/ (0.05);\r\n\r\n            \/* Custom color *\/\r\n            var customPicker = document.getElementById('pth-custom-contrast-picker');\r\n            var customHex = customPicker ? customPicker.value : '#ffffff';\r\n            var customRgb = self.hexToRgb(customHex);\r\n            var lumC      = customRgb ? self.getLuminance(customRgb.r, customRgb.g, customRgb.b) : 1;\r\n            var lumMax    = Math.max(lum, lumC);\r\n            var lumMin    = Math.min(lum, lumC);\r\n            var ratioCustom = (lumMax + 0.05) \/ (lumMin + 0.05);\r\n\r\n            \/* Update boxes background *\/\r\n            var cbW = document.getElementById('pth-cb-white');\r\n            var cbB = document.getElementById('pth-cb-black');\r\n            var cbC = document.getElementById('pth-cb-custom');\r\n            if (cbW) cbW.style.backgroundColor = hex;\r\n            if (cbB) cbB.style.backgroundColor = hex;\r\n            if (cbC) cbC.style.backgroundColor = hex;\r\n\r\n            \/* Update custom sample text color *\/\r\n            var cSampLg = document.getElementById('pth-custom-sample-lg');\r\n            var cSampSm = document.getElementById('pth-custom-sample-sm');\r\n            var ratioEl  = document.getElementById('pth-ratio-custom');\r\n            if (cSampLg) cSampLg.style.color = customHex;\r\n            if (cSampSm) cSampSm.style.color = customHex;\r\n            if (ratioEl) ratioEl.style.color  = customHex;\r\n\r\n            \/* Set ratio text + WCAG badges *\/\r\n            self.setContrastBadges('pth-ratio-white', 'pth-badges-white', ratioWhite, '#ffffff');\r\n            self.setContrastBadges('pth-ratio-black', 'pth-badges-black', ratioBlack, '#000000');\r\n            self.setContrastBadges('pth-ratio-custom', 'pth-badges-custom', ratioCustom, customHex);\r\n\r\n            \/* Suggest fix if white fails *\/\r\n            var fixEl = document.getElementById('pth-fix-suggestion');\r\n            var fixTxt = document.getElementById('pth-fix-text');\r\n            if (ratioWhite < 4.5 && ratioBlack < 4.5 && fixEl && fixTxt) {\r\n                var suggested = ratioBlack > ratioWhite ? '#000000 (black text)' : '#FFFFFF (white text)';\r\n                fixTxt.textContent = 'Use ' + suggested + ' \u2014 ratio ' + (ratioBlack > ratioWhite ? ratioBlack.toFixed(1) : ratioWhite.toFixed(1)) + ':1 (AA pass)';\r\n                fixEl.classList.add('pth-visible');\r\n            } else if (fixEl) {\r\n                fixEl.classList.remove('pth-visible');\r\n            }\r\n        },\r\n\r\n        setContrastBadges: function (ratioId, badgesId, ratio, textColor) {\r\n            var ratioEl  = document.getElementById(ratioId);\r\n            var badgesEl = document.getElementById(badgesId);\r\n            if (ratioEl) { ratioEl.textContent = ratio.toFixed(1) + ':1'; ratioEl.style.color = textColor; }\r\n            if (!badgesEl) return;\r\n            var html = '';\r\n            \/* AA normal text: 4.5:1 | AA large: 3:1 | AAA normal: 7:1 | AAA large: 4.5:1 | UI: 3:1 *\/\r\n            html += '<span class=\"pth-wcag-badge ' + (ratio >= 4.5 ? 'pth-wcag-pass' : 'pth-wcag-fail') + '\">AA<\/span>';\r\n            html += '<span class=\"pth-wcag-badge ' + (ratio >= 3.0 ? 'pth-wcag-pass' : 'pth-wcag-fail') + '\">AA Lg<\/span>';\r\n            html += '<span class=\"pth-wcag-badge ' + (ratio >= 7.0 ? 'pth-wcag-aaa'  : 'pth-wcag-fail') + '\">AAA<\/span>';\r\n            badgesEl.innerHTML = html;\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 PALETTE GENERATOR \u2500\u2500\u2500 *\/\r\n        updatePalette: function (h, s, l) {\r\n            var self = this;\r\n            \/* Tints & Shades \u2014 10 steps *\/\r\n            var shadesGrid = document.getElementById('pth-shades-grid');\r\n            if (shadesGrid) {\r\n                shadesGrid.innerHTML = '';\r\n                var steps = [95, 85, 75, 65, 55, 45, 35, 25, 15, 5];\r\n                steps.forEach(function (lightness) {\r\n                    var rgb = self.hslToRgb(h, s, lightness);\r\n                    var hex = self.rgbToHex(rgb.r, rgb.g, rgb.b);\r\n                    var box = document.createElement('div');\r\n                    box.className = 'pth-shade-box';\r\n                    box.style.backgroundColor = hex;\r\n                    box.title = hex;\r\n                    box.setAttribute('aria-label', 'Color shade ' + hex);\r\n                    box.setAttribute('role', 'button');\r\n                    box.setAttribute('tabindex', '0');\r\n                    box.addEventListener('click', function () {\r\n                        self.updateAll(rgb.r, rgb.g, rgb.b, null);\r\n                        self.showToast('Loaded ' + hex, 'success');\r\n                    });\r\n                    shadesGrid.appendChild(box);\r\n                });\r\n            }\r\n\r\n            \/* Harmony palettes *\/\r\n            self.buildHarmony('complementary', [h, (h + 180) % 360]);\r\n            self.buildHarmony('triadic',  [h, (h + 120) % 360, (h + 240) % 360]);\r\n            self.buildHarmony('analogous', [(h - 30 + 360) % 360, h, (h + 30) % 360]);\r\n            self.buildHarmony('split',    [h, (h + 150) % 360, (h + 210) % 360]);\r\n            self.buildHarmony('mono',     [h, h, h, h, h], [20, 35, 50, 65, 80]);\r\n        },\r\n\r\n        buildHarmony: function (type, hues, lightnesses) {\r\n            var self = this;\r\n            var container = document.getElementById('pth-palette-' + type);\r\n            if (!container) return;\r\n            container.innerHTML = '';\r\n            var hsl = self.rgbToHsl(self.currentRgb.r, self.currentRgb.g, self.currentRgb.b);\r\n\r\n            hues.forEach(function (hue, i) {\r\n                var l = lightnesses ? lightnesses[i] : hsl.l;\r\n                var rgb = self.hslToRgb(hue, hsl.s, l);\r\n                var hex = self.rgbToHex(rgb.r, rgb.g, rgb.b);\r\n                var wrap = document.createElement('div');\r\n                wrap.className = 'pth-swatch-wrap';\r\n                var swatch = document.createElement('div');\r\n                swatch.className = 'pth-swatch';\r\n                swatch.style.backgroundColor = hex;\r\n                swatch.title = hex;\r\n                swatch.setAttribute('role', 'button');\r\n                swatch.setAttribute('tabindex', '0');\r\n                swatch.setAttribute('aria-label', 'Color swatch ' + hex);\r\n                swatch.setAttribute('data-hex', hex);\r\n                swatch.addEventListener('click', function () {\r\n                    self.updateAll(rgb.r, rgb.g, rgb.b, null);\r\n                    self.showToast('Loaded ' + hex, 'success');\r\n                });\r\n                var lbl = document.createElement('span');\r\n                lbl.className = 'pth-swatch-label';\r\n                lbl.textContent = hex.toUpperCase();\r\n                wrap.appendChild(swatch);\r\n                wrap.appendChild(lbl);\r\n                container.appendChild(wrap);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 COLOR BLINDNESS SIMULATOR \u2500\u2500\u2500 *\/\r\n        updateColorBlindness: function (r, g, b) {\r\n            var self = this;\r\n\r\n            function sim(type) {\r\n                var R = r \/ 255, G = g \/ 255, B = b \/ 255;\r\n                var sr = R, sg = G, sb = B;\r\n\r\n                if (type === 'deuteranopia') {\r\n                    sr = 0.625 * R + 0.375 * G; sg = 0.7 * G + 0.3 * B; sb = 0.3 * G + 0.7 * B;\r\n                } else if (type === 'protanopia') {\r\n                    sr = 0.567 * R + 0.433 * G; sg = 0.558 * R + 0.442 * G; sb = 0.242 * G + 0.758 * B;\r\n                } else if (type === 'tritanopia') {\r\n                    sr = 0.95 * R + 0.05 * G; sg = 0.433 * G + 0.567 * B; sb = 0.475 * G + 0.525 * B;\r\n                } else if (type === 'achromatopsia') {\r\n                    var lv = 0.299 * R + 0.587 * G + 0.114 * B;\r\n                    sr = sg = sb = lv;\r\n                } else if (type === 'deuteranomaly') {\r\n                    sr = 0.8 * R + 0.2 * G; sg = 0.258 * R + 0.742 * G; sb = 0.142 * G + 0.858 * B;\r\n                }\r\n\r\n                return 'rgb(' + Math.round(sr * 255) + ',' + Math.round(sg * 255) + ',' + Math.round(sb * 255) + ')';\r\n            }\r\n\r\n            var hex = self.rgbToHex(r, g, b);\r\n            var normal = document.getElementById('pth-cb-normal');\r\n            if (normal) normal.style.backgroundColor = hex;\r\n\r\n            var types = ['deuteranopia','protanopia','tritanopia','achromatopsia','deuteranomaly'];\r\n            types.forEach(function (t) {\r\n                var el = document.getElementById('pth-cb-' + t);\r\n                if (el) el.style.backgroundColor = sim(t);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 COLOR MIXER \u2500\u2500\u2500 *\/\r\n        updateMixer: function () {\r\n            var self = this;\r\n            var aEl   = document.getElementById('pth-mix-a-picker');\r\n            var bEl   = document.getElementById('pth-mix-b-picker');\r\n            var ratio = document.getElementById('pth-mix-ratio');\r\n\r\n            if (!aEl || !bEl || !ratio) return;\r\n            var rgbA = self.hexToRgb(aEl.value) || { r: 37, g: 99, b: 235 };\r\n            var rgbB = self.hexToRgb(bEl.value) || { r: 241, g: 245, b: 249 };\r\n            var t    = parseInt(ratio.value, 10) \/ 100;\r\n\r\n            var mr = Math.round(rgbA.r * t + rgbB.r * (1 - t));\r\n            var mg = Math.round(rgbA.g * t + rgbB.g * (1 - t));\r\n            var mb = Math.round(rgbA.b * t + rgbB.b * (1 - t));\r\n            self.mixResult = { r: mr, g: mg, b: mb };\r\n\r\n            var hexMix = self.rgbToHex(mr, mg, mb);\r\n            var lumA   = self.getLuminance(rgbA.r, rgbA.g, rgbA.b);\r\n            var lumB   = self.getLuminance(rgbB.r, rgbB.g, rgbB.b);\r\n            var lumM   = self.getLuminance(mr, mg, mb);\r\n\r\n            var elA = document.getElementById('pth-mix-a');\r\n            var elB = document.getElementById('pth-mix-b');\r\n            var elR = document.getElementById('pth-mix-result');\r\n            var lblR= document.getElementById('pth-mix-result-label');\r\n\r\n            if (elA) { elA.style.backgroundColor = aEl.value; elA.style.color = lumA < 0.179 ? '#fff' : '#0f172a'; }\r\n            if (elB) { elB.style.backgroundColor = bEl.value; elB.style.color = lumB < 0.179 ? '#fff' : '#0f172a'; }\r\n            if (elR) { elR.style.backgroundColor = hexMix; elR.style.color = lumM < 0.179 ? '#fff' : '#0f172a'; elR.textContent = hexMix.toUpperCase(); }\r\n            if (lblR) lblR.textContent = hexMix.toUpperCase();\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 GRADIENT GENERATOR \u2500\u2500\u2500 *\/\r\n        updateGradient: function () {\r\n            var self = this;\r\n            var gradA  = document.getElementById('pth-grad-a');\r\n            var gradB  = document.getElementById('pth-grad-b');\r\n            var angle  = document.getElementById('pth-grad-angle');\r\n            var prev   = document.getElementById('pth-gradient-preview');\r\n            var cssOut = document.getElementById('pth-gradient-css');\r\n            if (!gradA || !gradB || !angle || !prev || !cssOut) return;\r\n\r\n            var a   = gradA.value;\r\n            var b   = gradB.value;\r\n            var deg = angle.value;\r\n            var css = 'background: linear-gradient(' + deg + ', ' + a + ', ' + b + ');';\r\n            var fallback = 'background: ' + a + '; \/* fallback *\/\\n';\r\n\r\n            prev.style.background = 'linear-gradient(' + deg + ', ' + a + ', ' + b + ')';\r\n            cssOut.textContent = fallback + css + '\\n\\n\/* With webkit prefix *\/\\n' +\r\n                'background: -webkit-linear-gradient(' + deg + ', ' + a + ', ' + b + ');\\n' + css;\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 IMAGE COLOR PICKER \u2500\u2500\u2500 *\/\r\n        loadImageFile: function (file) {\r\n            var self = this;\r\n            var reader = new FileReader();\r\n            reader.onload = function (e) {\r\n                var img = new Image();\r\n                img.onload = function () {\r\n                    var canvas = document.getElementById('pth-img-canvas');\r\n                    var wrap   = document.getElementById('pth-img-canvas-wrap');\r\n                    var drop   = document.getElementById('pth-img-drop-zone');\r\n                    if (!canvas) return;\r\n                    var ctx = canvas.getContext('2d');\r\n                    canvas.width  = img.width;\r\n                    canvas.height = img.height;\r\n                    ctx.drawImage(img, 0, 0);\r\n                    self.imgData = { canvas: canvas, ctx: ctx };\r\n                    if (wrap) wrap.style.display = 'block';\r\n                    if (drop) drop.style.display = 'none';\r\n                    self.showToast('Image loaded \u2014 click any pixel to pick color!', 'success');\r\n                };\r\n                img.src = e.target.result;\r\n            };\r\n            reader.readAsDataURL(file);\r\n        },\r\n\r\n        pickImageColor: function (e) {\r\n            var self = this;\r\n            var canvas = document.getElementById('pth-img-canvas');\r\n            if (!canvas || !self.imgData) return;\r\n            var rect = canvas.getBoundingClientRect();\r\n            var scaleX = canvas.width  \/ rect.width;\r\n            var scaleY = canvas.height \/ rect.height;\r\n            var x = Math.round((e.clientX - rect.left) * scaleX);\r\n            var y = Math.round((e.clientY - rect.top)  * scaleY);\r\n            var pixel = self.imgData.ctx.getImageData(x, y, 1, 1).data;\r\n            var r = pixel[0], g = pixel[1], b = pixel[2];\r\n            var hex = self.rgbToHex(r, g, b);\r\n\r\n            self.pickedColor = { r: r, g: g, b: b, hex: hex };\r\n\r\n            var bar     = document.getElementById('pth-picked-color-bar');\r\n            var swatch  = document.getElementById('pth-picked-swatch');\r\n            var hexEl   = document.getElementById('pth-picked-hex');\r\n            var rgbEl   = document.getElementById('pth-picked-rgb');\r\n            if (bar)    bar.style.display = 'flex';\r\n            if (swatch) swatch.style.backgroundColor = hex;\r\n            if (hexEl)  hexEl.textContent = hex.toUpperCase();\r\n            if (rgbEl)  rgbEl.textContent = 'rgb(' + r + ', ' + g + ', ' + b + ')';\r\n        },\r\n\r\n        showCrosshair: function (e) {\r\n            var canvas = document.getElementById('pth-img-canvas');\r\n            var ch     = document.getElementById('pth-img-crosshair');\r\n            if (!canvas || !ch || !this.imgData) return;\r\n            var rect = canvas.getBoundingClientRect();\r\n            ch.style.display = 'block';\r\n            ch.style.left = (e.clientX - rect.left) + 'px';\r\n            ch.style.top  = (e.clientY - rect.top)  + 'px';\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 CSS OUTPUT GENERATOR \u2500\u2500\u2500 *\/\r\n        setCssType: function (type) {\r\n            var self = this;\r\n            self.cssType = type;\r\n            document.querySelectorAll('[data-css-type]').forEach(function (btn) {\r\n                var isActive = btn.getAttribute('data-css-type') === type;\r\n                btn.classList.toggle('pth-active', isActive);\r\n                btn.setAttribute('aria-pressed', isActive ? 'true' : 'false');\r\n            });\r\n            self.generateCssOutput();\r\n        },\r\n\r\n        generateCssOutput: function () {\r\n            var self = this;\r\n            var el      = document.getElementById('pth-css-output');\r\n            var nameEl  = document.getElementById('pth-css-varname');\r\n            if (!el) return;\r\n\r\n            var name = (nameEl ? nameEl.value.trim() : 'primary') || 'primary';\r\n            var r = self.currentRgb.r, g = self.currentRgb.g, b = self.currentRgb.b;\r\n            var hex  = self.rgbToHex(r, g, b).toUpperCase();\r\n            var hsl  = self.rgbToHsl(r, g, b);\r\n            var cmyk = self.rgbToCmyk(r, g, b);\r\n            var output = '';\r\n\r\n            if (self.cssType === 'properties') {\r\n                output =\r\n                    '.element {\\n' +\r\n                    '  background-color: ' + hex + ';\\n' +\r\n                    '  color: ' + hex + ';\\n' +\r\n                    '  border-color: ' + hex + ';\\n' +\r\n                    '  outline-color: ' + hex + ';\\n' +\r\n                    '  box-shadow: 0 4px 14px rgba(' + r + ',' + g + ',' + b + ',0.3);\\n' +\r\n                    '  \/* HSL variant *\/\\n' +\r\n                    '  background-color: hsl(' + hsl.h + ', ' + hsl.s + '%, ' + hsl.l + '%);\\n' +\r\n                    '}';\r\n\r\n            } else if (self.cssType === 'variables') {\r\n                var hslDark  = self.hslToRgb(hsl.h, hsl.s, Math.max(0, hsl.l - 15));\r\n                var hslLight = self.hslToRgb(hsl.h, hsl.s, Math.min(100, hsl.l + 15));\r\n                output =\r\n                    ':root {\\n' +\r\n                    '  --color-' + name + ':        ' + hex + ';\\n' +\r\n                    '  --color-' + name + '-dark:   ' + self.rgbToHex(hslDark.r, hslDark.g, hslDark.b).toUpperCase() + ';\\n' +\r\n                    '  --color-' + name + '-light:  ' + self.rgbToHex(hslLight.r, hslLight.g, hslLight.b).toUpperCase() + ';\\n' +\r\n                    '  --color-' + name + '-rgb:    ' + r + ', ' + g + ', ' + b + ';\\n' +\r\n                    '  --color-' + name + '-hsl:    ' + hsl.h + 'deg ' + hsl.s + '% ' + hsl.l + '%;\\n' +\r\n                    '  --color-' + name + '-alpha30: rgba(' + r + ',' + g + ',' + b + ',0.3);\\n' +\r\n                    '  --color-' + name + '-alpha10: rgba(' + r + ',' + g + ',' + b + ',0.1);\\n' +\r\n                    '}';\r\n\r\n            } else if (self.cssType === 'tokens') {\r\n                var tokObj = {\r\n                    color: {}\r\n                };\r\n                tokObj.color[name] = {\r\n                    value: hex,\r\n                    type: 'color',\r\n                    description: 'Generated by PTH Color Studio v2.0',\r\n                    rgb: { r: r, g: g, b: b },\r\n                    hsl: { h: hsl.h, s: hsl.s + '%', l: hsl.l + '%' },\r\n                    cmyk: cmyk\r\n                };\r\n                output = JSON.stringify(tokObj, null, 2);\r\n\r\n            } else if (self.cssType === 'tailwind') {\r\n                var hslDk = self.hslToRgb(hsl.h, hsl.s, 20);\r\n                var hslLt = self.hslToRgb(hsl.h, Math.max(0, hsl.s - 10), 90);\r\n                output =\r\n                    '\/\/ tailwind.config.js\\n' +\r\n                    'module.exports = {\\n' +\r\n                    '  theme: {\\n' +\r\n                    '    extend: {\\n' +\r\n                    '      colors: {\\n' +\r\n                    '        ' + name + ': {\\n' +\r\n                    '          50:  \\'' + self.rgbToHex(hslLt.r, hslLt.g, hslLt.b).toUpperCase() + '\\',\\n' +\r\n                    '          500: \\'' + hex + '\\',\\n' +\r\n                    '          900: \\'' + self.rgbToHex(hslDk.r, hslDk.g, hslDk.b).toUpperCase() + '\\',\\n' +\r\n                    '        },\\n' +\r\n                    '      },\\n' +\r\n                    '    },\\n' +\r\n                    '  },\\n' +\r\n                    '};';\r\n            }\r\n\r\n            el.textContent = output;\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 PTH COLOR VALIDATOR \u2500\u2500\u2500 *\/\r\n        validatePthColor: function (r, g, b, hex) {\r\n            var lum = this.getLuminance(r, g, b);\r\n            var ratioOnWhite = (1.05) \/ (lum + 0.05);\r\n            var ratioOnBlack = (lum + 0.05) \/ (0.05);\r\n            var el = document.getElementById('pth-validator-output');\r\n            if (!el) return;\r\n\r\n            var issues = [];\r\n            var passes = [];\r\n\r\n            if (ratioOnWhite >= 4.5) passes.push('\u2705 Passes WCAG AA as text on white background (' + ratioOnWhite.toFixed(1) + ':1)');\r\n            else issues.push('\u274c Fails WCAG AA as text on white (' + ratioOnWhite.toFixed(1) + ':1 \u2014 needs 4.5:1)');\r\n\r\n            if (ratioOnWhite >= 7.0) passes.push('\u2705 Passes WCAG AAA on white (' + ratioOnWhite.toFixed(1) + ':1)');\r\n            if (ratioOnBlack >= 4.5) passes.push('\u2705 Passes WCAG AA as text on black (' + ratioOnBlack.toFixed(1) + ':1)');\r\n\r\n            \/* PTH approved colors check *\/\r\n            var pthApproved = ['#1e293b','#0f172a','#1d4ed8','#334155','#5b21b6','#4c1d95','#6d28d9','#047857','#14532d','#991b1b','#92400e','#059669','#dc2626','#2563eb'];\r\n            var isApproved = pthApproved.indexOf(hex.toLowerCase()) > -1;\r\n            if (isApproved) passes.push('\u2705 PTH Instruction v3.1 approved color');\r\n\r\n            if (ratioOnWhite < 4.5 && ratioOnBlack < 4.5) {\r\n                issues.push('\u26a0\ufe0f This color fails as text on both white and black \u2014 use as background only');\r\n            }\r\n\r\n            var html = '';\r\n            passes.forEach(function (p) { html += '<div style=\"color:#047857;margin-bottom:4px;\">' + p + '<\/div>'; });\r\n            issues.forEach(function (i) { html += '<div style=\"color:#991b1b;margin-bottom:4px;\">' + i + '<\/div>'; });\r\n            el.innerHTML = html || '<div style=\"color:#334155;\">Analysis complete for ' + hex.toUpperCase() + '<\/div>';\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 COPY HELPERS \u2500\u2500\u2500 *\/\r\n        copyAllFormats: function () {\r\n            var self = this;\r\n            var ids = ['pth-in-hex','pth-in-rgb','pth-in-hsl','pth-in-hsb','pth-in-cmyk','pth-in-lab'];\r\n            var lines = [];\r\n            ids.forEach(function (id) {\r\n                var el = document.getElementById(id);\r\n                if (el && el.value) lines.push(el.value);\r\n            });\r\n            self.copyToClipboard(lines.join('\\n'), null);\r\n            self.showToast('All formats copied!', 'success');\r\n        },\r\n\r\n        copyPalette: function (type) {\r\n            var self = this;\r\n            var container = document.getElementById('pth-palette-' + type);\r\n            if (!container) return;\r\n            var hexes = [];\r\n            container.querySelectorAll('[data-hex]').forEach(function (el) {\r\n                hexes.push(el.getAttribute('data-hex'));\r\n            });\r\n            self.copyToClipboard(hexes.join(', '), null);\r\n            self.showToast(type + ' palette copied!', 'success');\r\n        },\r\n\r\n        copyShadesCss: function () {\r\n            var self = this;\r\n            var hsl = self.rgbToHsl(self.currentRgb.r, self.currentRgb.g, self.currentRgb.b);\r\n            var steps = [95, 85, 75, 65, 55, 45, 35, 25, 15, 5];\r\n            var names = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900];\r\n            var lines = [':root {'];\r\n            steps.forEach(function (l, i) {\r\n                var rgb = self.hslToRgb(hsl.h, hsl.s, l);\r\n                lines.push('  --shade-' + names[i] + ': ' + self.rgbToHex(rgb.r, rgb.g, rgb.b).toUpperCase() + ';');\r\n            });\r\n            lines.push('}');\r\n            self.copyToClipboard(lines.join('\\n'), null);\r\n            self.showToast('Shades CSS variables copied!', 'success');\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 HISTORY \u2500\u2500\u2500 *\/\r\n        addToHistory: function (hex) {\r\n            var self = this;\r\n            if (self.history[0] === hex) return;\r\n            self.history.unshift(hex);\r\n            if (self.history.length > 12) self.history.pop();\r\n            var container = document.getElementById('pth-color-history');\r\n            if (!container) return;\r\n            container.innerHTML = '';\r\n            self.history.forEach(function (h) {\r\n                var sw = document.createElement('div');\r\n                sw.className = 'pth-history-swatch';\r\n                sw.style.backgroundColor = h;\r\n                sw.title = h;\r\n                sw.setAttribute('role', 'button');\r\n                sw.setAttribute('tabindex', '0');\r\n                sw.setAttribute('aria-label', 'Load color ' + h + ' from history');\r\n                sw.addEventListener('click', function () {\r\n                    var rgb = self.hexToRgb(h);\r\n                    if (rgb) self.updateAll(rgb.r, rgb.g, rgb.b, null);\r\n                });\r\n                container.appendChild(sw);\r\n            });\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 LOAD SAMPLE \/ RANDOM \u2500\u2500\u2500 *\/\r\n        loadSample: function () {\r\n            this.updateAll(37, 99, 235, null);\r\n            this.showToast('Sample color loaded \u2014 PTH Blue #2563EB!', 'success');\r\n        },\r\n        loadRandom: function () {\r\n            var r = Math.floor(Math.random() * 256);\r\n            var g = Math.floor(Math.random() * 256);\r\n            var b = Math.floor(Math.random() * 256);\r\n            this.updateAll(r, g, b, null);\r\n            this.showToast('Random color: ' + this.rgbToHex(r, g, b).toUpperCase(), 'info');\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 FORMAT PARSERS \u2500\u2500\u2500 *\/\r\n        parseFormat: function (type, value) {\r\n            var self = this;\r\n            value = value.trim();\r\n            try {\r\n                if (type === 'hex') {\r\n                    return self.hexToRgb(value);\r\n                } else if (type === 'rgb') {\r\n                    var m = value.match(\/(\\d+)[,\\s]+(\\d+)[,\\s]+(\\d+)\/);\r\n                    if (!m) return null;\r\n                    return { r: parseInt(m[1]), g: parseInt(m[2]), b: parseInt(m[3]) };\r\n                } else if (type === 'hsl') {\r\n                    var m2 = value.match(\/([\\d.]+)[,\\s]+(\\d+)%?[,\\s]+(\\d+)%?\/);\r\n                    if (!m2) return null;\r\n                    return self.hslToRgb(parseFloat(m2[1]), parseFloat(m2[2]), parseFloat(m2[3]));\r\n                } else if (type === 'hsb') {\r\n                    var m3 = value.match(\/([\\d.]+)[,\\s]+([\\d.]+)%?[,\\s]+([\\d.]+)%?\/);\r\n                    if (!m3) return null;\r\n                    return self.hsbToRgb(parseFloat(m3[1]), parseFloat(m3[2]), parseFloat(m3[3]));\r\n                } else if (type === 'cmyk') {\r\n                    var m4 = value.match(\/([\\d.]+)%?[,\\s]+([\\d.]+)%?[,\\s]+([\\d.]+)%?[,\\s]+([\\d.]+)%?\/);\r\n                    if (!m4) return null;\r\n                    return self.cmykToRgb(parseFloat(m4[1]), parseFloat(m4[2]), parseFloat(m4[3]), parseFloat(m4[4]));\r\n                } else if (type === 'lab') {\r\n                    var m5 = value.match(\/([\\d.]+)[,\\s]+([-\\d.]+)[,\\s]+([-\\d.]+)\/);\r\n                    if (!m5) return null;\r\n                    return self.labToRgb(parseFloat(m5[1]), parseFloat(m5[2]), parseFloat(m5[3]));\r\n                }\r\n            } catch(e) { return null; }\r\n            return null;\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 FIND NAMED \/ TAILWIND \u2500\u2500\u2500 *\/\r\n        findNamedColor: function (hex) {\r\n            var self = this;\r\n            var h = hex.toUpperCase();\r\n            for (var name in self.cssNamedColors) {\r\n                if (self.cssNamedColors[name].toUpperCase() === h) return name;\r\n            }\r\n            return null;\r\n        },\r\n\r\n        findTailwindColor: function (r, g, b) {\r\n            var self = this;\r\n            var best = null, bestDist = Infinity;\r\n            for (var name in self.tailwindColors) {\r\n                var tc = self.tailwindColors[name];\r\n                if (tc === 'transparent') continue;\r\n                var tRgb = self.hexToRgb(tc);\r\n                if (!tRgb) continue;\r\n                var dist = Math.sqrt(\r\n                    Math.pow(r - tRgb.r, 2) +\r\n                    Math.pow(g - tRgb.g, 2) +\r\n                    Math.pow(b - tRgb.b, 2)\r\n                );\r\n                if (dist < bestDist) { bestDist = dist; best = name; }\r\n            }\r\n            return bestDist < 30 ? best : (best + ' ~');\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 MATH: COLOR CONVERSIONS \u2500\u2500\u2500 *\/\r\n        hexToRgb: function (hex) {\r\n            hex = hex.replace(\/^#\/, '');\r\n            if (hex.length === 3) hex = hex.split('').map(function (c) { return c + c; }).join('');\r\n            if (hex.length !== 6) return null;\r\n            var n = parseInt(hex, 16);\r\n            if (isNaN(n)) return null;\r\n            return { r: (n >> 16) & 255, g: (n >> 8) & 255, b: n & 255 };\r\n        },\r\n\r\n        rgbToHex: function (r, g, b) {\r\n            return '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1).toUpperCase();\r\n        },\r\n\r\n        rgbToHsl: function (r, g, b) {\r\n            r \/= 255; g \/= 255; b \/= 255;\r\n            var max = Math.max(r, g, b), min = Math.min(r, g, b);\r\n            var h, s, l = (max + min) \/ 2;\r\n            if (max === min) { h = s = 0; }\r\n            else {\r\n                var d = max - min;\r\n                s = l > 0.5 ? d \/ (2 - max - min) : d \/ (max + min);\r\n                if      (max === r) h = (g - b) \/ d + (g < b ? 6 : 0);\r\n                else if (max === g) h = (b - r) \/ d + 2;\r\n                else                h = (r - g) \/ d + 4;\r\n                h \/= 6;\r\n            }\r\n            return { h: Math.round(h * 360), s: Math.round(s * 100), l: Math.round(l * 100) };\r\n        },\r\n\r\n        hslToRgb: function (h, s, l) {\r\n            s \/= 100; l \/= 100;\r\n            var c = (1 - Math.abs(2 * l - 1)) * s;\r\n            var x = c * (1 - Math.abs((h \/ 60) % 2 - 1));\r\n            var m = l - c \/ 2;\r\n            var r = 0, g = 0, b = 0;\r\n            if      (h < 60)  { r = c; g = x; b = 0; }\r\n            else if (h < 120) { r = x; g = c; b = 0; }\r\n            else if (h < 180) { r = 0; g = c; b = x; }\r\n            else if (h < 240) { r = 0; g = x; b = c; }\r\n            else if (h < 300) { r = x; g = 0; b = c; }\r\n            else               { r = c; g = 0; b = x; }\r\n            return {\r\n                r: Math.round((r + m) * 255),\r\n                g: Math.round((g + m) * 255),\r\n                b: Math.round((b + m) * 255)\r\n            };\r\n        },\r\n\r\n        rgbToHsb: function (r, g, b) {\r\n            r \/= 255; g \/= 255; b \/= 255;\r\n            var max = Math.max(r, g, b), min = Math.min(r, g, b), d = max - min;\r\n            var h = 0, s = max === 0 ? 0 : d \/ max, v = max;\r\n            if (max !== min) {\r\n                if      (max === r) h = (g - b) \/ d + (g < b ? 6 : 0);\r\n                else if (max === g) h = (b - r) \/ d + 2;\r\n                else                h = (r - g) \/ d + 4;\r\n                h \/= 6;\r\n            }\r\n            return { h: Math.round(h * 360), s: Math.round(s * 100), b: Math.round(v * 100) };\r\n        },\r\n\r\n        hsbToRgb: function (h, s, v) {\r\n            s \/= 100; v \/= 100;\r\n            var i = Math.floor(h \/ 60) % 6;\r\n            var f = h \/ 60 - Math.floor(h \/ 60);\r\n            var p = v * (1 - s), q = v * (1 - f * s), t = v * (1 - (1 - f) * s);\r\n            var r, g, b;\r\n            if      (i === 0) { r = v; g = t; b = p; }\r\n            else if (i === 1) { r = q; g = v; b = p; }\r\n            else if (i === 2) { r = p; g = v; b = t; }\r\n            else if (i === 3) { r = p; g = q; b = v; }\r\n            else if (i === 4) { r = t; g = p; b = v; }\r\n            else               { r = v; g = p; b = q; }\r\n            return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };\r\n        },\r\n\r\n        rgbToCmyk: function (r, g, b) {\r\n            var c = 1 - r \/ 255, m = 1 - g \/ 255, y = 1 - b \/ 255;\r\n            var k = Math.min(c, m, y);\r\n            if (k === 1) return { c: 0, m: 0, y: 0, k: 100 };\r\n            return {\r\n                c: Math.round((c - k) \/ (1 - k) * 100),\r\n                m: Math.round((m - k) \/ (1 - k) * 100),\r\n                y: Math.round((y - k) \/ (1 - k) * 100),\r\n                k: Math.round(k * 100)\r\n            };\r\n        },\r\n\r\n        cmykToRgb: function (c, m, y, k) {\r\n            c \/= 100; m \/= 100; y \/= 100; k \/= 100;\r\n            return {\r\n                r: Math.round(255 * (1 - c) * (1 - k)),\r\n                g: Math.round(255 * (1 - m) * (1 - k)),\r\n                b: Math.round(255 * (1 - y) * (1 - k))\r\n            };\r\n        },\r\n\r\n        rgbToLab: function (r, g, b) {\r\n            \/* sRGB \u2192 XYZ \u2192 LAB *\/\r\n            var toLinear = function (v) { v \/= 255; return v <= 0.04045 ? v \/ 12.92 : Math.pow((v + 0.055) \/ 1.055, 2.4); };\r\n            var rl = toLinear(r), gl = toLinear(g), bl = toLinear(b);\r\n            var x = (rl * 0.4124 + gl * 0.3576 + bl * 0.1805) \/ 0.95047;\r\n            var y = (rl * 0.2126 + gl * 0.7152 + bl * 0.0722) \/ 1.00000;\r\n            var z = (rl * 0.0193 + gl * 0.1192 + bl * 0.9505) \/ 1.08883;\r\n            var f = function (t) { return t > 0.008856 ? Math.cbrt(t) : 7.787 * t + 16 \/ 116; };\r\n            var L = 116 * f(y) - 16;\r\n            var A = 500 * (f(x) - f(y));\r\n            var B = 200 * (f(y) - f(z));\r\n            return { l: Math.round(L), a: Math.round(A), b2: Math.round(B) };\r\n        },\r\n\r\n        labToRgb: function (L, A, B) {\r\n            var fy = (L + 16) \/ 116, fx = A \/ 500 + fy, fz = fy - B \/ 200;\r\n            var x = (Math.pow(fx, 3) > 0.008856 ? Math.pow(fx, 3) : (fx - 16 \/ 116) \/ 7.787) * 0.95047;\r\n            var y = (Math.pow(fy, 3) > 0.008856 ? Math.pow(fy, 3) : (fy - 16 \/ 116) \/ 7.787) * 1.00000;\r\n            var z = (Math.pow(fz, 3) > 0.008856 ? Math.pow(fz, 3) : (fz - 16 \/ 116) \/ 7.787) * 1.08883;\r\n            var toSrgb = function (v) { v = v <= 0.0031308 ? 12.92 * v : 1.055 * Math.pow(v, 1 \/ 2.4) - 0.055; return Math.max(0, Math.min(255, Math.round(v * 255))); };\r\n            return {\r\n                r: toSrgb(3.2406 * x - 1.5372 * y - 0.4986 * z),\r\n                g: toSrgb(-0.9689 * x + 1.8758 * y + 0.0415 * z),\r\n                b: toSrgb(0.0557 * x - 0.2040 * y + 1.0570 * z)\r\n            };\r\n        },\r\n\r\n        getLuminance: function (r, g, b) {\r\n            var toL = function (v) { v \/= 255; return v <= 0.03928 ? v \/ 12.92 : Math.pow((v + 0.055) \/ 1.055, 2.4); };\r\n            return 0.2126 * toL(r) + 0.7152 * toL(g) + 0.0722 * toL(b);\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 FULL WIDTH TOGGLE \u2500\u2500\u2500 *\/\r\n        toggleWidth: function () {\r\n            var layout  = document.getElementById('pth-color-layout');\r\n            var sidebar = document.getElementById('pth-color-sidebar');\r\n            var btn     = document.getElementById('pth-cs-fw-btn');\r\n            if (!layout || !sidebar || !btn) return;\r\n            if (layout.classList.contains('pth-full-width')) {\r\n                layout.classList.remove('pth-full-width');\r\n                sidebar.style.display = '';\r\n                btn.textContent = '\\u29c6 Full Width';\r\n            } else {\r\n                layout.classList.add('pth-full-width');\r\n                sidebar.style.display = 'none';\r\n                btn.textContent = '\\u25e8 Split View';\r\n            }\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 HELPERS \u2500\u2500\u2500 *\/\r\n        setVal: function (id, val) { var el = document.getElementById(id); if (el) el.value = val; },\r\n        setEl:  function (id, val) { var el = document.getElementById(id); if (el) el.textContent = val; },\r\n\r\n        copyToClipboard: function (text, btn) {\r\n            var self = this;\r\n            try {\r\n                navigator.clipboard.writeText(text).then(function () {\r\n                    if (btn) { btn.classList.add('copied'); setTimeout(function () { btn.classList.remove('copied'); }, 2000); }\r\n                }).catch(function () { self.fallbackCopy(text); });\r\n            } catch(e) { self.fallbackCopy(text); }\r\n        },\r\n\r\n        fallbackCopy: function (text) {\r\n            var ta = document.createElement('textarea');\r\n            ta.value = text; ta.style.position = 'fixed'; ta.style.top = '-9999px';\r\n            document.body.appendChild(ta); ta.select();\r\n            try { document.execCommand('copy'); } catch(e) {}\r\n            document.body.removeChild(ta);\r\n        },\r\n\r\n        \/* \u2500\u2500\u2500 TOAST \u2500\u2500\u2500 *\/\r\n        showToast: function (msg, type) {\r\n            var c = document.getElementById('pth-color-toast');\r\n            if (!c) return;\r\n            var t = document.createElement('div');\r\n            t.className = 'pth-toast-msg pth-toast-' + (type || 'info');\r\n            t.textContent = msg;\r\n            c.appendChild(t);\r\n            setTimeout(function () { if (t.parentNode) t.parentNode.removeChild(t); }, 3500);\r\n        }\r\n    };\r\n\r\n    \/* =======================================================\r\n       BOOTSTRAP \u2014 WP\/LiteSpeed 4-layer safe init (v3.0)\r\n       ======================================================= *\/\r\n    function runInit() {\r\n        if (!window.pthColorApp.initialized &&\r\n            document.getElementById('pth-color-wrapper')) {\r\n            window.pthColorApp.initialized = true;\r\n            window.pthColorApp.init();\r\n        }\r\n    }\r\n    runInit();\r\n    if (document.readyState === 'loading') {\r\n        document.addEventListener('DOMContentLoaded', runInit);\r\n    }\r\n    window.addEventListener('load', function () { setTimeout(runInit, 50); });\r\n    if (!window.pthColorApp.initialized && typeof MutationObserver !== 'undefined') {\r\n        var pthObs = new MutationObserver(function () {\r\n            if (document.getElementById('pth-color-wrapper')) {\r\n                pthObs.disconnect(); runInit();\r\n            }\r\n        });\r\n        pthObs.observe(document.body || document.documentElement, { childList: true, subtree: true });\r\n        setTimeout(function () { pthObs.disconnect(); }, 10000);\r\n    }\r\n\r\n})();\r\n<\/script>\n\n\n\n<style>\n.pth-feature-wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px;margin-bottom:30px}\n.pth-feat-box{border:1px solid #e2e8f0;background:#fff;padding:24px;border-radius:12px;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);transition:all .3s ease}\n.pth-feat-box:hover{border-color:#bfdbfe;transform:translateY(-3px);box-shadow:0 10px 15px -3px rgba(0,0,0,0.05)}\n.pth-feat-title{font-size:1.05rem;font-weight:800;color:#0f172a;margin-bottom:10px;display:flex;align-items:center;gap:10px}\n.pth-feat-text{font-size:.9rem;color:#1e293b;line-height:1.6;margin:0;font-weight:500}\n.pth-steps-wrap{border:1px solid #e2e8f0;background:#fff;padding:40px 30px;border-radius:16px;text-align:center;box-shadow:0 4px 6px -1px rgba(0,0,0,0.02);margin-bottom:40px}\n.pth-steps-title{font-size:1.2rem;font-weight:800;color:#0f172a;text-transform:uppercase;margin-bottom:35px;letter-spacing:1px}\n.pth-steps-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:30px}\n.pth-step-item{display:flex;flex-direction:column;align-items:center}\n.pth-step-num{width:45px;height:45px;background:#2563eb;color:#fff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:800;font-size:1.2rem;margin-bottom:15px;box-shadow:0 4px 10px rgba(37,99,235,.3)}\n.pth-step-name{font-weight:800;color:#0f172a;margin-bottom:8px;font-size:1rem}\n.pth-step-desc{font-size:.9rem;color:#1e293b;line-height:1.5;margin:0;font-weight:500}\n<\/style>\n\n<div class=\"pth-feature-wrap\">\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\ud83d\udfe2 7-Format Color Converter with Named Color Detection<\/div>\n        <p class=\"pth-feat-text\">The \ud83d\udd04 Convert tab handles seven color formats simultaneously \u2014 HEX, RGB, HSL, HSB, CMYK, LAB, and CSS Custom Properties. Type any format in any field and every other format updates instantly. The tool automatically detects whether your color matches a CSS named color (cornflowerblue, coral, steelblue \u2014 140+ names checked) and finds the nearest Tailwind CSS color class within a perceptual distance threshold. Copy individual formats with single-click copy buttons, or click Copy All Formats to grab every format at once in a single clipboard operation.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\ud83d\udd35 Full WCAG 2.1 Contrast Checker with Auto Fix<\/div>\n        <p class=\"pth-feat-text\">The \ud83d\udd0d Contrast tab calculates WCAG 2.1 contrast ratios against white text, black text, and any custom color you pick. Each combination shows three badge levels \u2014 AA (4.5:1 normal text), AA Large (3:1 for 18pt+ text), and AAA (7:1 strict). Exact contrast ratios display numerically \u2014 4.7:1, 12.3:1 \u2014 not just pass\/fail. When both white and black text fail the AA threshold, a gold suggestion box appears recommending which achieves the better ratio. The custom text color picker lets you check any hex color combination for your specific design context.<\/p>\n    <\/div>\n    <div class=\"pth-feat-box\">\n        <div class=\"pth-feat-title\">\ud83d\udfe3 Palette Generator, Image Picker &#038; Color Blindness Simulator<\/div>\n        <p class=\"pth-feat-text\">The \ud83c\udf08 Palette tab generates five harmony types from any active color \u2014 Complementary (180\u00b0), Triadic (120\u00b0 apart), Analogous (\u00b130\u00b0), Split-Complementary, and Monochromatic \u2014 plus a 10-step tint and shade scale with one-click CSS variable export. The \ud83d\udee0\ufe0f Tools tab adds an Image Color Picker (upload any image, click any pixel to extract its exact HEX and RGB values), a Gradient Generator with CSS output, and a 6-type Color Blindness Simulator showing Deuteranopia, Protanopia, Tritanopia, Achromatopsia, Deuteranomaly, and normal vision side by side.<\/p>\n    <\/div>\n<\/div>\n\n<div class=\"pth-steps-wrap\">\n    <div class=\"pth-steps-title\">How to Use Color Studio Pro<\/div>\n    <div class=\"pth-steps-grid\">\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">1<\/div>\n            <div class=\"pth-step-name\">Pick or Enter Your Color<\/div>\n            <p class=\"pth-step-desc\">Click the color picker square to open the native browser color wheel, or type directly into any format field \u2014 HEX (#2563EB), RGB (37, 99, 235), HSL (221, 83%, 53%), or CMYK. The large color preview hero updates instantly. Click \ud83c\udfb2 Random to generate a random color, or \ud83d\udca1 Load Sample to load PTH Blue for reference.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">2<\/div>\n            <div class=\"pth-step-name\">Check WCAG Contrast<\/div>\n            <p class=\"pth-step-desc\">Switch to the \ud83d\udd0d Contrast tab. The two main boxes show your color as the background with white text and black text \u2014 WCAG AA, AA Large, and AAA badges update live. Pick a custom text color using the color picker to check any specific combination. If neither white nor black passes AA, a gold suggestion box recommends the better option automatically.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">3<\/div>\n            <div class=\"pth-step-name\">Generate Palettes<\/div>\n            <p class=\"pth-step-desc\">Switch to \ud83c\udf08 Palette. A 10-step shade scale appears instantly \u2014 click any shade to load it as your active color. Complementary, triadic, analogous, split-complementary, and monochromatic harmony palettes generate below. Click \ud83d\udccb Copy CSS Vars on the shade scale to copy all 10 shades as <code>--shade-50<\/code> through <code>--shade-900<\/code> CSS variables ready to paste into your stylesheet.<\/p>\n        <\/div>\n        <div class=\"pth-step-item\">\n            <div class=\"pth-step-num\">4<\/div>\n            <div class=\"pth-step-name\">Export CSS Code<\/div>\n            <p class=\"pth-step-desc\">Switch to \ud83d\udcbb CSS Output. Choose from four formats: CSS Properties (background, color, border, box-shadow), CSS Variables (with dark\/light variants and alpha channels), Design Tokens JSON (compatible with Figma and Style Dictionary), or Tailwind Config with 50\/500\/900 scale entries. Enter your token name in the input field, then click \ud83d\udccb Copy Code to paste directly into your project.<\/p>\n        <\/div>\n    <\/div>\n<\/div>\n\n\n\n<h2 id=\"\ud83d\udd34-why-color-format-conversion-matters-across-design-and-development-workflows\" class=\"wp-block-heading\">\ud83d\udd34&nbsp;<strong>Why Color Format Conversion Matters Across Design and Development Workflows<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A single color exists simultaneously in multiple formats \u2014 and different tools, contexts, and outputs expect different ones. Figma exports hex values. CSS stylesheets use hex, RGB, or HSL. Print workflows require CMYK. Machine learning pipelines and color science calculations work in LAB color space. Tailwind CSS uses named utility classes. Design tokens use JSON. When a brand color changes from one format to another as it moves through a workflow \u2014 from the designer&#8217;s hex code to the developer&#8217;s RGB variable to the printer&#8217;s CMYK specification \u2014 conversion errors introduce subtle but real color shifts if the wrong formula is used.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Convert tab in this tool handles all seven formats in a single view with live bidirectional updates. Every field accepts input \u2014 type an HSL value, and HEX, RGB, CMYK, and LAB update automatically. The conversion chain uses accurate mathematical formulas: RGB\u2192HSL through the standard min\/max algorithm, RGB\u2192CMYK through the ink coverage formula, and RGB\u2192LAB through the full sRGB\u2192XYZ\u2192CIE L*a*b* pipeline including the D65 illuminant white point and gamma correction. LAB is perceptually uniform \u2014 equal numerical distances correspond to equal perceived color differences \u2014 which makes it valuable for color difference calculations, gradient interpolation, and accessibility analysis beyond what RGB or HSL can express.<\/p>\n\n\n<figure class=\"pth-article-figure pth-img-left\" style=\"float:left; width:600px; max-width:100%; margin:4px 28px 16px 0; clear:left;\"><img decoding=\"async\" src=\"https:\/\/schoolict.net\/tools\/wp-content\/uploads\/2026\/06\/color-studio-pro-tool-preview-800x447.jpeg\" alt=\"Color Studio Pro showing 5 tabs with color converter panel WCAG contrast checker palette generator and CSS output for web developers\" width=\"600\" height=\"338\" loading=\"lazy\" data-no-lazy=\"1\" class=\"pth-article-img\" style=\"width:100%;height:auto;display:block;border-radius:10px;border:1px solid #e2e8f0;\"><\/figure>\n\n\n\n<h2 id=\"\ud83d\udfe1-wcag-2-1-contrast-ratios-the-mathematics-behind-pass-and-fail\" class=\"wp-block-heading\">\ud83d\udfe1&nbsp;<strong>WCAG 2.1 Contrast Ratios \u2014 The Mathematics Behind Pass and Fail<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The WCAG 2.1 contrast ratio formula is:&nbsp;<strong>(L1 + 0.05) \/ (L2 + 0.05)<\/strong>&nbsp;where L1 is the relative luminance of the lighter color and L2 is the relative luminance of the darker color. Relative luminance is calculated from linearised sRGB values using the formula:&nbsp;<strong>L = 0.2126R + 0.7152G + 0.0722B<\/strong>&nbsp;where each channel is first gamma-corrected: values \u2264 0.03928 divide by 12.92, and values above use the power function&nbsp;<code>(v + 0.055) \/ 1.055 ^ 2.4<\/code>. The 0.05 offset in the contrast formula prevents division by zero when comparing against pure black (luminance 0).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The WCAG 2.1 thresholds are:&nbsp;<strong>4.5:1<\/strong>&nbsp;for AA conformance on normal text (under 18pt regular or 14pt bold),&nbsp;<strong>3:1<\/strong>&nbsp;for AA conformance on large text (18pt+ regular or 14pt+ bold) and for UI component boundaries, and&nbsp;<strong>7:1<\/strong>&nbsp;for AAA conformance on normal text. A ratio of 1:1 means identical colors \u2014 zero contrast. Pure black on pure white achieves 21:1, the maximum possible ratio. The Contrast tab displays all three thresholds simultaneously so you can determine at a glance which level your color combination achieves and for what text sizes.<\/p>\n\n\n\n<h3 id=\"\ud83d\udfe2-how-the-auto-fix-suggestion-works\" class=\"wp-block-heading\">\ud83d\udfe2&nbsp;<strong>How the Auto-Fix Suggestion Works<\/strong><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When a color&#8217;s contrast against both white and black falls below the 4.5:1 AA threshold \u2014 which happens in the mid-luminance range around lightness values 35\u201365% \u2014 the tool compares the two ratios and suggests the higher one. This is rarely needed for highly saturated colors since deep blues, greens, and reds almost always pass with white text while pale yellows and light grays pass with black text. The problematic zone is medium saturation colors \u2014 muted greens, dusty oranges, medium grays \u2014 where neither extreme provides sufficient contrast. The fix suggestion shows the exact ratio achieved with the recommended pairing, letting you decide whether to switch text color or adjust the background color&#8217;s lightness in the HSL tab.<\/p>\n\n\n\n<h2 id=\"\ud83d\udfe1-color-harmony-systems-what-each-palette-type-means-for-design\" class=\"wp-block-heading\">\ud83d\udfe1&nbsp;<strong>Color Harmony Systems \u2014 What Each Palette Type Means for Design<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Color harmony theory describes relationships between colors on the hue wheel (0\u2013360\u00b0). Each harmony type produces a different visual dynamic.&nbsp;<strong>Complementary<\/strong>&nbsp;(180\u00b0 opposite) creates maximum contrast \u2014 blue and orange, red and green, purple and yellow. High visual tension, effective for call-to-action buttons against content backgrounds.&nbsp;<strong>Triadic<\/strong>&nbsp;(120\u00b0 apart) gives three evenly spaced colors with balanced contrast \u2014 primary, secondary, tertiary in equal visual weight. Common in sports team branding and children&#8217;s design.&nbsp;<strong>Analogous<\/strong>&nbsp;(adjacent \u00b130\u00b0) creates calm, cohesive palettes with low contrast between elements \u2014 used in nature-inspired design, gradients, and backgrounds where visual harmony matters more than contrast.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Split-Complementary<\/strong>&nbsp;is a safer version of complementary: instead of the exact opposite hue, it uses the two hues adjacent to the complement (\u00b130\u00b0 from the complement). It retains visual tension while being less jarring.&nbsp;<strong>Monochromatic<\/strong>&nbsp;uses the same hue at different lightness values \u2014 five variations at 20%, 35%, 50%, 65%, and 80% lightness. This produces the most cohesive possible palette and is the foundation of design systems like Tailwind CSS (which uses 50-900 numeric scales for each hue). The 10-step shade scale in the Palette tab maps directly to Tailwind&#8217;s scale structure \u2014 click Copy CSS Vars to get&nbsp;<code>--shade-50<\/code>&nbsp;through&nbsp;<code>--shade-900<\/code>&nbsp;as CSS custom properties.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\ud83d\udd35&nbsp;<strong>Click any palette swatch<\/strong>&nbsp;to load it as the active color \u2014 the entire tool (contrast, palette, CSS output) updates for that new color instantly.<\/li>\n\n\n\n<li>\ud83d\udfe0&nbsp;<strong>Color History sidebar<\/strong>&nbsp;automatically saves your last 12 colors \u2014 click any history swatch to restore a previous color without retyping.<\/li>\n\n\n\n<li>\ud83d\udfe3&nbsp;<strong>PTH Color System presets<\/strong>&nbsp;\u2014 the sidebar shows all 12 WCAG AA approved colors from the PTH v3.1 instruction set, each verified to pass 4.5:1 contrast on light backgrounds.<\/li>\n<\/ul>\n\n\n\n<h2 id=\"\ud83d\udfe1-image-color-picker-gradient-generator-and-css-output-formats\" class=\"wp-block-heading\">\ud83d\udfe1&nbsp;<strong>Image Color Picker, Gradient Generator, and CSS Output Formats<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Image Color Picker in the \ud83d\udee0\ufe0f Tools tab uses an HTML5 canvas element and the&nbsp;<code>getImageData()<\/code>&nbsp;API to read pixel values directly in the browser. Upload any JPEG, PNG, WebP, or GIF image \u2014 the image renders on a canvas with a crosshair cursor. Click any pixel to extract its exact RGB values, which convert to HEX automatically. The tool displays both the HEX code and RGB values with a live swatch. Use Color gives you the extracted color as the active color throughout the entire studio \u2014 contrast ratios, palette, and CSS output all update for the picked color. This is useful for brand color extraction, matching colors from screenshots, and identifying exact values from reference images without external tools.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Gradient Generator produces a&nbsp;<code>linear-gradient()<\/code>&nbsp;CSS rule with the angle, two color stops, and a&nbsp;<code>-webkit-<\/code>&nbsp;prefixed fallback for older Safari versions. The CSS Output tab generates four distinct output formats.&nbsp;<strong>CSS Properties<\/strong>&nbsp;gives a ready-to-paste&nbsp;<code>.element<\/code>&nbsp;block with background, text, border, outline, and box-shadow set to your color.&nbsp;<strong>CSS Variables<\/strong>&nbsp;generates a&nbsp;<code>:root<\/code>&nbsp;block with the base color, a 15%-darker variant, a 15%-lighter variant, the raw RGB channel values for use in&nbsp;<code>rgba()<\/code>&nbsp;expressions, HSL format, and two pre-built alpha variants at 30% and 10% opacity. The Design Tokens JSON follows the&nbsp;<a href=\"https:\/\/www.w3.org\/community\/design-tokens\/\" rel=\"noreferrer noopener\" target=\"_blank\">W3C Design Token Community Group<\/a>&nbsp;format, compatible with Figma&#8217;s Token Studio plugin and Style Dictionary. Tailwind Config exports a&nbsp;<code>module.exports<\/code>&nbsp;object with 50, 500, and 900 scale entries for your custom color. Use our&nbsp;Color Studio Pro&nbsp;to generate all four formats from any color without switching between tools.<\/p>\n\n\n\n<style>\n.pth-faq-section{margin-top:50px;margin-bottom:40px;font-family:inherit}\n.pth-faq-header{font-size:1.8rem;font-weight:800;color:#0f172a;margin-bottom:25px;border-bottom:2px solid #e2e8f0;padding-bottom:10px;display:flex;align-items:center;gap:10px}\n.pth-faq-grid{display:grid;grid-template-columns:100%;gap:20px}\n@media(min-width:768px){.pth-faq-grid{grid-template-columns:repeat(2,1fr)}}\n@media(min-width:1024px){.pth-faq-grid{grid-template-columns:repeat(3,1fr)}}\n.pth-faq-card{background:#f8fafc;padding:24px;border-radius:12px;border:1px solid #e2e8f0;transition:transform .2s ease;break-inside:avoid}\n.pth-faq-card:hover{transform:translateY(-3px);box-shadow:0 4px 12px rgba(0,0,0,.05)}\n.pth-faq-q{color:#0f172a;font-size:1rem;font-weight:700;margin:0 0 12px;line-height:1.4}\n.pth-faq-a{margin:0;font-size:.95rem;color:#1e293b;line-height:1.6;font-weight:500}\n<\/style>\n\n<div class=\"pth-faq-section\">\n    <div class=\"pth-faq-header\">\ud83e\udd14 Frequently Asked Questions<\/div>\n    <div class=\"pth-faq-grid\">\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">What is the difference between HSL and HSB color models?<\/p>\n            <p class=\"pth-faq-a\">Both use Hue (0\u2013360\u00b0) and Saturation (0\u2013100%), but differ in the third channel. HSL uses Lightness \u2014 at 0% lightness the color is black, at 100% it is white, and at 50% it is the purest hue. HSB (also called HSV) uses Brightness\/Value \u2014 at 0% brightness the color is always black, and at 100% brightness with 100% saturation you get the pure hue. At 100% brightness with 0% saturation you get white. CSS supports HSL natively; HSB is used in Photoshop, Illustrator, and most design tools.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">Why does the LAB value look different from what Photoshop shows?<\/p>\n            <p class=\"pth-faq-a\">LAB values depend on the reference white point used for the XYZ conversion. This tool uses the D65 illuminant (standard daylight, 6500K) which is the standard for web and digital color \u2014 the same reference point used by CSS Color Level 4 and browser implementations. Photoshop historically used D50 (5000K, print-optimised) for some profiles. Converted colors may differ slightly between D50 and D65 reference points. For web development work, D65 is the correct reference.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">How does the Tailwind color match work?<\/p>\n            <p class=\"pth-faq-a\">The tool calculates the Euclidean distance between your color&#8217;s RGB values and every color in the Tailwind CSS v3 palette \u2014 from <code>slate-50<\/code> to <code>rose-900<\/code>. The nearest match by perceptual RGB distance is returned. If the distance is under 30 RGB units, the exact class name is shown. If over 30, a tilde (~) indicates a close approximation. The match covers the primary color scale; exact matches exist for all Tailwind v3 colors since they&#8217;re hardcoded in the lookup table.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">Can I use the image picker on photographs to extract brand colors?<\/p>\n            <p class=\"pth-faq-a\">Yes. Upload a brand asset, logo screenshot, or product photo and click the dominant color area. The crosshair cursor appears as you hover and the exact pixel RGB values are extracted on click. For JPEGs, note that compression artifacts can slightly shift pixel colors \u2014 for precise brand color extraction, use PNG or WebP source files. The Use Color button loads the picked color throughout the entire studio so you can immediately check its WCAG contrast ratios and generate CSS variables.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">What is the Design Tokens JSON format compatible with?<\/p>\n            <p class=\"pth-faq-a\">The JSON output follows the W3C Design Token Community Group specification \u2014 the emerging standard for design token exchange between tools. It is compatible with Figma&#8217;s Token Studio plugin (import directly into your Figma file), Style Dictionary (Amazon&#8217;s design token compiler that outputs to CSS, SCSS, iOS, Android), and Theo (Salesforce&#8217;s token system). The token includes the hex value, type annotation, descriptive text, and structured RGB, HSL, and CMYK data for each channel.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">How accurate is the Color Blindness Simulator?<\/p>\n            <p class=\"pth-faq-a\">The simulation uses established RGB transformation matrices published in color science research for Deuteranopia, Protanopia, Tritanopia, and Deuteranomaly. These matrices are approximations \u2014 real color vision deficiency varies between individuals and is more complex than a linear transform captures. The simulator gives a reliable general indication of how your color appears to users with different types of color vision deficiency, but should not be treated as medically precise. Test critical UI decisions with real users whenever possible.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">What does the PTH Color Validator in the CSS Output tab check?<\/p>\n            <p class=\"pth-faq-a\">The PTH Color Validator checks your color against two standards: WCAG 2.1 AA conformance as text on white and black backgrounds, and membership in the PTH Instruction v3.1 approved color list. The approved list contains 12 specific hex values verified to pass 4.5:1 contrast on light backgrounds \u2014 colors like <code>#1d4ed8<\/code>, <code>#5b21b6<\/code>, <code>#047857<\/code>, and <code>#991b1b<\/code>. Colors outside this list can still be used as backgrounds or decorative elements \u2014 the validator specifically flags their suitability as text colors on light backgrounds.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">Can I save my color palettes for later?<\/p>\n            <p class=\"pth-faq-a\">The Color History sidebar stores your last 12 colors in browser session memory \u2014 they persist while the page is open but clear on refresh. For permanent storage, use the CSS Variables or Design Tokens JSON export to save your palette to a file. Copy the CSS Variables output and paste it into your project&#8217;s global stylesheet. The Design Tokens JSON can be committed to your repository and imported into Figma or your build pipeline for persistent team access.<\/p>\n        <\/div>\n\n        <div class=\"pth-faq-card\">\n            <p class=\"pth-faq-q\">Why does my CSS Custom Property show double the color in the Convert tab?<\/p>\n            <p class=\"pth-faq-a\">The CSS Variable field in the Convert tab outputs the full custom property declaration \u2014 <code>--color-primary: #2563EB;<\/code> \u2014 formatted for direct paste into a <code>:root<\/code> block. If you need just the hex value for use inside a <code>var()<\/code> call, copy from the HEX field instead. The full declaration format is intentional \u2014 it gives you a paste-ready line for your stylesheet without needing to add the property name and colon manually.<\/p>\n        <\/div>\n\n    <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>All-in-One Color Studio &amp; Color Format Converter (HEX, RGB, HSL, CMYK) Convert HEX, RGB, HSL, and CMYK color codes instantly with this free, 100% offline color format converter. Features live visual preview and one-click CSS copy. \ud83d\udfe2 7-Format Color Converter with Named Color Detection The \ud83d\udd04 Convert tab handles seven color formats simultaneously \u2014 HEX, &#8230; <a title=\"All-in-One Color Studio &amp; Color Format Converter (HEX, RGB, HSL, CMYK)\" class=\"read-more\" href=\"https:\/\/schoolict.net\/tools\/ultimate-color-format-converter\/\" aria-label=\"Read more about All-in-One Color Studio &amp; Color Format Converter (HEX, RGB, HSL, CMYK)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":732,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-720","page","type-page","status-publish","has-post-thumbnail"],"_links":{"self":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/720","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/comments?post=720"}],"version-history":[{"count":0,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/pages\/720\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media\/732"}],"wp:attachment":[{"href":"https:\/\/schoolict.net\/tools\/wp-json\/wp\/v2\/media?parent=720"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}