{"id":468,"date":"2026-10-15T05:47:18","date_gmt":"2026-10-15T05:47:18","guid":{"rendered":"https:\/\/ongroundmedia.com\/?page_id=468"},"modified":"2026-10-15T05:50:02","modified_gmt":"2026-10-15T05:50:02","slug":"color-converter","status":"publish","type":"page","link":"https:\/\/ongroundmedia.com\/?page_id=468","title":{"rendered":"Color Converter"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"468\" class=\"elementor elementor-468\">\n\t\t\t\t<div class=\"elementor-element elementor-element-9865082 e-con e-atomic-element e-flexbox-base e-default-div e-c10402b \" data-id=\"9865082\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"9865082\">\n    \t\t<div class=\"elementor-element elementor-element-d004464 elementor-widget elementor-widget-html\" data-id=\"d004464\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!doctype html><html><head><meta charset=utf8><meta name=viewport content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><style>:root{color-scheme:light;box-sizing:border-box;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}html{scroll-padding-top:env(safe-area-inset-top,0px)}body{margin:0;padding:0;font:14px -apple-system,BlinkMacSystemFont,sans-serif;background:#fff;color:#000}img{max-width:100%}[hidden]:not([hidden=until-found i]){display:none!important}<\/style><\/head><body>\r\n<title>Hue Bench<\/title>\r\n<meta name=\"claude:viewport-fit-sides\" content=\"cover\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\r\n<link rel=\"preconnect\" href=\"https:\/\/fonts.gstatic.com\" crossorigin>\r\n<link rel=\"stylesheet\" href=\"https:\/\/fonts.googleapis.com\/css2?family=Bricolage+Grotesque:opsz,wght@12..96,500..800&family=Instrument+Sans:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap\">\r\n<style>\r\n\/* Layout: a swatch-led bench. The user's color is the only chroma; the UI stays a cool, slightly green-grey neutral. Sections are open blocks divided by hairlines, not cards. *\/\r\n:root{\r\n  --bg:#ECEEEB;\r\n  --surface:#F7F8F6;\r\n  --ink:#151918;\r\n  --muted:#5A645F;\r\n  --line:#D5DAD6;\r\n  --line-strong:#B7C0BA;\r\n  --edge:rgba(21,25,24,.16);\r\n  --good:#1B7A4C;\r\n  --bad:#B03A2E;\r\n  --checker-a:#FFFFFF;\r\n  --checker-b:#D8DDD9;\r\n  --shadow:rgba(21,25,24,.28);\r\n  --cur:#FF6B35;\r\n  --f-display:'Bricolage Grotesque','Segoe UI',system-ui,sans-serif;\r\n  --f-body:'Instrument Sans','Segoe UI',system-ui,sans-serif;\r\n  --f-mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,Consolas,monospace;\r\n}\r\n@media (prefers-color-scheme: dark){\r\n  :root:not([data-theme=\"light\"]){\r\n    --bg:#111413;\r\n    --surface:#1A1E1C;\r\n    --ink:#ECEFEB;\r\n    --muted:#9AA39E;\r\n    --line:#2A302D;\r\n    --line-strong:#434B47;\r\n    --edge:rgba(236,239,235,.22);\r\n    --good:#5CC58E;\r\n    --bad:#F0806F;\r\n    --checker-a:#2A2F2C;\r\n    --checker-b:#3A403C;\r\n    --shadow:rgba(0,0,0,.6);\r\n    color-scheme:dark;\r\n  }\r\n}\r\n:root[data-theme=\"dark\"]{\r\n  --bg:#111413;\r\n  --surface:#1A1E1C;\r\n  --ink:#ECEFEB;\r\n  --muted:#9AA39E;\r\n  --line:#2A302D;\r\n  --line-strong:#434B47;\r\n  --edge:rgba(236,239,235,.22);\r\n  --good:#5CC58E;\r\n  --bad:#F0806F;\r\n  --checker-a:#2A2F2C;\r\n  --checker-b:#3A403C;\r\n  --shadow:rgba(0,0,0,.6);\r\n  color-scheme:dark;\r\n}\r\n\r\n*{box-sizing:border-box}\r\nhtml{-webkit-text-size-adjust:100%}\r\nbody{\r\n  margin:0;background:var(--bg);color:var(--ink);\r\n  font-family:var(--f-body);font-size:15px;line-height:1.5;\r\n  padding-block:20px 56px;\r\n  padding-left:max(16px,env(safe-area-inset-left,0px));\r\n  padding-right:max(16px,env(safe-area-inset-right,0px));\r\n}\r\n.wrap{max-width:1120px;margin:0 auto;display:flex;flex-direction:column;gap:44px}\r\nbutton,input,select,textarea{font:inherit;color:inherit}\r\n:focus-visible{outline:2px solid var(--ink);outline-offset:2px}\r\n\r\n\/* header *\/\r\n.top{display:flex;align-items:center;justify-content:space-between;gap:16px}\r\n.brand{display:flex;align-items:center;gap:12px;min-width:0}\r\n.dot-cur{width:16px;height:16px;border-radius:50%;background:var(--cur);box-shadow:inset 0 0 0 1px var(--edge);flex:none}\r\nh1{font-family:var(--f-display);font-weight:700;font-size:28px;letter-spacing:-.02em;line-height:1.1;margin:0}\r\n.tag{font-family:var(--f-mono);font-size:12px;color:var(--muted);letter-spacing:.03em;margin-top:2px}\r\n\r\n.btn{\r\n  display:inline-flex;align-items:center;gap:8px;min-height:40px;padding:8px 14px;\r\n  border-radius:999px;border:1px solid var(--line-strong);background:var(--surface);\r\n  font-size:13.5px;font-weight:500;cursor:pointer;white-space:nowrap;\r\n}\r\n.btn:hover{border-color:var(--ink)}\r\n.btn svg{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}\r\n.btn.primary{background:var(--ink);color:var(--bg);border-color:var(--ink)}\r\n.btn.icon{padding:0;width:40px;justify-content:center}\r\n.btn.small{min-height:34px;padding:6px 12px;font-size:12.5px}\r\n\r\n\/* bench *\/\r\n.bench{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:32px}\r\n.left{display:flex;flex-direction:column;gap:12px;min-width:0}\r\n.swatch{\r\n  position:relative;flex:1;min-height:360px;border-radius:24px;overflow:hidden;isolation:isolate;\r\n  background:conic-gradient(var(--checker-b) 25%,var(--checker-a) 0 50%,var(--checker-b) 0 75%,var(--checker-a) 0) 0 0\/22px 22px;\r\n  --sw-ink:#fff;\r\n}\r\n.swatch-color{position:absolute;inset:0;transition:background .12s}\r\n.swatch::after{content:\"\";position:absolute;inset:0;border-radius:inherit;box-shadow:inset 0 0 0 1px var(--edge);pointer-events:none}\r\n.sw-meta{position:absolute;inset:0;padding:24px;display:flex;flex-direction:column;justify-content:space-between;color:var(--sw-ink);min-width:0}\r\n.sw-kind{font-family:var(--f-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;opacity:.78}\r\n.sw-name{font-family:var(--f-display);font-weight:700;font-size:clamp(30px,5vw,42px);letter-spacing:-.025em;line-height:1.04;text-wrap:balance;margin-top:6px}\r\n.sw-bottom{display:flex;justify-content:space-between;align-items:flex-end;gap:16px;flex-wrap:wrap;font-family:var(--f-mono);font-size:13px}\r\n.sw-hex{font-size:20px;font-weight:500;letter-spacing:.01em}\r\n.sw-sub{opacity:.82;overflow-wrap:anywhere}\r\n.toolbar{display:flex;flex-wrap:wrap;gap:8px}\r\n.picker{padding-left:10px}\r\n.picker input{\r\n  -webkit-appearance:none;appearance:none;width:22px;height:22px;padding:0;border:0;background:none;cursor:pointer;\r\n}\r\n.picker input::-webkit-color-swatch-wrapper{padding:0}\r\n.picker input::-webkit-color-swatch{border:1px solid var(--edge);border-radius:50%}\r\n.picker input::-moz-color-swatch{border:1px solid var(--edge);border-radius:50%}\r\n\r\n.convert{display:flex;flex-direction:column;gap:14px;min-width:0}\r\n.field{display:flex;flex-direction:column;gap:8px}\r\n.field label,.cap{font-family:var(--f-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}\r\n.field input[type=text]{\r\n  width:100%;font-family:var(--f-mono);font-size:16px;padding:14px 16px;border-radius:14px;\r\n  border:1.5px solid var(--line-strong);background:var(--surface);\r\n}\r\n.hint{font-size:12.5px;color:var(--muted);min-height:1.5em;margin:0}\r\n.hint.err{color:var(--bad)}\r\n.opts{display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center}\r\n.opt{display:flex;align-items:center;gap:10px;font-size:12.5px;color:var(--muted)}\r\n.seg{display:inline-flex;border:1px solid var(--line-strong);border-radius:999px;padding:2px;background:var(--surface)}\r\n.seg button{border:0;border-radius:999px;background:none;color:var(--muted);padding:5px 12px;font-size:12.5px;cursor:pointer}\r\n.seg button[aria-pressed=\"true\"]{background:var(--ink);color:var(--bg)}\r\n.outs{display:flex;flex-direction:column;border-top:1px solid var(--line)}\r\n.out{\r\n  appearance:none;-webkit-appearance:none;background:none;border:0;border-bottom:1px solid var(--line);\r\n  width:100%;text-align:left;cursor:pointer;\r\n  display:grid;grid-template-columns:96px minmax(0,1fr) 22px;gap:12px;align-items:center;padding:11px 6px;\r\n}\r\n.out:hover{background:var(--surface)}\r\n.out-k{font-family:var(--f-mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}\r\n.out-v{font-family:var(--f-mono);font-size:14px;overflow-wrap:anywhere}\r\n.out svg{width:16px;height:16px;stroke:var(--muted);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}\r\n.out.done svg{stroke:var(--good)}\r\n\r\n\/* sections *\/\r\n.pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px}\r\n.blk{border-top:1px solid var(--line-strong);padding-top:18px;display:flex;flex-direction:column;gap:16px;min-width:0}\r\n.blk-h{display:flex;align-items:baseline;justify-content:space-between;gap:8px 16px;flex-wrap:wrap}\r\nh2{font-family:var(--f-display);font-weight:700;font-size:20px;letter-spacing:-.01em;line-height:1.2;margin:0}\r\n.blk-h p{margin:0;font-size:13px;color:var(--muted)}\r\n.blk-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}\r\n\r\n\/* sliders *\/\r\n.sliders{display:flex;flex-direction:column;gap:12px}\r\n.grp{font-family:var(--f-mono);font-size:11px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin-top:6px}\r\n.grp:first-child{margin-top:0}\r\n.sl{display:grid;grid-template-columns:16px minmax(0,1fr) 64px;gap:14px;align-items:center}\r\n.sl label{font-family:var(--f-mono);font-size:12px;color:var(--muted)}\r\n.sl input[type=number]{\r\n  width:100%;padding:6px 8px;border-radius:8px;border:1px solid var(--line-strong);background:var(--surface);\r\n  font-family:var(--f-mono);font-size:13px;text-align:right;font-variant-numeric:tabular-nums;-moz-appearance:textfield;\r\n}\r\n.sl input[type=number]::-webkit-inner-spin-button,.sl input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}\r\ninput[type=range]{\r\n  -webkit-appearance:none;appearance:none;width:100%;height:12px;margin:0;border-radius:999px;\r\n  background:var(--line);box-shadow:inset 0 0 0 1px var(--edge);cursor:pointer;\r\n}\r\ninput[type=range]::-webkit-slider-runnable-track{background:transparent;height:12px}\r\ninput[type=range]::-moz-range-track{background:transparent;height:12px}\r\ninput[type=range]::-webkit-slider-thumb{\r\n  -webkit-appearance:none;width:22px;height:22px;margin-top:-5px;border-radius:50%;\r\n  background:var(--surface);border:2.5px solid var(--ink);box-shadow:0 1px 4px var(--shadow);\r\n}\r\ninput[type=range]::-moz-range-thumb{\r\n  width:17px;height:17px;border-radius:50%;background:var(--surface);border:2.5px solid var(--ink);box-shadow:0 1px 4px var(--shadow);\r\n}\r\n\r\n\/* contrast *\/\r\n.ct-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}\r\n.ct{border-radius:16px;padding:14px;display:flex;flex-direction:column;gap:10px;min-width:0;box-shadow:inset 0 0 0 1px var(--edge)}\r\n.ct-l{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;opacity:.85}\r\n.ct-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px}\r\n.ct-aa{font-family:var(--f-display);font-weight:700;font-size:42px;line-height:1;letter-spacing:-.02em}\r\n.ct-ratio{font-family:var(--f-mono);font-size:13px;font-variant-numeric:tabular-nums}\r\n.pills{display:flex;flex-wrap:wrap;gap:5px}\r\n.pill{font-family:var(--f-mono);font-size:10.5px;padding:2px 7px;border-radius:999px;border:1px solid currentColor;white-space:nowrap}\r\n.pill.fail{opacity:.55;text-decoration:line-through}\r\n.ct-best{margin:0;font-size:13px;color:var(--muted)}\r\n.ct-best strong{color:var(--ink);font-weight:600}\r\n\r\n\/* scale *\/\r\n.scale{display:grid;grid-template-columns:repeat(auto-fit,minmax(68px,1fr));gap:8px}\r\n.step{appearance:none;-webkit-appearance:none;border:0;background:none;padding:0;cursor:pointer;text-align:left;display:flex;flex-direction:column;gap:5px;min-width:0}\r\n.step-c{height:76px;border-radius:12px;box-shadow:inset 0 0 0 1px var(--edge);position:relative}\r\n.step-c .pin{position:absolute;left:10px;bottom:10px;width:7px;height:7px;border-radius:50%;display:none}\r\n.step.base .pin{display:block}\r\n.step-n{font-family:var(--f-mono);font-size:11px;color:var(--muted)}\r\n.step-h{font-family:var(--f-mono);font-size:11px}\r\n.prefix{display:flex;align-items:center;gap:8px;font-family:var(--f-mono);font-size:12px;color:var(--muted)}\r\n.prefix input{width:110px;padding:6px 10px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface);font-family:var(--f-mono);font-size:12.5px}\r\n\r\n\/* harmonies *\/\r\n.harm{display:grid;grid-template-columns:170px minmax(0,1fr);gap:12px;align-items:center;padding:10px 0;border-bottom:1px solid var(--line)}\r\n.harm:first-of-type{border-top:1px solid var(--line)}\r\n.harm-n{font-size:14px;font-weight:500}\r\n.harm-n small{display:block;font-family:var(--f-mono);font-size:11px;color:var(--muted);font-weight:400}\r\n.chips{display:flex;gap:10px;flex-wrap:wrap}\r\n.chip{appearance:none;-webkit-appearance:none;border:0;background:none;padding:0;cursor:pointer;display:flex;flex-direction:column;gap:4px;align-items:flex-start}\r\n.chip-c{width:84px;height:50px;border-radius:10px;box-shadow:inset 0 0 0 1px var(--edge)}\r\n.chip.base .chip-c{box-shadow:inset 0 0 0 1px var(--edge),0 0 0 2px var(--bg),0 0 0 3.5px var(--ink)}\r\n.chip-h{font-family:var(--f-mono);font-size:11px;color:var(--muted)}\r\n\r\n\/* palette *\/\r\n.pal{display:flex;flex-wrap:wrap;gap:14px}\r\n.pal-item{position:relative;display:flex;flex-direction:column;gap:4px}\r\n.pal-sw{appearance:none;-webkit-appearance:none;border:0;padding:0;cursor:pointer;width:92px;height:62px;border-radius:12px;box-shadow:inset 0 0 0 1px var(--edge)}\r\n.pal-x{\r\n  position:absolute;top:-7px;right:-7px;width:24px;height:24px;border-radius:50%;border:2px solid var(--bg);\r\n  background:var(--ink);color:var(--bg);display:grid;place-items:center;cursor:pointer;padding:0;\r\n}\r\n.pal-x svg{width:11px;height:11px;stroke:currentColor;fill:none;stroke-width:2.4;stroke-linecap:round}\r\n.pal-h{font-family:var(--f-mono);font-size:11px;color:var(--muted)}\r\n.pal-empty{margin:0;color:var(--muted);font-size:13.5px}\r\n\r\n\/* bulk *\/\r\n.bulk{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.25fr);gap:24px}\r\n.bulk-in-wrap{display:flex;flex-direction:column;gap:10px;min-width:0}\r\ntextarea{\r\n  width:100%;min-height:190px;resize:vertical;font-family:var(--f-mono);font-size:13px;line-height:1.7;\r\n  padding:12px 14px;border-radius:14px;border:1.5px solid var(--line-strong);background:var(--surface);\r\n}\r\nselect{\r\n  font-size:13px;padding:7px 12px;border-radius:999px;border:1px solid var(--line-strong);background:var(--surface);\r\n}\r\n.bulk-out-wrap{display:flex;flex-direction:column;min-width:0;border-top:1px solid var(--line)}\r\n.bulk-row{display:grid;grid-template-columns:18px minmax(0,1fr) minmax(0,1.1fr);gap:12px;align-items:center;padding:8px 2px;border-bottom:1px solid var(--line);font-family:var(--f-mono);font-size:12.5px}\r\n.bulk-row .dot{width:18px;height:18px;border-radius:50%;box-shadow:inset 0 0 0 1px var(--edge)}\r\n.bulk-row .bi{color:var(--muted);overflow-wrap:anywhere}\r\n.bulk-row .bo{overflow-wrap:anywhere}\r\n.bulk-row .bo.bad{color:var(--bad)}\r\n\r\n.foot{font-size:12.5px;color:var(--muted);margin:0}\r\n\r\n.toast{\r\n  position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom,0px));transform:translate(-50%,14px);\r\n  background:var(--ink);color:var(--bg);padding:10px 16px;border-radius:999px;font-family:var(--f-mono);font-size:12.5px;\r\n  opacity:0;pointer-events:none;transition:opacity .18s,transform .18s;max-width:calc(100% - 32px);text-align:center;z-index:10;\r\n}\r\n.toast.on{opacity:1;transform:translate(-50%,0)}\r\n\r\n@media (max-width:860px){\r\n  .bench,.pair,.bulk{grid-template-columns:minmax(0,1fr)}\r\n  .bench{gap:24px}\r\n  .pair{gap:44px}\r\n  .swatch{min-height:260px}\r\n}\r\n@media (max-width:620px){\r\n  .harm{grid-template-columns:minmax(0,1fr);gap:8px}\r\n  h1{font-size:24px}\r\n  .out{grid-template-columns:82px minmax(0,1fr) 20px;gap:8px}\r\n}\r\n@media (prefers-reduced-motion:reduce){\r\n  *{transition:none!important}\r\n}\r\n<\/style>\r\n\r\n<div class=\"wrap\">\r\n  <header class=\"top\">\r\n    <div class=\"brand\">\r\n      <span class=\"dot-cur\" aria-hidden=\"true\"><\/span>\r\n      <div>\r\n        <h1>Hue Bench<\/h1>\r\n        <div class=\"tag\">HEX \u00b7 RGB \u00b7 HSL color converter<\/div>\r\n      <\/div>\r\n    <\/div>\r\n    <button class=\"btn icon\" id=\"themeBtn\" type=\"button\" aria-label=\"Switch light or dark theme\" title=\"Switch theme\">\r\n      <svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"8.5\"\/><path d=\"M12 3.5a8.5 8.5 0 0 1 0 17z\" fill=\"currentColor\"\/><\/svg>\r\n    <\/button>\r\n  <\/header>\r\n\r\n  <main class=\"wrap\" style=\"gap:44px;padding:0\">\r\n    <section class=\"bench\" aria-label=\"Converter\">\r\n      <div class=\"left\">\r\n        <div class=\"swatch\" id=\"swatch\">\r\n          <div class=\"swatch-color\" id=\"swC\"><\/div>\r\n          <div class=\"sw-meta\">\r\n            <div>\r\n              <div class=\"sw-kind\" id=\"swKind\">Closest CSS name<\/div>\r\n              <div class=\"sw-name\" id=\"swName\">Tomato<\/div>\r\n            <\/div>\r\n            <div class=\"sw-bottom\">\r\n              <span class=\"sw-hex\" id=\"swHex\">#FF6B35<\/span>\r\n              <span class=\"sw-sub\" id=\"swSub\">hsl(16, 100%, 60%)<\/span>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n        <div class=\"toolbar\">\r\n          <button class=\"btn\" id=\"randBtn\" type=\"button\">\r\n            <svg viewBox=\"0 0 24 24\"><path d=\"M16 3h5v5M4 20 21 3M21 16v5h-5M15 15l6 6M4 4l5 5\"\/><\/svg>Random\r\n          <\/button>\r\n          <label class=\"btn picker\" title=\"Open color picker\">\r\n            <input type=\"color\" id=\"picker\" aria-label=\"Color picker\" value=\"#ff6b35\"><span>Picker<\/span>\r\n          <\/label>\r\n          <button class=\"btn\" id=\"dropBtn\" type=\"button\" hidden>\r\n            <svg viewBox=\"0 0 24 24\"><path d=\"M14 4.5l5.5 5.5M12.5 6l5.5 5.5-7 7H6.5v-4.5zM5 19l1.5-1.5\"\/><\/svg>Eyedropper\r\n          <\/button>\r\n          <button class=\"btn primary\" id=\"saveBtn\" type=\"button\">\r\n            <svg viewBox=\"0 0 24 24\"><path d=\"M12 5v14M5 12h14\"\/><\/svg>Save to palette\r\n          <\/button>\r\n        <\/div>\r\n      <\/div>\r\n\r\n      <div class=\"convert\">\r\n        <div class=\"field\">\r\n          <label for=\"colorInput\">Color<\/label>\r\n          <input type=\"text\" id=\"colorInput\" value=\"#FF6B35\" spellcheck=\"false\" autocomplete=\"off\" autocapitalize=\"off\" placeholder=\"#FF6B35, rgb(255 107 53), hsl(16 100% 60%), tomato\">\r\n          <p class=\"hint\" id=\"hint\" role=\"status\"><\/p>\r\n        <\/div>\r\n        <div class=\"opts\">\r\n          <div class=\"opt\">Syntax\r\n            <div class=\"seg\" role=\"group\" aria-label=\"Color syntax\" id=\"segSyntax\">\r\n              <button type=\"button\" data-v=\"classic\" aria-pressed=\"true\">Classic<\/button>\r\n              <button type=\"button\" data-v=\"modern\" aria-pressed=\"false\">Modern<\/button>\r\n            <\/div>\r\n          <\/div>\r\n          <div class=\"opt\">HEX\r\n            <div class=\"seg\" role=\"group\" aria-label=\"HEX letter case\" id=\"segCase\">\r\n              <button type=\"button\" data-v=\"upper\" aria-pressed=\"true\">ABC<\/button>\r\n              <button type=\"button\" data-v=\"lower\" aria-pressed=\"false\">abc<\/button>\r\n            <\/div>\r\n          <\/div>\r\n        <\/div>\r\n        <div class=\"outs\" id=\"outs\"><\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <div class=\"pair\">\r\n      <section class=\"blk\" aria-labelledby=\"h-adjust\">\r\n        <div class=\"blk-h\"><h2 id=\"h-adjust\">Adjust<\/h2><p>Drag any channel. The others follow.<\/p><\/div>\r\n        <div class=\"sliders\" id=\"sliders\"><\/div>\r\n      <\/section>\r\n\r\n      <section class=\"blk\" aria-labelledby=\"h-contrast\">\r\n        <div class=\"blk-h\"><h2 id=\"h-contrast\">Contrast<\/h2><p>WCAG ratios, both directions.<\/p><\/div>\r\n        <div class=\"ct-grid\" id=\"ctGrid\"><\/div>\r\n        <p class=\"ct-best\" id=\"ctBest\"><\/p>\r\n      <\/section>\r\n    <\/div>\r\n\r\n    <section class=\"blk\" aria-labelledby=\"h-scale\">\r\n      <div class=\"blk-h\">\r\n        <div>\r\n          <h2 id=\"h-scale\">Shades and tints<\/h2>\r\n          <p>Eleven steps around your color. Tap a step to copy its HEX.<\/p>\r\n        <\/div>\r\n        <div class=\"blk-actions\">\r\n          <label class=\"prefix\">Prefix <input type=\"text\" id=\"prefix\" value=\"brand\" maxlength=\"24\" spellcheck=\"false\" autocomplete=\"off\" aria-label=\"CSS variable prefix\"><\/label>\r\n          <button class=\"btn small\" id=\"copyScale\" type=\"button\">Copy as CSS variables<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"scale\" id=\"scale\"><\/div>\r\n    <\/section>\r\n\r\n    <section class=\"blk\" aria-labelledby=\"h-harm\">\r\n      <div class=\"blk-h\"><h2 id=\"h-harm\">Harmonies<\/h2><p>Hues rotated around the HSL wheel. Tap one to make it the base.<\/p><\/div>\r\n      <div id=\"harms\"><\/div>\r\n    <\/section>\r\n\r\n    <section class=\"blk\" aria-labelledby=\"h-pal\">\r\n      <div class=\"blk-h\">\r\n        <div>\r\n          <h2 id=\"h-pal\">Palette<\/h2>\r\n          <p id=\"palNote\">Sample colors shown until you save your own.<\/p>\r\n        <\/div>\r\n        <div class=\"blk-actions\">\r\n          <button class=\"btn small\" id=\"palCss\" type=\"button\">Copy CSS<\/button>\r\n          <button class=\"btn small\" id=\"palList\" type=\"button\">Copy list<\/button>\r\n          <button class=\"btn small\" id=\"palClear\" type=\"button\">Clear<\/button>\r\n        <\/div>\r\n      <\/div>\r\n      <div class=\"pal\" id=\"pal\"><\/div>\r\n    <\/section>\r\n\r\n    <section class=\"blk\" aria-labelledby=\"h-bulk\">\r\n      <div class=\"blk-h\"><h2 id=\"h-bulk\">Bulk convert<\/h2><p>One color per line, any format.<\/p><\/div>\r\n      <div class=\"bulk\">\r\n        <div class=\"bulk-in-wrap\">\r\n          <label class=\"cap\" for=\"bulkIn\">Input<\/label>\r\n          <textarea id=\"bulkIn\" spellcheck=\"false\" aria-label=\"Colors to convert, one per line\">#FF6B35\r\nrgb(27 42 65)\r\nhsl(48 87% 67%)\r\n14, 173, 105\r\nrebeccapurple\r\n#EFEFE9CC<\/textarea>\r\n          <div class=\"opt\">Convert to\r\n            <select id=\"bulkTo\" aria-label=\"Output format\">\r\n              <option value=\"hex\">HEX<\/option>\r\n              <option value=\"rgb\">RGB<\/option>\r\n              <option value=\"hsl\">HSL<\/option>\r\n              <option value=\"tok\">HSL tokens<\/option>\r\n            <\/select>\r\n          <\/div>\r\n        <\/div>\r\n        <div>\r\n          <div class=\"blk-actions\" style=\"justify-content:space-between;margin-bottom:10px\">\r\n            <span class=\"cap\">Result<\/span>\r\n            <button class=\"btn small\" id=\"bulkCopy\" type=\"button\">Copy all<\/button>\r\n          <\/div>\r\n          <div class=\"bulk-out-wrap\" id=\"bulkOut\"><\/div>\r\n        <\/div>\r\n      <\/div>\r\n    <\/section>\r\n\r\n    <p class=\"foot\">Conversions run in sRGB. HSL values are rounded to whole numbers, so a round trip can shift a channel by one. Contrast ratios ignore opacity.<\/p>\r\n  <\/main>\r\n<\/div>\r\n<div class=\"toast\" id=\"toast\" role=\"status\" aria-live=\"polite\"><\/div>\r\n\r\n<script>\r\n(function(){\r\n'use strict';\r\nvar $=function(s,r){return (r||document).querySelector(s)};\r\nvar clamp=function(v,a,b){return Math.min(b,Math.max(a,v))};\r\nvar root=document.documentElement;\r\n\r\n\/* ---------- CSS named colors ---------- *\/\r\nvar NAMES=\"AliceBlue:f0f8ff,AntiqueWhite:faebd7,Aqua:00ffff,Aquamarine:7fffd4,Azure:f0ffff,Beige:f5f5dc,Bisque:ffe4c4,Black:000000,BlanchedAlmond:ffebcd,Blue:0000ff,BlueViolet:8a2be2,Brown:a52a2a,BurlyWood:deb887,CadetBlue:5f9ea0,Chartreuse:7fff00,Chocolate:d2691e,Coral:ff7f50,CornflowerBlue:6495ed,Cornsilk:fff8dc,Crimson:dc143c,Cyan:00ffff,DarkBlue:00008b,DarkCyan:008b8b,DarkGoldenRod:b8860b,DarkGray:a9a9a9,DarkGreen:006400,DarkKhaki:bdb76b,DarkMagenta:8b008b,DarkOliveGreen:556b2f,DarkOrange:ff8c00,DarkOrchid:9932cc,DarkRed:8b0000,DarkSalmon:e9967a,DarkSeaGreen:8fbc8f,DarkSlateBlue:483d8b,DarkSlateGray:2f4f4f,DarkTurquoise:00ced1,DarkViolet:9400d3,DeepPink:ff1493,DeepSkyBlue:00bfff,DimGray:696969,DodgerBlue:1e90ff,FireBrick:b22222,FloralWhite:fffaf0,ForestGreen:228b22,Fuchsia:ff00ff,Gainsboro:dcdcdc,GhostWhite:f8f8ff,Gold:ffd700,GoldenRod:daa520,Gray:808080,Green:008000,GreenYellow:adff2f,HoneyDew:f0fff0,HotPink:ff69b4,IndianRed:cd5c5c,Indigo:4b0082,Ivory:fffff0,Khaki:f0e68c,Lavender:e6e6fa,LavenderBlush:fff0f5,LawnGreen:7cfc00,LemonChiffon:fffacd,LightBlue:add8e6,LightCoral:f08080,LightCyan:e0ffff,LightGoldenRodYellow:fafad2,LightGray:d3d3d3,LightGreen:90ee90,LightPink:ffb6c1,LightSalmon:ffa07a,LightSeaGreen:20b2aa,LightSkyBlue:87cefa,LightSlateGray:778899,LightSteelBlue:b0c4de,LightYellow:ffffe0,Lime:00ff00,LimeGreen:32cd32,Linen:faf0e6,Magenta:ff00ff,Maroon:800000,MediumAquaMarine:66cdaa,MediumBlue:0000cd,MediumOrchid:ba55d3,MediumPurple:9370db,MediumSeaGreen:3cb371,MediumSlateBlue:7b68ee,MediumSpringGreen:00fa9a,MediumTurquoise:48d1cc,MediumVioletRed:c71585,MidnightBlue:191970,MintCream:f5fffa,MistyRose:ffe4e1,Moccasin:ffe4b5,NavajoWhite:ffdead,Navy:000080,OldLace:fdf5e6,Olive:808000,OliveDrab:6b8e23,Orange:ffa500,OrangeRed:ff4500,Orchid:da70d6,PaleGoldenRod:eee8aa,PaleGreen:98fb98,PaleTurquoise:afeeee,PaleVioletRed:db7093,PapayaWhip:ffefd5,PeachPuff:ffdab9,Peru:cd853f,Pink:ffc0cb,Plum:dda0dd,PowderBlue:b0e0e6,Purple:800080,RebeccaPurple:663399,Red:ff0000,RosyBrown:bc8f8f,RoyalBlue:4169e1,SaddleBrown:8b4513,Salmon:fa8072,SandyBrown:f4a460,SeaGreen:2e8b57,SeaShell:fff5ee,Sienna:a0522d,Silver:c0c0c0,SkyBlue:87ceeb,SlateBlue:6a5acd,SlateGray:708090,Snow:fffafa,SpringGreen:00ff7f,SteelBlue:4682b4,Tan:d2b48c,Teal:008080,Thistle:d8bfd8,Tomato:ff6347,Turquoise:40e0d0,Violet:ee82ee,Wheat:f5deb3,White:ffffff,WhiteSmoke:f5f5f5,Yellow:ffff00,YellowGreen:9acd32\";\r\nvar NAMED={},NLIST=[];\r\nNAMES.split(',').forEach(function(p){\r\n  var a=p.split(':'),h=a[1];\r\n  NAMED[a[0].toLowerCase()]=h;\r\n  NLIST.push({n:a[0],r:parseInt(h.slice(0,2),16),g:parseInt(h.slice(2,4),16),b:parseInt(h.slice(4,6),16)});\r\n});\r\nfunction pretty(n){return n.replace(\/([a-z])([A-Z])\/g,'$1 $2')}\r\nfunction nearest(r,g,b){\r\n  var best=null,bd=1e12;\r\n  for(var i=0;i<NLIST.length;i++){\r\n    var c=NLIST[i],rm=(r+c.r)\/2,dr=r-c.r,dg=g-c.g,db=b-c.b;\r\n    var d=(2+rm\/256)*dr*dr+4*dg*dg+(2+(255-rm)\/256)*db*db;\r\n    if(d<=bd){bd=d;best=c}\r\n  }\r\n  return {name:best.n,exact:bd===0};\r\n}\r\n\r\n\/* ---------- conversion math ---------- *\/\r\nfunction rgbToHsl(r,g,b){\r\n  r\/=255;g\/=255;b\/=255;\r\n  var mx=Math.max(r,g,b),mn=Math.min(r,g,b),d=mx-mn,l=(mx+mn)\/2,h=0,s=0;\r\n  if(d){\r\n    s=d\/(1-Math.abs(2*l-1));\r\n    if(mx===r)h=((g-b)\/d)%6;else if(mx===g)h=(b-r)\/d+2;else h=(r-g)\/d+4;\r\n    h*=60;if(h<0)h+=360;\r\n  }\r\n  return [h,s*100,l*100];\r\n}\r\nfunction hslToRgb(h,s,l){\r\n  s\/=100;l\/=100;\r\n  var a=s*Math.min(l,1-l);\r\n  function f(n){var k=(n+h\/30)%12;return l-a*Math.max(-1,Math.min(k-3,Math.min(9-k,1)))}\r\n  return [f(0)*255,f(8)*255,f(4)*255];\r\n}\r\nfunction lin(v){v\/=255;return v<=0.03928?v\/12.92:Math.pow((v+0.055)\/1.055,2.4)}\r\nfunction lum(r,g,b){return 0.2126*lin(r)+0.7152*lin(g)+0.0722*lin(b)}\r\nfunction ratio(a,b){var x=Math.max(a,b),y=Math.min(a,b);return (x+0.05)\/(y+0.05)}\r\n\r\n\/* ---------- parsing ---------- *\/\r\nfunction pAlpha(v){\r\n  if(v===undefined||v===null||v==='')return 1;\r\n  var n=String(v).slice(-1)==='%'?parseFloat(v)\/100:parseFloat(v);\r\n  return isFinite(n)?clamp(n,0,1):1;\r\n}\r\nfunction pChan(v){\r\n  var n=String(v).slice(-1)==='%'?parseFloat(v)*2.55:parseFloat(v);\r\n  return clamp(Math.round(n),0,255);\r\n}\r\nfunction parseColor(raw){\r\n  var s=String(raw).trim().toLowerCase().replace(\/grey\/g,'gray'),m;\r\n  if(!s)return null;\r\n  if(s==='transparent')return {r:0,g:0,b:0,a:0};\r\n  if(NAMED[s]){var h0=NAMED[s];return {r:parseInt(h0.slice(0,2),16),g:parseInt(h0.slice(2,4),16),b:parseInt(h0.slice(4,6),16),a:1}}\r\n  m=s.match(\/^#?([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$\/);\r\n  if(m){\r\n    var h=m[1];\r\n    if(h.length<=4)h=h.split('').map(function(c){return c+c}).join('');\r\n    return {r:parseInt(h.slice(0,2),16),g:parseInt(h.slice(2,4),16),b:parseInt(h.slice(4,6),16),a:h.length===8?Math.round(parseInt(h.slice(6,8),16)\/255*100)\/100:1};\r\n  }\r\n  m=s.match(\/^rgba?\\(\\s*([\\d.]+%?)\\s*[,\\s]\\s*([\\d.]+%?)\\s*[,\\s]\\s*([\\d.]+%?)\\s*(?:[,\\\/]\\s*([\\d.]+%?)\\s*)?\\)$\/);\r\n  if(m)return {r:pChan(m[1]),g:pChan(m[2]),b:pChan(m[3]),a:pAlpha(m[4])};\r\n  m=s.match(\/^hsla?\\(\\s*(-?[\\d.]+)(?:deg)?\\s*[,\\s]\\s*([\\d.]+)%?\\s*[,\\s]\\s*([\\d.]+)%?\\s*(?:[,\\\/]\\s*([\\d.]+%?)\\s*)?\\)$\/);\r\n  if(!m)m=s.match(\/^(-?[\\d.]+)(?:deg)?[,\\s]+([\\d.]+)%[,\\s]+([\\d.]+)%(?:\\s*\\\/\\s*([\\d.]+%?))?$\/);\r\n  if(m)return hslParsed(parseFloat(m[1]),parseFloat(m[2]),parseFloat(m[3]),pAlpha(m[4]));\r\n  m=s.match(\/^(\\d{1,3}(?:\\.\\d+)?)[,\\s]+(\\d{1,3}(?:\\.\\d+)?)[,\\s]+(\\d{1,3}(?:\\.\\d+)?)$\/);\r\n  if(m){\r\n    var a=[+m[1],+m[2],+m[3]];\r\n    if(a.some(function(v){return v>255}))return null;\r\n    return {r:Math.round(a[0]),g:Math.round(a[1]),b:Math.round(a[2]),a:1};\r\n  }\r\n  return null;\r\n}\r\nfunction hslParsed(h,s,l,a){\r\n  if(!isFinite(h)||!isFinite(s)||!isFinite(l))return null;\r\n  h=((h%360)+360)%360;s=clamp(s,0,100);l=clamp(l,0,100);\r\n  var rgb=hslToRgb(h,s,l).map(Math.round);\r\n  return {r:rgb[0],g:rgb[1],b:rgb[2],a:a,hsl:[h,s,l]};\r\n}\r\n\r\n\/* ---------- state ---------- *\/\r\nvar S={r:255,g:107,b:53,a:1,h:16,s:100,l:60};\r\nfunction setRGB(r,g,b,a){\r\n  S.r=clamp(Math.round(r),0,255);S.g=clamp(Math.round(g),0,255);S.b=clamp(Math.round(b),0,255);\r\n  var x=rgbToHsl(S.r,S.g,S.b);\r\n  if(x[1]>0.001&&x[2]>0.001&&x[2]<99.999)S.h=x[0];\r\n  S.s=x[1];S.l=x[2];\r\n  if(a!==undefined)S.a=clamp(a,0,1);\r\n}\r\nfunction setHSL(h,s,l,a){\r\n  S.h=clamp(h,0,360);S.s=clamp(s,0,100);S.l=clamp(l,0,100);\r\n  var c=hslToRgb(S.h%360,S.s,S.l);\r\n  S.r=clamp(Math.round(c[0]),0,255);S.g=clamp(Math.round(c[1]),0,255);S.b=clamp(Math.round(c[2]),0,255);\r\n  if(a!==undefined)S.a=clamp(a,0,1);\r\n}\r\nfunction applyParsed(p){\r\n  if(p.hsl)setHSL(p.hsl[0],p.hsl[1],p.hsl[2],p.a);else setRGB(p.r,p.g,p.b,p.a);\r\n}\r\nfunction mk(p){\r\n  var c={r:p.r,g:p.g,b:p.b,a:p.a};\r\n  if(p.hsl){c.h=p.hsl[0];c.s=p.hsl[1];c.l=p.hsl[2]}\r\n  else{var x=rgbToHsl(p.r,p.g,p.b);c.h=x[0];c.s=x[1];c.l=x[2]}\r\n  return c;\r\n}\r\n\r\n\/* ---------- formatting ---------- *\/\r\nvar O={syntax:'classic',upper:true};\r\nfunction p2(v){var s=v.toString(16);return s.length<2?'0'+s:s}\r\nfunction hv(c){return ((Math.round(c.h)%360)+360)%360}\r\nfunction aN(a){return +a.toFixed(2)}\r\nfunction toHex(c){\r\n  var x=p2(c.r)+p2(c.g)+p2(c.b);\r\n  if(c.a<1)x+=p2(Math.round(c.a*255));\r\n  return '#'+(O.upper?x.toUpperCase():x);\r\n}\r\nfunction toRgb(c){\r\n  var t=c.a<1;\r\n  if(O.syntax==='modern')return 'rgb('+c.r+' '+c.g+' '+c.b+(t?' \/ '+Math.round(c.a*100)+'%':'')+')';\r\n  return t?'rgba('+c.r+', '+c.g+', '+c.b+', '+aN(c.a)+')':'rgb('+c.r+', '+c.g+', '+c.b+')';\r\n}\r\nfunction toHsl(c){\r\n  var h=hv(c),s=Math.round(c.s),l=Math.round(c.l),t=c.a<1;\r\n  if(O.syntax==='modern')return 'hsl('+h+' '+s+'% '+l+'%'+(t?' \/ '+Math.round(c.a*100)+'%':'')+')';\r\n  return t?'hsla('+h+', '+s+'%, '+l+'%, '+aN(c.a)+')':'hsl('+h+', '+s+'%, '+l+'%)';\r\n}\r\nfunction toTok(c){return hv(c)+' '+Math.round(c.s)+'% '+Math.round(c.l)+'%'+(c.a<1?' \/ '+aN(c.a):'')}\r\nvar FMT={hex:toHex,rgb:toRgb,hsl:toHsl,tok:toTok};\r\nfunction rgbCss(c){return 'rgb('+c.r+','+c.g+','+c.b+')'}\r\nfunction rgbaCss(c){return 'rgba('+c.r+','+c.g+','+c.b+','+c.a+')'}\r\nvar CK='conic-gradient(var(--checker-b) 25%,var(--checker-a) 0 50%,var(--checker-b) 0 75%,var(--checker-a) 0) 0 0\/12px 12px';\r\nfunction layer(css){return 'linear-gradient('+css+','+css+'),'+CK}\r\nfunction inkFor(r,g,b){var L=lum(r,g,b);return ratio(L,0)>=ratio(L,1)?'#111513':'#FFFFFF'}\r\n\r\n\/* ---------- toast + copy ---------- *\/\r\nvar tt;\r\nfunction toast(m){var t=$('#toast');t.textContent=m;t.classList.add('on');clearTimeout(tt);tt=setTimeout(function(){t.classList.remove('on')},1700)}\r\nfunction copy(text,label){\r\n  function done(ok){toast(ok?'Copied '+(label||text):'Copy blocked. Select the text and press Ctrl+C.')}\r\n  function fallback(){\r\n    var ok=false;\r\n    try{\r\n      var ta=document.createElement('textarea');ta.value=text;ta.style.cssText='position:fixed;opacity:0;top:0;left:0';\r\n      document.body.appendChild(ta);ta.select();ok=document.execCommand('copy');ta.remove();\r\n    }catch(e){}\r\n    done(ok);\r\n  }\r\n  try{\r\n    if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(text).then(function(){done(true)},fallback)}\r\n    else fallback();\r\n  }catch(e){fallback()}\r\n}\r\n\r\n\/* ---------- DOM: outputs ---------- *\/\r\nvar ICON_COPY='<svg viewBox=\"0 0 24 24\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2.5\"\/><path d=\"M5 15V6a2 2 0 0 1 2-2h9\"\/><\/svg>';\r\nvar ICON_OK='<svg viewBox=\"0 0 24 24\"><path d=\"M5 12.5l4.5 4.5L19 7.5\"\/><\/svg>';\r\nvar OUTS=[\r\n  ['HEX',function(c){return toHex(c)}],\r\n  ['RGB',function(c){return toRgb(c)}],\r\n  ['HSL',function(c){return toHsl(c)}],\r\n  ['HSL tokens',function(c){return toTok(c)}],\r\n  ['CSS variable',function(c){return '--color-primary: '+toHex(c)+';'}],\r\n  ['Tailwind',function(c){return 'bg-['+toHex(c)+']'}]\r\n];\r\nvar outsEl=$('#outs'),outRows=[];\r\nOUTS.forEach(function(o,i){\r\n  var b=document.createElement('button');b.type='button';b.className='out';\r\n  b.innerHTML='<span class=\"out-k\"><\/span><code class=\"out-v\"><\/code><span class=\"ic\"><\/span>';\r\n  b.querySelector('.out-k').textContent=o[0];\r\n  b.querySelector('.ic').innerHTML=ICON_COPY;\r\n  b.addEventListener('click',function(){\r\n    var v=b.querySelector('.out-v').textContent;\r\n    copy(v,o[0]);\r\n    b.classList.add('done');b.querySelector('.ic').innerHTML=ICON_OK;\r\n    setTimeout(function(){b.classList.remove('done');b.querySelector('.ic').innerHTML=ICON_COPY},1200);\r\n  });\r\n  outsEl.appendChild(b);outRows.push(b.querySelector('.out-v'));\r\n});\r\n\r\n\/* ---------- DOM: sliders ---------- *\/\r\nvar CH=[\r\n  {k:'r',l:'R',n:'Red',min:0,max:255,g:'RGB'},\r\n  {k:'g',l:'G',n:'Green',min:0,max:255,g:'RGB'},\r\n  {k:'b',l:'B',n:'Blue',min:0,max:255,g:'RGB'},\r\n  {k:'h',l:'H',n:'Hue',min:0,max:360,g:'HSL'},\r\n  {k:'s',l:'S',n:'Saturation',min:0,max:100,g:'HSL'},\r\n  {k:'l',l:'L',n:'Lightness',min:0,max:100,g:'HSL'},\r\n  {k:'a',l:'A',n:'Opacity',min:0,max:100,g:'Opacity'}\r\n];\r\nvar SL={},slWrap=$('#sliders'),lastG='';\r\nCH.forEach(function(ch){\r\n  if(ch.g!==lastG){var t=document.createElement('div');t.className='grp';t.textContent=ch.g;slWrap.appendChild(t);lastG=ch.g}\r\n  var row=document.createElement('div');row.className='sl';\r\n  row.innerHTML='<label for=\"rng-'+ch.k+'\">'+ch.l+'<\/label>'+\r\n    '<input type=\"range\" id=\"rng-'+ch.k+'\" min=\"'+ch.min+'\" max=\"'+ch.max+'\" step=\"1\" aria-label=\"'+ch.n+'\">'+\r\n    '<input type=\"number\" id=\"num-'+ch.k+'\" min=\"'+ch.min+'\" max=\"'+ch.max+'\" step=\"1\" inputmode=\"numeric\" aria-label=\"'+ch.n+' value\">';\r\n  slWrap.appendChild(row);\r\n  var rng=row.querySelector('input[type=range]'),num=row.querySelector('input[type=number]');\r\n  SL[ch.k]={rng:rng,num:num,ch:ch};\r\n  rng.addEventListener('input',function(){onChannel(ch,parseFloat(rng.value))});\r\n  num.addEventListener('input',function(){var v=parseFloat(num.value);if(isFinite(v))onChannel(ch,v)});\r\n  num.addEventListener('blur',function(){num.value=chVal(ch.k)});\r\n});\r\nfunction chVal(k){\r\n  if(k==='r'||k==='g'||k==='b')return S[k];\r\n  if(k==='h')return Math.round(S.h);\r\n  if(k==='s'||k==='l')return Math.round(S[k]);\r\n  return Math.round(S.a*100);\r\n}\r\nfunction onChannel(ch,v){\r\n  v=clamp(v,ch.min,ch.max);var k=ch.k;\r\n  if(k==='r'||k==='g'||k==='b'){var c={r:S.r,g:S.g,b:S.b};c[k]=Math.round(v);setRGB(c.r,c.g,c.b)}\r\n  else if(k==='a'){S.a=v\/100}\r\n  else{var d={h:S.h,s:S.s,l:S.l};d[k]=v;setHSL(d.h,d.s,d.l)}\r\n  render();\r\n}\r\nfunction paintTracks(){\r\n  var r=S.r,g=S.g,b=S.b,h=S.h.toFixed(1),s=S.s.toFixed(1),l=S.l.toFixed(1);\r\n  SL.r.rng.style.background='linear-gradient(to right,rgb(0,'+g+','+b+'),rgb(255,'+g+','+b+'))';\r\n  SL.g.rng.style.background='linear-gradient(to right,rgb('+r+',0,'+b+'),rgb('+r+',255,'+b+'))';\r\n  SL.b.rng.style.background='linear-gradient(to right,rgb('+r+','+g+',0),rgb('+r+','+g+',255))';\r\n  var stops=[];for(var i=0;i<=6;i++)stops.push('hsl('+(i*60)+' '+s+'% '+l+'%)');\r\n  SL.h.rng.style.background='linear-gradient(to right,'+stops.join(',')+')';\r\n  SL.s.rng.style.background='linear-gradient(to right,hsl('+h+' 0% '+l+'%),hsl('+h+' 100% '+l+'%))';\r\n  SL.l.rng.style.background='linear-gradient(to right,hsl('+h+' '+s+'% 0%),hsl('+h+' '+s+'% 50%),hsl('+h+' '+s+'% 100%))';\r\n  SL.a.rng.style.background='linear-gradient(to right,rgba('+r+','+g+','+b+',0),rgb('+r+','+g+','+b+')),'+CK;\r\n}\r\n\r\n\/* ---------- DOM: contrast ---------- *\/\r\nvar ctEls=[],ctGrid=$('#ctGrid');\r\n['White text','Black text','On white','On black'].forEach(function(lbl){\r\n  var d=document.createElement('div');d.className='ct';\r\n  d.innerHTML='<div class=\"ct-l\"><\/div><div class=\"ct-row\"><span class=\"ct-aa\">Aa<\/span><span class=\"ct-ratio\"><\/span><\/div><div class=\"pills\"><span class=\"pill\"><\/span><span class=\"pill\"><\/span><span class=\"pill\"><\/span><\/div>';\r\n  d.querySelector('.ct-l').textContent=lbl;\r\n  ctGrid.appendChild(d);ctEls.push(d);\r\n});\r\nvar PILLS=[['AA',4.5],['AA Large',3],['AAA',7]];\r\nfunction paintContrast(){\r\n  var L=lum(S.r,S.g,S.b),rw=ratio(L,1),rb=ratio(L,0),col=rgbCss(S);\r\n  var defs=[[col,'#FFFFFF',rw],[col,'#000000',rb],['#FFFFFF',col,rw],['#000000',col,rb]];\r\n  defs.forEach(function(d,i){\r\n    var el=ctEls[i];\r\n    el.style.background=d[0];el.style.color=d[1];\r\n    el.querySelector('.ct-ratio').textContent=d[2].toFixed(2)+':1';\r\n    var ps=el.querySelectorAll('.pill');\r\n    PILLS.forEach(function(p,j){\r\n      var ok=d[2]>=p[1];\r\n      ps[j].textContent=(ok?'\u2713 ':'\u2715 ')+p[0];\r\n      ps[j].className='pill'+(ok?'':' fail');\r\n    });\r\n  });\r\n  var best=rw>=rb?['white',rw]:['black',rb];\r\n  $('#ctBest').innerHTML='Best text on this color: <strong>'+best[0]+'<\/strong> at '+best[1].toFixed(2)+':1.'+(S.a<1?' Opacity is ignored.':'');\r\n}\r\n\r\n\/* ---------- DOM: scale ---------- *\/\r\nvar STEPS=[50,100,200,300,400,500,600,700,800,900,950];\r\nvar TINT={50:.92,100:.84,200:.68,300:.5,400:.25},SHADE={600:.15,700:.3,800:.48,900:.66,950:.8};\r\nvar scaleEl=$('#scale'),stepEls=[],scaleVals=[];\r\nSTEPS.forEach(function(n){\r\n  var b=document.createElement('button');b.type='button';b.className='step'+(n===500?' base':'');\r\n  b.setAttribute('aria-label','Copy shade '+n);\r\n  b.innerHTML='<span class=\"step-c\"><span class=\"pin\"><\/span><\/span><span class=\"step-n\">'+n+'<\/span><span class=\"step-h\"><\/span>';\r\n  b.addEventListener('click',function(){var h=b.getAttribute('data-hex');copy(h,n+' '+h)});\r\n  scaleEl.appendChild(b);stepEls.push(b);\r\n});\r\nfunction scaleColors(){\r\n  return STEPS.map(function(n){\r\n    var t,to,c=[S.r,S.g,S.b];\r\n    if(n===500)return {r:S.r,g:S.g,b:S.b,a:1};\r\n    if(TINT[n]!==undefined){t=TINT[n];to=255}else{t=SHADE[n];to=0}\r\n    return {r:Math.round(c[0]+(to-c[0])*t),g:Math.round(c[1]+(to-c[1])*t),b:Math.round(c[2]+(to-c[2])*t),a:1};\r\n  });\r\n}\r\nfunction paintScale(){\r\n  var cols=scaleColors();scaleVals=cols;\r\n  cols.forEach(function(c,i){\r\n    var el=stepEls[i],h=toHex(c);\r\n    el.setAttribute('data-hex',h);\r\n    el.querySelector('.step-c').style.background=rgbCss(c);\r\n    el.querySelector('.pin').style.background=inkFor(c.r,c.g,c.b);\r\n    el.querySelector('.step-h').textContent=h;\r\n  });\r\n}\r\nfunction prefix(){return ($('#prefix').value||'brand').toLowerCase().replace(\/[^a-z0-9-]+\/g,'-').replace(\/^-+|-+$\/g,'')||'brand'}\r\nfunction cssBlock(prefixName,items){\r\n  return ':root {\\n'+items.map(function(it){return '  --'+prefixName+'-'+it[0]+': '+it[1]+';'}).join('\\n')+'\\n}';\r\n}\r\n$('#copyScale').addEventListener('click',function(){\r\n  var items=STEPS.map(function(n,i){return [n,toHex(scaleVals[i])]});\r\n  copy(cssBlock(prefix(),items),'CSS variables');\r\n});\r\n$('#prefix').addEventListener('input',function(){});\r\n\r\n\/* ---------- DOM: harmonies ---------- *\/\r\nvar HARM=[\r\n  ['Complementary','opposite hue',[0,180]],\r\n  ['Analogous','neighbors, 30\u00b0',[-30,0,30]],\r\n  ['Triadic','three even steps',[0,120,240]],\r\n  ['Split complementary','base plus two near-opposites',[0,150,210]],\r\n  ['Tetradic','four even steps',[0,90,180,270]]\r\n];\r\nvar harmsEl=$('#harms'),harmChips=[];\r\nHARM.forEach(function(h){\r\n  var row=document.createElement('div');row.className='harm';\r\n  var n=document.createElement('div');n.className='harm-n';\r\n  n.innerHTML='<span><\/span><small><\/small>';\r\n  n.querySelector('span').textContent=h[0];n.querySelector('small').textContent=h[1];\r\n  var chips=document.createElement('div');chips.className='chips';\r\n  h[2].forEach(function(off){\r\n    var b=document.createElement('button');b.type='button';b.className='chip'+(off===0?' base':'');\r\n    b.innerHTML='<span class=\"chip-c\"><\/span><span class=\"chip-h\"><\/span>';\r\n    b.setAttribute('data-off',off);\r\n    b.addEventListener('click',function(){\r\n      if(off===0){copy(b.getAttribute('data-hex'),'base color');return}\r\n      var p=parseColor(b.getAttribute('data-hex'));\r\n      if(p){setRGB(p.r,p.g,p.b);render()}\r\n    });\r\n    chips.appendChild(b);harmChips.push(b);\r\n  });\r\n  row.appendChild(n);row.appendChild(chips);harmsEl.appendChild(row);\r\n});\r\nfunction paintHarm(){\r\n  harmChips.forEach(function(b){\r\n    var off=+b.getAttribute('data-off');\r\n    var c=hslToRgb(((S.h+off)%360+360)%360,S.s,S.l).map(Math.round);\r\n    var obj={r:c[0],g:c[1],b:c[2],a:1},hx=toHex(obj);\r\n    if(off===0){obj.a=S.a}\r\n    b.setAttribute('data-hex',off===0?toHex({r:S.r,g:S.g,b:S.b,a:1}):hx);\r\n    b.querySelector('.chip-c').style.background=rgbCss(obj);\r\n    b.querySelector('.chip-h').textContent=(off===0?'base ':'')+(off===0?toHex({r:S.r,g:S.g,b:S.b,a:1}):hx);\r\n  });\r\n}\r\n\r\n\/* ---------- palette ---------- *\/\r\nvar SAMPLE=['#FF6B35','#1B2A41','#F4D35E','#0EAD69','#EFEFE9'];\r\nvar pal=SAMPLE.slice(),usingSample=true;\r\nfunction validHex(h){return typeof h==='string'&&\/^#[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$\/.test(h)}\r\ntry{\r\n  var stored=JSON.parse(localStorage.getItem('hb-pal')||'null');\r\n  if(Array.isArray(stored)){pal=stored.filter(validHex);usingSample=false}\r\n}catch(e){}\r\nfunction persist(){try{localStorage.setItem('hb-pal',JSON.stringify(pal))}catch(e){}}\r\nfunction fmtHexStr(h){return O.upper?h.toUpperCase():h.toLowerCase()}\r\nfunction renderPal(){\r\n  var el=$('#pal');\r\n  $('#palNote').textContent=usingSample?'Sample colors shown until you save your own.':(pal.length?pal.length+' saved on this device.':'Nothing saved yet.');\r\n  if(!pal.length){el.innerHTML='<p class=\"pal-empty\">No colors yet. Use Save to palette to keep the current color here.<\/p>';return}\r\n  el.innerHTML=pal.map(function(h,i){\r\n    var p=parseColor(h),css=rgbaCss(p);\r\n    return '<div class=\"pal-item\"><button type=\"button\" class=\"pal-sw\" data-i=\"'+i+'\" style=\"background:'+layer(css)+'\" aria-label=\"Use '+h+'\"><\/button>'+\r\n      '<button type=\"button\" class=\"pal-x\" data-x=\"'+i+'\" aria-label=\"Remove '+h+'\"><svg viewBox=\"0 0 24 24\"><path d=\"M6 6l12 12M18 6L6 18\"\/><\/svg><\/button>'+\r\n      '<span class=\"pal-h\">'+fmtHexStr(h)+'<\/span><\/div>';\r\n  }).join('');\r\n}\r\n$('#pal').addEventListener('click',function(e){\r\n  var x=e.target.closest('.pal-x'),s=e.target.closest('.pal-sw');\r\n  if(x){pal.splice(+x.getAttribute('data-x'),1);usingSample=false;persist();renderPal();return}\r\n  if(s){var p=parseColor(pal[+s.getAttribute('data-i')]);if(p){applyParsed(p);render()}}\r\n});\r\n$('#saveBtn').addEventListener('click',function(){\r\n  var h=toHex(S).toUpperCase();\r\n  if(usingSample){pal=[];usingSample=false}\r\n  if(pal.indexOf(h)>-1){toast('Already in palette');renderPal();return}\r\n  pal.push(h);persist();renderPal();toast('Saved '+fmtHexStr(h));\r\n});\r\n$('#palClear').addEventListener('click',function(){pal=[];usingSample=false;persist();renderPal()});\r\n$('#palCss').addEventListener('click',function(){\r\n  if(!pal.length){toast('Palette is empty');return}\r\n  copy(cssBlock(prefix(),pal.map(function(h,i){return [i+1,fmtHexStr(h)]})),'CSS variables');\r\n});\r\n$('#palList').addEventListener('click',function(){\r\n  if(!pal.length){toast('Palette is empty');return}\r\n  copy(pal.map(fmtHexStr).join('\\n'),'color list');\r\n});\r\n\r\n\/* ---------- bulk ---------- *\/\r\nvar bulkLast='';\r\nfunction renderBulk(){\r\n  var kind=$('#bulkTo').value,lines=$('#bulkIn').value.split(\/\\r?\\n\/),out=$('#bulkOut'),res=[];\r\n  out.innerHTML='';\r\n  lines.forEach(function(line){\r\n    var t=line.trim();if(!t)return;\r\n    var p=parseColor(t),row=document.createElement('div');row.className='bulk-row';\r\n    var dot=document.createElement('span'),bi=document.createElement('span'),bo=document.createElement('span');\r\n    dot.className='dot';bi.className='bi';bo.className='bo';\r\n    bi.textContent=t;\r\n    if(p){\r\n      var c=mk(p),v=FMT[kind](c);\r\n      dot.style.background=layer(rgbaCss(c));bo.textContent=v;res.push(v);\r\n    }else{\r\n      bo.textContent='Not a color';bo.className='bo bad';\r\n    }\r\n    row.appendChild(dot);row.appendChild(bi);row.appendChild(bo);out.appendChild(row);\r\n  });\r\n  bulkLast=res.join('\\n');\r\n}\r\n$('#bulkIn').addEventListener('input',renderBulk);\r\n$('#bulkTo').addEventListener('change',renderBulk);\r\n$('#bulkCopy').addEventListener('click',function(){\r\n  if(!bulkLast){toast('Nothing to copy');return}\r\n  copy(bulkLast,'converted list');\r\n});\r\n\r\n\/* ---------- main input ---------- *\/\r\nvar inp=$('#colorInput'),hint=$('#hint');\r\nvar HINT='Accepts HEX (3, 4, 6 or 8 digits), rgb(), hsl(), plain R G B numbers and CSS color names.';\r\nfunction setHint(msg,err){hint.textContent=msg;hint.className='hint'+(err?' err':'')}\r\ninp.addEventListener('input',function(){\r\n  if(!inp.value.trim()){setHint(HINT,false);return}\r\n  var p=parseColor(inp.value);\r\n  if(!p){setHint('Could not read that. Try #FF6B35 or rgb(255 107 53).',true);return}\r\n  setHint(HINT,false);applyParsed(p);render();\r\n});\r\ninp.addEventListener('blur',function(){inp.value=toHex(S);setHint(HINT,false)});\r\n\r\nvar picker=$('#picker');\r\npicker.addEventListener('input',function(){\r\n  var p=parseColor(picker.value);if(p){setRGB(p.r,p.g,p.b);render()}\r\n});\r\n$('#randBtn').addEventListener('click',function(){\r\n  setHSL(Math.random()*360,50+Math.random()*45,32+Math.random()*38,1);render();\r\n});\r\nif('EyeDropper' in window){\r\n  var db=$('#dropBtn');db.hidden=false;\r\n  db.addEventListener('click',function(){\r\n    try{\r\n      new window.EyeDropper().open().then(function(r){var p=parseColor(r.sRGBHex);if(p){setRGB(p.r,p.g,p.b);render()}}).catch(function(){});\r\n    }catch(e){}\r\n  });\r\n}\r\n\r\n\/* ---------- option toggles ---------- *\/\r\nfunction wireSeg(id,key,map){\r\n  var seg=$(id);\r\n  seg.addEventListener('click',function(e){\r\n    var b=e.target.closest('button');if(!b)return;\r\n    var v=b.getAttribute('data-v');O[key]=map(v);\r\n    Array.prototype.forEach.call(seg.querySelectorAll('button'),function(x){x.setAttribute('aria-pressed',x===b?'true':'false')});\r\n    render();renderPal();renderBulk();\r\n  });\r\n}\r\nwireSeg('#segSyntax','syntax',function(v){return v});\r\nwireSeg('#segCase','upper',function(v){return v==='upper'});\r\n\r\n\/* ---------- theme ---------- *\/\r\nfunction isDark(){\r\n  var t=root.getAttribute('data-theme');\r\n  if(t)return t==='dark';\r\n  return window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches;\r\n}\r\ntry{var th=localStorage.getItem('hb-theme');if(th==='dark'||th==='light')root.setAttribute('data-theme',th)}catch(e){}\r\n$('#themeBtn').addEventListener('click',function(){\r\n  var next=isDark()?'light':'dark';\r\n  root.setAttribute('data-theme',next);\r\n  try{localStorage.setItem('hb-theme',next)}catch(e){}\r\n});\r\n\r\n\/* ---------- render ---------- *\/\r\nfunction render(){\r\n  var c=S;\r\n  root.style.setProperty('--cur',rgbaCss(c));\r\n  $('#swC').style.background=rgbaCss(c);\r\n  $('#swatch').style.setProperty('--sw-ink',c.a<0.5?'var(--ink)':inkFor(c.r,c.g,c.b));\r\n  var nn=nearest(c.r,c.g,c.b);\r\n  $('#swName').textContent=pretty(nn.name);\r\n  $('#swKind').textContent=nn.exact?'CSS color name':'Closest CSS name';\r\n  $('#swHex').textContent=toHex(c);\r\n  $('#swSub').textContent=toRgb(c);\r\n  OUTS.forEach(function(o,i){outRows[i].textContent=o[1](c)});\r\n  picker.value='#'+p2(c.r)+p2(c.g)+p2(c.b);\r\n  CH.forEach(function(ch){\r\n    var s=SL[ch.k],v=chVal(ch.k);\r\n    if(document.activeElement!==s.rng)s.rng.value=ch.k==='h'?S.h:(ch.k==='s'||ch.k==='l'?S[ch.k]:v);\r\n    if(document.activeElement!==s.num)s.num.value=v;\r\n  });\r\n  paintTracks();paintContrast();paintScale();paintHarm();\r\n  if(document.activeElement!==inp){inp.value=toHex(c);setHint(HINT,false)}\r\n}\r\n\r\nsetRGB(255,107,53,1);\r\nrender();renderPal();renderBulk();\r\nsetHint(HINT,false);\r\n})();\r\n<\/script>\r\n\r\n<\/body><\/html>\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Hue Bench Hue Bench HEX \u00b7 RGB \u00b7 HSL color converter Closest CSS name Tomato #FF6B35 hsl(16, 100%, 60%) Random [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"no-sidebar","site-content-layout":"","ast-site-content-layout":"full-width-container","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"set","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"class_list":["post-468","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/468","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=468"}],"version-history":[{"count":4,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/468\/revisions"}],"predecessor-version":[{"id":473,"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=\/wp\/v2\/pages\/468\/revisions\/473"}],"wp:attachment":[{"href":"https:\/\/ongroundmedia.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}