{"product_id":"11-mini-low-pro-emergency-light-bar","title":"New - 11\" Mini Low Pro Emergency Light Bar","description":"\u003c!-- LOWPRO MINI INTERACTIVE PLAYER --\u003e\n\u003cdiv id=\"lowpro-player-block\" style=\"margin:0 0 26px;\"\u003e\n\u003cdiv class=\"lowpro-cta\"\u003e\n\u003ch2 style=\"margin:0 0 4px;font-size:24px;line-height:1.25;\"\u003eTake the Controls: Try This Light Bar Live\u003c\/h2\u003e\n\u003cp style=\"margin:0 0 12px;font-size:15px;line-height:1.5;\"\u003eFlip the rocker, press the pattern button, and switch on the 360° Halo scene light, exactly like the socket controller that ships in the box. Only the colors this bar is offered in can be selected.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003ciframe id=\"lowpro-player-frame\" class=\"lowpro-frame\" title=\"Mini Low Pro Emergency Bar interactive demo\" style=\"width:100%;border:0;display:block;border-radius:16px;background:#0a0c0f;\" srcdoc=\"\u0026lt;!DOCTYPE html\u0026gt;\n\u0026lt;html lang=\u0026quot;en\u0026quot;\u0026gt;\n\u0026lt;head\u0026gt;\n\u0026lt;meta charset=\u0026quot;UTF-8\u0026quot;\u0026gt;\n\u0026lt;meta name=\u0026quot;viewport\u0026quot; content=\u0026quot;width=device-width, initial-scale=1.0\u0026quot;\u0026gt;\n\u0026lt;title\u0026gt;Mini Low Pro Simulator\u0026lt;\/title\u0026gt;\n\u0026lt;style\u0026gt;\n  :root{\n    --bg:#0a0c0f; --panel:#111418; --panel2:#161a20; --edge:#242a33;\n    --txt:#e8ecf2; --dim:#8a94a3;\n  }\n  *{box-sizing:border-box; -webkit-tap-highlight-color:transparent}\n  html,body{margin:0;padding:0;background:var(--bg);color:var(--txt);\n    font-family:\u0026quot;Segoe UI\u0026quot;,system-ui,-apple-system,Roboto,Arial,sans-serif;}\n  .wrap{max-width:1100px;margin:0 auto;padding:14px 16px 20px;}\n  header{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:6px}\n  .brand{font-weight:800;letter-spacing:.18em;font-size:19px;white-space:nowrap}\n  .brand span{color:var(--dim);font-weight:600}\n  .sub{color:var(--dim);font-size:12.5px;letter-spacing:.08em;text-transform:uppercase}\n  .sizeBtns{margin-left:auto;display:flex;gap:6px}\n  .sizeBtns button{background:var(--panel2);border:1px solid #2c333d;color:var(--txt);\n    border-radius:7px;font-size:12px;padding:4px 10px;cursor:pointer}\n  .sizeBtns button.on{border-color:#ffb43a;color:#ffcf7d}\n  .stage{background:radial-gradient(ellipse at 50% 30%, #14181e 0%, #0b0d11 70%);\n    border:1px solid var(--edge);border-radius:14px;padding:6px 10px 2px;position:relative;overflow:hidden}\n  .stage svg{display:block;width:100%;height:auto}\n  .stageLabel{position:absolute;top:10px;left:14px;font-size:11px;letter-spacing:.14em;\n    color:#5b6470;text-transform:uppercase}\n  .haloBadge{position:absolute;top:10px;right:14px;display:none;align-items:center;gap:8px;\n    font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:#dfe9f7;\n    background:rgba(70,90,120,.22);border:1px solid rgba(190,215,255,.35);\n    border-radius:999px;padding:5px 12px 5px 9px;backdrop-filter:blur(2px)}\n  .haloBadge .dot{width:8px;height:8px;border-radius:50%;background:#F4F8FF;\n    box-shadow:0 0 8px 2px rgba(220,235,255,.9);flex:none}\n  .haloBadge b{font-weight:700;color:#fff}\n  .haloBadge span{color:#9fb0c6;text-transform:none;letter-spacing:.02em}\n  @media(max-width:700px){.haloBadge span{display:none}}\n  .lower{display:grid;grid-template-columns:270px 1fr;gap:14px;margin-top:14px;align-items:stretch}\n  .compactSel{display:none}\n  @media(max-width:840px){\n    .stage{padding:8px 8px 4px}\n    .stageLabel{position:static;font-size:10px;margin:0 0 6px}\n    .haloBadge{position:static;font-size:10px;padding:4px 9px;margin:0 0 6px;width:max-content}\n    .wrap{padding:6px 6px 10px !important}\n    .lower{grid-template-columns:1fr;gap:10px}\n    .cardCtl{order:1}\n    .cardColors{order:2}\n    .cardColors .cRow,.cardColors .hint{display:none}\n    .cardColors.expanded .cRow{display:block}\n    .compactSel{display:flex;align-items:center;gap:10px;flex-wrap:wrap}\n    .compactSel .sw{cursor:default}\n    .compactSel .sw:hover{transform:none}\n  }\n  .card{background:var(--panel);border:1px solid var(--edge);border-radius:14px;padding:14px}\n  .card h3{margin:0 0 10px;font-size:11.5px;letter-spacing:.16em;color:var(--dim);\n    text-transform:uppercase;font-weight:700}\n  .cRow{margin-bottom:12px}\n  .cRow .lbl{font-size:12px;color:var(--dim);margin-bottom:6px;display:flex;justify-content:space-between;align-items:center}\n  .swatches{display:flex;gap:8px;flex-wrap:wrap}\n  .sw{width:38px;height:30px;border-radius:7px;border:2px solid #2c333d;cursor:pointer;\n    position:relative;transition:transform .08s}\n  .sw:hover{transform:translateY(-1px)}\n  .sw.sel{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.25),0 0 14px rgba(255,255,255,.15)}\n  .sw.dis{opacity:.22;cursor:not-allowed}\n  .sw.none{background:repeating-linear-gradient(45deg,#1a1f26 0 6px,#12161b 6px 12px)}\n  .sw.none::after{content:\u0026quot;OFF\u0026quot;;position:absolute;inset:0;display:flex;align-items:center;\n    justify-content:center;font-size:9px;color:#6b7480;font-weight:700;letter-spacing:.05em}\n  .hint{font-size:11.5px;line-height:1.5;color:#6d7684;border-top:1px solid var(--edge);\n    padding-top:10px;margin-top:2px}\n  .hint b{color:#9aa4b2;font-weight:600}\n  .swapBtn{background:var(--panel2);border:1px solid #2c333d;color:var(--txt);border-radius:7px;\n    font-size:11px;padding:4px 9px;cursor:pointer;letter-spacing:.06em}\n  .swapBtn:hover{border-color:#4a5462}\n  .ctlWrap{display:flex;justify-content:center}\n  .ctlWrap svg{width:100%;max-width:300px;height:auto}\n  .legend{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:6px 16px;\n    margin:12px auto 0;max-width:420px;border-top:1px solid var(--edge);padding-top:12px}\n  .legend div{display:flex;align-items:baseline;gap:8px;font-size:11.5px;line-height:1.4}\n  .legend b{color:#ffcf7d;font-weight:700;min-width:20px;flex:none}\n  .legend span{color:#7f8b9c}\n  @media(max-width:520px){.legend{grid-template-columns:1fr}}\n  .kb{cursor:pointer}\n  @keyframes ringPulse{0%,100%{stroke-opacity:.9}50%{stroke-opacity:.12}}\n  .pulseRing{fill:none;stroke:#ffb43a;stroke-width:2.5;animation:ringPulse 1.8s ease-in-out infinite;pointer-events:none}\n  @keyframes hintPulse{0%,100%{opacity:.6}50%{opacity:1}}\n  .tryHint{display:flex;justify-content:center;margin:10px 0 0}\n  .tryHint span{display:inline-flex;align-items:center;gap:8px;font-size:12px;letter-spacing:.08em;\n    text-transform:uppercase;color:#ffcf7d;border:1px solid rgba(255,180,58,.45);border-radius:999px;\n    padding:6px 14px;animation:hintPulse 2.4s ease-in-out infinite;background:rgba(255,180,58,.07)}\n  .tryHint .dotLive{width:7px;height:7px;border-radius:50%;background:#ffb43a;\n    box-shadow:0 0 7px 2px rgba(255,180,58,.7);flex:none}\n  footer{margin-top:12px;color:#59626e;font-size:11px;letter-spacing:.04em;\n    display:flex;justify-content:space-between;flex-wrap:wrap;gap:6px}\n\u0026lt;\/style\u0026gt;\n\u0026lt;\/head\u0026gt;\n\u0026lt;body\u0026gt;\n\u0026lt;div class=\u0026quot;wrap\u0026quot;\u0026gt;\n  \u0026lt;header\u0026gt;\n    \u0026lt;div class=\u0026quot;brand\u0026quot;\u0026gt;BLACK OAK \u0026lt;span\u0026gt;LED\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;sub\u0026quot;\u0026gt;Mini Low Pro\u0026amp;trade; Emergency Bar · Interactive Demo \u0026amp;bull; \u0026lt;span id=\u0026quot;sizeLabel\u0026quot;\u0026gt;17\u0026amp;Prime;\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;sizeBtns\u0026quot; id=\u0026quot;sizeBtns\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n  \u0026lt;\/header\u0026gt;\n\n  \u0026lt;div class=\u0026quot;stage\u0026quot;\u0026gt;\n    \u0026lt;div class=\u0026quot;stageLabel\u0026quot; id=\u0026quot;patternLabel\u0026quot;\u0026gt;Pattern 1 · Split Steady Burn\u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;haloBadge\u0026quot; id=\u0026quot;haloBadge\u0026quot;\u0026gt;\u0026lt;i class=\u0026quot;dot\u0026quot;\u0026gt;\u0026lt;\/i\u0026gt;\n      \u0026lt;b\u0026gt;360\u0026amp;deg; Halo\u0026lt;\/b\u0026gt;\u0026lt;span\u0026gt;\u0026amp;nbsp;scene light \u0026amp;middot; rocker down\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n    \u0026lt;svg id=\u0026quot;barSvg\u0026quot; viewBox=\u0026quot;0 0 1000 240\u0026quot; aria-label=\u0026quot;Light bar simulation\u0026quot;\u0026gt;\u0026lt;\/svg\u0026gt;\n  \u0026lt;\/div\u0026gt;\n\n  \u0026lt;div class=\u0026quot;tryHint\u0026quot; id=\u0026quot;tryHint\u0026quot;\u0026gt;\u0026lt;span\u0026gt;\u0026lt;i class=\u0026quot;dotLive\u0026quot;\u0026gt;\u0026lt;\/i\u0026gt;Live demo \u0026amp;middot; flip the rocker, press the button\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n\n  \u0026lt;div class=\u0026quot;lower\u0026quot;\u0026gt;\n    \u0026lt;div class=\u0026quot;card cardColors\u0026quot; id=\u0026quot;colorCard\u0026quot;\u0026gt;\n      \u0026lt;h3\u0026gt;Select Colors\u0026lt;\/h3\u0026gt;\n      \u0026lt;div class=\u0026quot;compactSel\u0026quot; id=\u0026quot;compactSel\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n      \u0026lt;div class=\u0026quot;cRow\u0026quot;\u0026gt;\n        \u0026lt;div class=\u0026quot;lbl\u0026quot;\u0026gt;\u0026lt;span\u0026gt;Color 1\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;swatches\u0026quot; id=\u0026quot;sw1\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n      \u0026lt;\/div\u0026gt;\n      \u0026lt;div class=\u0026quot;cRow\u0026quot;\u0026gt;\n        \u0026lt;div class=\u0026quot;lbl\u0026quot;\u0026gt;\u0026lt;span\u0026gt;Color 2 (dual color)\u0026lt;\/span\u0026gt;\n          \u0026lt;button class=\u0026quot;swapBtn\u0026quot; id=\u0026quot;swapBtn\u0026quot; title=\u0026quot;Swap Color 1 and Color 2\u0026quot;\u0026gt;\u0026amp;#8646; Swap\u0026lt;\/button\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div class=\u0026quot;swatches\u0026quot; id=\u0026quot;sw2\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n      \u0026lt;\/div\u0026gt;\n      \u0026lt;div class=\u0026quot;hint\u0026quot; id=\u0026quot;colorHint\u0026quot;\u0026gt;\u0026lt;\/div\u0026gt;\n    \u0026lt;\/div\u0026gt;\n    \u0026lt;div class=\u0026quot;card cardCtl\u0026quot;\u0026gt;\n      \u0026lt;h3\u0026gt;Socket Controller · flip the rocker \u0026amp;middot; press the button\u0026lt;\/h3\u0026gt;\n      \u0026lt;div class=\u0026quot;ctlWrap\u0026quot;\u0026gt;\n        \u0026lt;svg id=\u0026quot;ctl\u0026quot; viewBox=\u0026quot;0 0 300 300\u0026quot; aria-label=\u0026quot;Socket plug controller\u0026quot;\u0026gt;\u0026lt;\/svg\u0026gt;\n      \u0026lt;\/div\u0026gt;\n      \u0026lt;div class=\u0026quot;legend\u0026quot;\u0026gt;\n        \u0026lt;div\u0026gt;\u0026lt;b\u0026gt;Button\u0026lt;\/b\u0026gt;\u0026lt;span\u0026gt;Next flash pattern\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div\u0026gt;\u0026lt;b\u0026gt;I\u0026lt;\/b\u0026gt;\u0026lt;span\u0026gt;Warning flash patterns\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div\u0026gt;\u0026lt;b\u0026gt;O\u0026lt;\/b\u0026gt;\u0026lt;span\u0026gt;Off\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n        \u0026lt;div\u0026gt;\u0026lt;b\u0026gt;II\u0026lt;\/b\u0026gt;\u0026lt;span\u0026gt;360\u0026amp;deg; Halo scene light\u0026lt;\/span\u0026gt;\u0026lt;\/div\u0026gt;\n      \u0026lt;\/div\u0026gt;\n    \u0026lt;\/div\u0026gt;\n  \u0026lt;\/div\u0026gt;\n\n  \u0026lt;footer\u0026gt;\n    \u0026lt;div\u0026gt;BLACK OAK LED · Navigate the Night.\u0026lt;\/div\u0026gt;\n    \u0026lt;div\u0026gt;Designed and engineered in Sarasota, Florida\u0026lt;\/div\u0026gt;\n  \u0026lt;\/footer\u0026gt;\n\u0026lt;\/div\u0026gt;\n\n\u0026lt;script\u0026gt;\n\u0026quot;use strict\u0026quot;;\nconst LEDCOLORS = {\n  amber:{main:\u0026quot;#ffb43a\u0026quot;, core:\u0026quot;#ffe9b0\u0026quot;, glow:\u0026quot;#ff9d00\u0026quot;, label:\u0026quot;Amber\u0026quot;},\n  white:{main:\u0026quot;#F4F8FF\u0026quot;, core:\u0026quot;#ffffff\u0026quot;, glow:\u0026quot;#cfe4ff\u0026quot;, label:\u0026quot;White\u0026quot;},\n  red:  {main:\u0026quot;#ff2d23\u0026quot;, core:\u0026quot;#ffb0a8\u0026quot;, glow:\u0026quot;#ff1400\u0026quot;, label:\u0026quot;Red\u0026quot;},\n  blue: {main:\u0026quot;#2a62ff\u0026quot;, core:\u0026quot;#b8ccff\u0026quot;, glow:\u0026quot;#0040ff\u0026quot;, label:\u0026quot;Blue\u0026quot;},\n  green:{main:\u0026quot;#19d949\u0026quot;, core:\u0026quot;#c2ffcf\u0026quot;, glow:\u0026quot;#00c832\u0026quot;, label:\u0026quot;Green\u0026quot;}\n};\n\n\/* Catalog per size, straight from the product pages.\n   singles: colors sold alone. duals: exact combos sold. *\/\nconst SIZES = {\n  \u0026quot;11\u0026quot;: {\n    label:\u0026quot;11\u0026amp;Prime;\u0026quot;, front:4, span:290, x0:355,\n    singles:[], duals:[[\u0026quot;amber\u0026quot;,\u0026quot;white\u0026quot;]],\n    note:\u0026quot;The 11\u0026amp;Prime; Mini ships in Amber \u0026amp;amp; White.\u0026quot;\n  },\n  \u0026quot;17\u0026quot;: {\n    label:\u0026quot;17\u0026amp;Prime;\u0026quot;, front:4, span:390, x0:305,\n    singles:[\u0026quot;amber\u0026quot;,\u0026quot;blue\u0026quot;,\u0026quot;green\u0026quot;,\u0026quot;red\u0026quot;,\u0026quot;white\u0026quot;],\n    duals:[[\u0026quot;amber\u0026quot;,\u0026quot;blue\u0026quot;],[\u0026quot;amber\u0026quot;,\u0026quot;green\u0026quot;],[\u0026quot;amber\u0026quot;,\u0026quot;red\u0026quot;],[\u0026quot;amber\u0026quot;,\u0026quot;white\u0026quot;],[\u0026quot;red\u0026quot;,\u0026quot;blue\u0026quot;],[\u0026quot;red\u0026quot;,\u0026quot;white\u0026quot;]],\n    note:\u0026quot;Every combo shown here is orderable on the 17\u0026amp;Prime; bar.\u0026quot;\n  }\n};\nlet SIZE = \u0026quot;11\u0026quot;;\n\nconst S = {\n  color1:\u0026quot;amber\u0026quot;, color2:\u0026quot;white\u0026quot;,\n  rocker:\u0026quot;up\u0026quot;,            \/\/ up = warning LEDs, mid = off, down = white halo\n  pattern:1\n};\n\nconst NS=\u0026quot;http:\/\/www.w3.org\/2000\/svg\u0026quot;;\nconst bar = document.getElementById(\u0026quot;barSvg\u0026quot;);\nlet modules = [];\nfunction el(name, attrs, parent){\n  const e=document.createElementNS(NS,name);\n  for(const k in attrs) e.setAttribute(k,attrs[k]);\n  if(parent) parent.appendChild(e);\n  return e;\n}\n\nfunction buildBar(){\n  bar.innerHTML=\u0026quot;\u0026quot;; modules=[];\n  const cfg=SIZES[SIZE];\n  const defs = el(\u0026quot;defs\u0026quot;,{},bar);\n  (()=\u0026gt;{ const f=el(\u0026quot;filter\u0026quot;,{id:\u0026quot;ledGlow\u0026quot;, x:\u0026quot;-80%\u0026quot;,y:\u0026quot;-80%\u0026quot;,width:\u0026quot;260%\u0026quot;,height:\u0026quot;260%\u0026quot;},defs);\n    el(\u0026quot;feGaussianBlur\u0026quot;,{stdDeviation:4, result:\u0026quot;b\u0026quot;},f);\n    const m=el(\u0026quot;feMerge\u0026quot;,{},f);\n    el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;b\u0026quot;},m); el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;SourceGraphic\u0026quot;},m); })();\n  (()=\u0026gt;{ const f=el(\u0026quot;filter\u0026quot;,{id:\u0026quot;haloGlow\u0026quot;, filterUnits:\u0026quot;userSpaceOnUse\u0026quot;,\n      x:\u0026quot;-120\u0026quot;,y:\u0026quot;-160\u0026quot;,width:\u0026quot;1240\u0026quot;,height:\u0026quot;560\u0026quot;},defs);\n    el(\u0026quot;feGaussianBlur\u0026quot;,{stdDeviation:11, result:\u0026quot;b\u0026quot;},f);\n    const m=el(\u0026quot;feMerge\u0026quot;,{},f);\n    el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;b\u0026quot;},m); el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;SourceGraphic\u0026quot;},m); })();\n\n  const L=cfg.x0, R=cfg.x0+cfg.span, cL=L-75, cR=R+75;\n  const G = el(\u0026quot;g\u0026quot;,{},bar);\n  const haloLayer = el(\u0026quot;g\u0026quot;,{},G);\n  const sidePaths = {\n    front:`M ${L},62 L ${R},62`,\n    back: `M ${L},178 L ${R},178`,\n    left: `M ${L},62 L ${cL},95 L ${cL},145 L ${L},178`,\n    right:`M ${R},62 L ${cR},95 L ${cR},145 L ${R},178`\n  };\n  const haloEls={};\n  for(const z in sidePaths){\n    const g=el(\u0026quot;g\u0026quot;,{filter:\u0026quot;url(#haloGlow)\u0026quot;},haloLayer);\n    [[10,.9],[26,.4],[52,.16],[88,.07]].forEach(([wd,op])=\u0026gt;{\n      el(\u0026quot;path\u0026quot;,{d:sidePaths[z], stroke:\u0026quot;#eef4ff\u0026quot;,\u0026quot;stroke-width\u0026quot;:wd,\u0026quot;stroke-opacity\u0026quot;:op,\n        fill:\u0026quot;none\u0026quot;,\u0026quot;stroke-linecap\u0026quot;:\u0026quot;round\u0026quot;,\u0026quot;stroke-linejoin\u0026quot;:\u0026quot;round\u0026quot;},g);\n    });\n    g.setAttribute(\u0026quot;visibility\u0026quot;,\u0026quot;hidden\u0026quot;);\n    haloEls[z]=g;\n  }\n  S._haloEls=haloEls;\n\n  el(\u0026quot;polygon\u0026quot;,{points:`${L},62 ${R},62 ${cR},95 ${cR},145 ${R},178 ${L},178 ${cL},145 ${cL},95`,\n    fill:\u0026quot;#15181d\u0026quot;, stroke:\u0026quot;#3a4149\u0026quot;,\u0026quot;stroke-width\u0026quot;:3},G);\n  el(\u0026quot;polygon\u0026quot;,{points:`${L+8},70 ${R-8},70 ${cR-12},99 ${cR-12},141 ${R-8},170 ${L+8},170 ${cL+12},141 ${cL+12},99`,\n    fill:\u0026quot;#0e1114\u0026quot;, stroke:\u0026quot;#22272e\u0026quot;,\u0026quot;stroke-width\u0026quot;:1},G);\n  el(\u0026quot;text\u0026quot;,{x:500,y:114,\u0026quot;text-anchor\u0026quot;:\u0026quot;middle\u0026quot;,fill:\u0026quot;#c9d0d9\u0026quot;,\u0026quot;font-size\u0026quot;:\u0026quot;17\u0026quot;,\n    \u0026quot;font-weight\u0026quot;:\u0026quot;800\u0026quot;,\u0026quot;letter-spacing\u0026quot;:\u0026quot;4\u0026quot;,\u0026quot;font-family\u0026quot;:\u0026quot;inherit\u0026quot;},G).textContent=\u0026quot;BLACK OAK\u0026quot;;\n  el(\u0026quot;text\u0026quot;,{x:500,y:130,\u0026quot;text-anchor\u0026quot;:\u0026quot;middle\u0026quot;,fill:\u0026quot;#4c545e\u0026quot;,\u0026quot;font-size\u0026quot;:\u0026quot;8\u0026quot;,\n    \u0026quot;letter-spacing\u0026quot;:\u0026quot;2\u0026quot;},G).textContent=\u0026quot;SAE W3-1 22\u0026quot;;\n\n  const ledLayer = el(\u0026quot;g\u0026quot;,{},G);\n  const N=cfg.front, h=12, gap=6;\n  const w = cfg.span\/N - gap;\n  const addMod=(zone,x,y)=\u0026gt;{\n    const g=el(\u0026quot;g\u0026quot;,{},ledLayer);\n    const lens=el(\u0026quot;rect\u0026quot;,{x,y,width:w,height:h,rx:4, fill:\u0026quot;#23282f\u0026quot;, stroke:\u0026quot;#10131a\u0026quot;,\u0026quot;stroke-width\u0026quot;:1},g);\n    const halo=el(\u0026quot;rect\u0026quot;,{x:x-6,y:y-6,width:w+12,height:h+12,rx:9, fill:\u0026quot;none\u0026quot;,opacity:0, filter:\u0026quot;url(#ledGlow)\u0026quot;},g);\n    modules.push({zone, lens, halo, px:x+w\/2});\n  };\n  const addRot=(zone,cx,cy,len,rot)=\u0026gt;{\n    const g=el(\u0026quot;g\u0026quot;,{transform:`rotate(${rot} ${cx} ${cy})`},ledLayer);\n    const lens=el(\u0026quot;rect\u0026quot;,{x:cx-len\/2,y:cy-h\/2,width:len,height:h,rx:4,\n      fill:\u0026quot;#23282f\u0026quot;,stroke:\u0026quot;#10131a\u0026quot;,\u0026quot;stroke-width\u0026quot;:1},g);\n    const halo=el(\u0026quot;rect\u0026quot;,{x:cx-len\/2-6,y:cy-h\/2-6,width:len+12,height:h+12,rx:9,\n      fill:\u0026quot;none\u0026quot;,opacity:0,filter:\u0026quot;url(#ledGlow)\u0026quot;},g);\n    modules.push({zone,lens,halo,px:cx});\n  };\n  for(let i=0;i\u0026lt;N;i++){ addMod(\u0026quot;front\u0026quot;, L+5+i*(cfg.span\/N), 52); }\n  addRot(\u0026quot;right\u0026quot;,R+34,73,64,23.7);\n  addRot(\u0026quot;right\u0026quot;,cR-4,120,44,90);\n  addRot(\u0026quot;right\u0026quot;,R+34,167,64,-23.7);\n  for(let i=N-1;i\u0026gt;=0;i--){ addMod(\u0026quot;back\u0026quot;, L+5+i*(cfg.span\/N), 176); }\n  addRot(\u0026quot;left\u0026quot;,L-34,167,64,23.7);\n  addRot(\u0026quot;left\u0026quot;,cL+4,120,44,90);\n  addRot(\u0026quot;left\u0026quot;,L-34,73,64,-23.7);\n\n  const pxs=modules.map(m=\u0026gt;m.px);\n  S._pxmin=Math.min(...pxs); S._pxmax=Math.max(...pxs);\n  const mid=(S._pxmin+S._pxmax)\/2;\n  modules.forEach(m=\u0026gt;{ m.side = m.px\u0026lt;=mid ? \u0026quot;L\u0026quot;:\u0026quot;R\u0026quot;; m.p=(m.px-S._pxmin)\/(S._pxmax-S._pxmin); });\n}\n\n\/* ---- Pattern engine. Timings measured frame-by-frame from the 17\u0026quot; socket-controller video. ---- *\/\nfunction ph(t,cyc){ return t % cyc; }\nconst PATTERNS = [\n  {name:\u0026quot;Split Steady Burn\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{           \/\/ video 11.5-16s \/ 26-37s \/ 95s-end\n    return {color: m.side===\u0026quot;L\u0026quot;?c1:c2, k:.85};\n  }},\n  {name:\u0026quot;Alternating Single Flash\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{     \/\/ video 37-42s: A 170ms, off 230, W 200, off 240\n    const p=ph(t,840);\n    if(p\u0026lt;170) return {color:c1,k:1};\n    if(p\u0026gt;=400\u0026amp;\u0026amp;p\u0026lt;600) return {color:c2,k:1};\n    return null;\n  }},\n  {name:\u0026quot;Split Flash\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{                  \/\/ video 42.5-45.8s: halves flash together, 200 on \/ 270 off\n    const p=ph(t,470);\n    if(p\u0026lt;200) return {color: m.side===\u0026quot;L\u0026quot;?c2:c1, k:1};\n    return null;\n  }},\n  {name:\u0026quot;Alternating Double Flash\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{     \/\/ video 45.9-49s\n    const p=ph(t,1470);\n    if(p\u0026lt;130||(p\u0026gt;=200\u0026amp;\u0026amp;p\u0026lt;330)) return {color:c1,k:1};\n    if((p\u0026gt;=730\u0026amp;\u0026amp;p\u0026lt;860)||(p\u0026gt;=930\u0026amp;\u0026amp;p\u0026lt;1060)) return {color:c2,k:1};\n    return null;\n  }},\n  {name:\u0026quot;Slow Alternating Flash\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{       \/\/ video 49-52s: 430 on \/ 370 off each color\n    const p=ph(t,1600);\n    if(p\u0026lt;430) return {color:c1,k:1};\n    if(p\u0026gt;=800\u0026amp;\u0026amp;p\u0026lt;1230) return {color:c2,k:1};\n    return null;\n  }},\n  {name:\u0026quot;Double Flash + Steady\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{        \/\/ video 52.2-55.9s: C1 double pulse, C2 400ms burn\n    const p=ph(t,1300);\n    if(p\u0026lt;200||(p\u0026gt;=270\u0026amp;\u0026amp;p\u0026lt;470)) return {color:c1,k:1};\n    if(p\u0026gt;=600\u0026amp;\u0026amp;p\u0026lt;1000) return {color:c2,k:.85};\n    return null;\n  }},\n  {name:\u0026quot;Half Ping-Pong\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{               \/\/ video 56-63s: L C1, R C1, L C2, R C2\n    const p=ph(t,1600), seg=Math.floor(p\/400), local=p%400;\n    if(local\u0026gt;=270) return null;\n    const col = seg\u0026lt;2?c1:c2, side = (seg%2===0)?\u0026quot;L\u0026quot;:\u0026quot;R\u0026quot;;\n    return m.side===side ? {color:col,k:1} : null;\n  }},\n  {name:\u0026quot;Dual Rotation\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{                \/\/ video 63-70.4s: opposite ends counter-chasing\n    const p=ph(t,1400)\/1400;\n    const d1=Math.abs(m.p-p), d2=Math.abs(m.p-((p+.5)%1));\n    if(Math.min(d1,1-d1)\u0026lt;.18) return {color:c1,k:1};\n    if(Math.min(d2,1-d2)\u0026lt;.18) return {color:c2,k:1};\n    return null;\n  }},\n  {name:\u0026quot;Steady + Flash Combo\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{         \/\/ video 70.4-77.5s: one half steady, other flashes; swaps\n    const swap=Math.floor(t\/3500)%2===1;\n    const steadySide = swap?\u0026quot;R\u0026quot;:\u0026quot;L\u0026quot;;\n    if(m.side===steadySide) return {color: swap?c2:c1, k:.8};\n    const p=ph(t,730);\n    if(p\u0026lt;330) return {color: swap?c1:c2, k:1};\n    return null;\n  }},\n  {name:\u0026quot;End-to-End Sweep\u0026quot;, f:(m,t,c1,c2)=\u0026gt;{             \/\/ video 77.6-85.9s: C1 builds across, then C2\n    const cyc=1700, p=ph(t,cyc), half=cyc\/2;\n    const dirFlip=Math.floor(t\/cyc)%2===1;\n    const local=p%half, col=p\u0026lt;half?c1:c2;\n    let b;\n    if(local\u0026lt;500) b=local\/500; else if(local\u0026lt;700) b=1; else return null;\n    const pos=dirFlip?1-m.p:m.p;\n    return pos\u0026lt;=b+.002 ? {color:col,k:1} : null;\n  }}\n];\n\nfunction activeColors(){\n  const c1=S.color1, c2=S.color2||S.color1;\n  return [c1,c2];\n}\n\nlet lastLabel=\u0026quot;\u0026quot;;\nfunction render(t){\n  const halo = S.rocker===\u0026quot;down\u0026quot;;\n  const on = S.rocker===\u0026quot;up\u0026quot;;\n  const [c1,c2]=activeColors();\n  const P=PATTERNS[S.pattern-1];\n  for(const m of modules){\n    let st=null;\n    if(on) st=P.f(m,t,c1,c2);\n    else if(halo) st={color:\u0026quot;white\u0026quot;,k:.9};\n    m.cur=st;\n    if(st){ m.lastT=t; m.lastC=st.color; m.lastK=st.k; }\n    let drawC=null, drawK=0;\n    if(st){ drawC=st.color; drawK=st.k; }\n    else if(m.lastC \u0026amp;\u0026amp; (t-m.lastT)\u0026lt;70){ drawC=m.lastC; drawK=m.lastK*(1-(t-m.lastT)\/70)*.7; }\n    if(drawC){\n      const c=LEDCOLORS[drawC];\n      m.lens.setAttribute(\u0026quot;fill\u0026quot;, drawK\u0026gt;.55? c.core : c.main);\n      m.lens.setAttribute(\u0026quot;stroke\u0026quot;, c.main);\n      m.halo.setAttribute(\u0026quot;fill\u0026quot;, c.glow);\n      m.halo.setAttribute(\u0026quot;opacity\u0026quot;, (0.85*drawK).toFixed(2));\n    }else{\n      m.lens.setAttribute(\u0026quot;fill\u0026quot;,\u0026quot;#23282f\u0026quot;);\n      m.lens.setAttribute(\u0026quot;stroke\u0026quot;,\u0026quot;#10131a\u0026quot;);\n      m.halo.setAttribute(\u0026quot;opacity\u0026quot;,\u0026quot;0\u0026quot;);\n    }\n  }\n  for(const z in S._haloEls) S._haloEls[z].setAttribute(\u0026quot;visibility\u0026quot;, halo?\u0026quot;visible\u0026quot;:\u0026quot;hidden\u0026quot;);\n  const lbl = S.rocker===\u0026quot;mid\u0026quot; ? \u0026quot;Rocker centered · Off\u0026quot;\n    : S.rocker===\u0026quot;down\u0026quot; ? \u0026quot;360° Halo Scene Light · steady white\u0026quot;\n    : tourActive ? \u0026quot;Live demo · 10 flash patterns\u0026quot;\n    : `Pattern ${S.pattern} · ${P.name}`;\n  if(lbl!==lastLabel){ lastLabel=lbl; document.getElementById(\u0026quot;patternLabel\u0026quot;).textContent=lbl; }\n  document.getElementById(\u0026quot;haloBadge\u0026quot;).style.display = halo ? \u0026quot;flex\u0026quot;:\u0026quot;none\u0026quot;;\n  requestAnimationFrame(render);\n}\n\n\/* ---------------- Socket controller (replica of the plug in the video) ---------------- *\/\nconst ctl=document.getElementById(\u0026quot;ctl\u0026quot;);\nlet rockerParts={}, patternBtnG=null;\nfunction buildController(){\n  ctl.innerHTML=\u0026quot;\u0026quot;;\n  const defs=el(\u0026quot;defs\u0026quot;,{},ctl);\n  (()=\u0026gt;{ const f=el(\u0026quot;filter\u0026quot;,{id:\u0026quot;btnGlow\u0026quot;,x:\u0026quot;-40%\u0026quot;,y:\u0026quot;-40%\u0026quot;,width:\u0026quot;180%\u0026quot;,height:\u0026quot;180%\u0026quot;},defs);\n    el(\u0026quot;feGaussianBlur\u0026quot;,{stdDeviation:\u0026quot;2.2\u0026quot;,result:\u0026quot;b\u0026quot;},f);\n    const m=el(\u0026quot;feMerge\u0026quot;,{},f);\n    el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;b\u0026quot;},m); el(\u0026quot;feMergeNode\u0026quot;,{in:\u0026quot;SourceGraphic\u0026quot;},m); })();\n  const lg=el(\u0026quot;linearGradient\u0026quot;,{id:\u0026quot;plugBody\u0026quot;,x1:\u0026quot;0\u0026quot;,y1:\u0026quot;0\u0026quot;,x2:\u0026quot;0\u0026quot;,y2:\u0026quot;1\u0026quot;},defs);\n  el(\u0026quot;stop\u0026quot;,{offset:\u0026quot;0\u0026quot;,\u0026quot;stop-color\u0026quot;:\u0026quot;#2a2f37\u0026quot;},lg);\n  el(\u0026quot;stop\u0026quot;,{offset:\u0026quot;.5\u0026quot;,\u0026quot;stop-color\u0026quot;:\u0026quot;#171a1f\u0026quot;},lg);\n  el(\u0026quot;stop\u0026quot;,{offset:\u0026quot;1\u0026quot;,\u0026quot;stop-color\u0026quot;:\u0026quot;#0d0f12\u0026quot;},lg);\n\n  \/* socket base (the 12V outlet it plugs into) *\/\n  el(\u0026quot;ellipse\u0026quot;,{cx:150,cy:262,rx:118,ry:26,fill:\u0026quot;#0b0d10\u0026quot;,stroke:\u0026quot;#242a33\u0026quot;},ctl);\n  el(\u0026quot;ellipse\u0026quot;,{cx:150,cy:256,rx:100,ry:20,fill:\u0026quot;#10131a\u0026quot;,stroke:\u0026quot;#2b333d\u0026quot;},ctl);\n  el(\u0026quot;ellipse\u0026quot;,{cx:150,cy:254,rx:74,ry:14,fill:\u0026quot;none\u0026quot;,stroke:\u0026quot;#2a62ff\u0026quot;,\u0026quot;stroke-opacity\u0026quot;:\u0026quot;.55\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;3\u0026quot;,filter:\u0026quot;url(#btnGlow)\u0026quot;},ctl);\n\n  \/* plug barrel *\/\n  el(\u0026quot;rect\u0026quot;,{x:116,y:196,width:68,height:62,rx:14,fill:\u0026quot;url(#plugBody)\u0026quot;,stroke:\u0026quot;#000\u0026quot;},ctl);\n\n  \/* controller head *\/\n  el(\u0026quot;rect\u0026quot;,{x:70,y:26,width:160,height:184,rx:26,fill:\u0026quot;url(#plugBody)\u0026quot;,stroke:\u0026quot;#000\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;2\u0026quot;},ctl);\n  el(\u0026quot;rect\u0026quot;,{x:78,y:34,width:144,height:168,rx:20,fill:\u0026quot;none\u0026quot;,stroke:\u0026quot;#2c333d\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;1.2\u0026quot;},ctl);\n\n  \/* pattern button on top *\/\n  const pb=el(\u0026quot;g\u0026quot;,{class:\u0026quot;kb\u0026quot;,role:\u0026quot;button\u0026quot;,tabindex:\u0026quot;0\u0026quot;,\u0026quot;aria-label\u0026quot;:\u0026quot;Cycle flash pattern\u0026quot;},ctl);\n  el(\u0026quot;circle\u0026quot;,{cx:150,cy:58,r:20,fill:\u0026quot;#101318\u0026quot;,stroke:\u0026quot;#000\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;2\u0026quot;},pb);\n  const pbFace=el(\u0026quot;circle\u0026quot;,{cx:150,cy:58,r:14,fill:\u0026quot;#22262d\u0026quot;,stroke:\u0026quot;#3a414b\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;1.5\u0026quot;},pb);\n  el(\u0026quot;text\u0026quot;,{x:150,y:92,\u0026quot;text-anchor\u0026quot;:\u0026quot;middle\u0026quot;,fill:\u0026quot;#8a94a3\u0026quot;,\u0026quot;font-size\u0026quot;:\u0026quot;10\u0026quot;,\u0026quot;letter-spacing\u0026quot;:\u0026quot;1.5\u0026quot;,\u0026quot;font-weight\u0026quot;:\u0026quot;700\u0026quot;},pb).textContent=\u0026quot;PATTERN\u0026quot;;\n  pb.addEventListener(\u0026quot;click\u0026quot;,()=\u0026gt;press(\u0026quot;pattern\u0026quot;));\n  pb.addEventListener(\u0026quot;keydown\u0026quot;,e=\u0026gt;{if(e.key===\u0026quot;Enter\u0026quot;||e.key===\u0026quot; \u0026quot;){e.preventDefault();press(\u0026quot;pattern\u0026quot;);}});\n  patternBtnG={g:pb,face:pbFace};\n  S._ring=el(\u0026quot;circle\u0026quot;,{cx:150,cy:58,r:24,class:\u0026quot;pulseRing\u0026quot;},ctl);\n\n  \/* 3-position rocker *\/\n  const rx=150, ry=150, rw=56, rh=92;\n  el(\u0026quot;rect\u0026quot;,{x:rx-rw\/2-7,y:ry-rh\/2-7,width:rw+14,height:rh+14,rx:12,fill:\u0026quot;#0c0e12\u0026quot;,stroke:\u0026quot;#000\u0026quot;},ctl);\n  const zones=[\n    {pos:\u0026quot;up\u0026quot;,   y:ry-rh\/2,      lab:\u0026quot;I\u0026quot;},\n    {pos:\u0026quot;mid\u0026quot;,  y:ry-rh\/6,      lab:\u0026quot;O\u0026quot;},\n    {pos:\u0026quot;down\u0026quot;, y:ry+rh\/6,      lab:\u0026quot;II\u0026quot;}\n  ];\n  rockerParts={};\n  zones.forEach(z=\u0026gt;{\n    const g=el(\u0026quot;g\u0026quot;,{class:\u0026quot;kb\u0026quot;,role:\u0026quot;button\u0026quot;,tabindex:\u0026quot;0\u0026quot;,\u0026quot;aria-label\u0026quot;:\u0026quot;Rocker \u0026quot;+z.pos},ctl);\n    const r=el(\u0026quot;rect\u0026quot;,{x:rx-rw\/2,y:z.y,width:rw,height:rh\/3,fill:\u0026quot;#1b1f26\u0026quot;,stroke:\u0026quot;#31383f\u0026quot;,\u0026quot;stroke-width\u0026quot;:\u0026quot;1\u0026quot;},g);\n    const tx=el(\u0026quot;text\u0026quot;,{x:rx,y:z.y+rh\/6+4,\u0026quot;text-anchor\u0026quot;:\u0026quot;middle\u0026quot;,fill:\u0026quot;#9aa4b2\u0026quot;,\u0026quot;font-size\u0026quot;:\u0026quot;13\u0026quot;,\u0026quot;font-weight\u0026quot;:\u0026quot;700\u0026quot;},g);\n    tx.textContent=z.lab;\n    g.addEventListener(\u0026quot;click\u0026quot;,()=\u0026gt;press(\u0026quot;rocker_\u0026quot;+z.pos));\n    g.addEventListener(\u0026quot;keydown\u0026quot;,e=\u0026gt;{if(e.key===\u0026quot;Enter\u0026quot;||e.key===\u0026quot; \u0026quot;){e.preventDefault();press(\u0026quot;rocker_\u0026quot;+z.pos);}});\n    rockerParts[z.pos]={rect:r,text:tx};\n  });\n\n  el(\u0026quot;text\u0026quot;,{x:150,y:288,fill:\u0026quot;#59636f\u0026quot;,\u0026quot;font-size\u0026quot;:\u0026quot;10\u0026quot;,\u0026quot;letter-spacing\u0026quot;:\u0026quot;1.5\u0026quot;,\u0026quot;text-anchor\u0026quot;:\u0026quot;middle\u0026quot;},ctl).textContent=\u0026quot;12V SOCKET\u0026quot;;\n  syncRocker();\n}\nfunction syncRocker(){\n  for(const pos in rockerParts){\n    const on = S.rocker===pos;\n    rockerParts[pos].rect.setAttribute(\u0026quot;fill\u0026quot;, on? (pos===\u0026quot;mid\u0026quot;?\u0026quot;#3a414b\u0026quot;:\u0026quot;#dfe7f5\u0026quot;) : \u0026quot;#1b1f26\u0026quot;);\n    rockerParts[pos].text.setAttribute(\u0026quot;fill\u0026quot;, on? \u0026quot;#12151a\u0026quot; : \u0026quot;#9aa4b2\u0026quot;);\n    if(on) rockerParts[pos].rect.setAttribute(\u0026quot;filter\u0026quot;,\u0026quot;url(#btnGlow)\u0026quot;);\n    else rockerParts[pos].rect.removeAttribute(\u0026quot;filter\u0026quot;);\n  }\n}\nfunction press(key){\n  markInteract();\n  if(key===\u0026quot;pattern\u0026quot;){\n    if(S.rocker!==\u0026quot;up\u0026quot;){ S.rocker=\u0026quot;up\u0026quot;; }   \/\/ like the hardware: button only matters with rocker up\n    else S.pattern = S.pattern % PATTERNS.length + 1;\n    patternBtnG.face.setAttribute(\u0026quot;fill\u0026quot;,\u0026quot;#aab6c9\u0026quot;);\n    setTimeout(()=\u0026gt;patternBtnG.face.setAttribute(\u0026quot;fill\u0026quot;,\u0026quot;#22262d\u0026quot;),140);\n  }\n  if(key===\u0026quot;rocker_up\u0026quot;) S.rocker=\u0026quot;up\u0026quot;;\n  if(key===\u0026quot;rocker_mid\u0026quot;) S.rocker=\u0026quot;mid\u0026quot;;\n  if(key===\u0026quot;rocker_down\u0026quot;) S.rocker=\u0026quot;down\u0026quot;;\n  syncRocker();\n}\n\n\/* ---------------- Color selection, constrained to the catalog ---------------- *\/\nfunction catalog(){ return SIZES[SIZE]; }\nfunction validC2(c1){\n  const c=catalog(); const out=[];\n  c.duals.forEach(([a,b])=\u0026gt;{ if(a===c1) out.push(b); else if(b===c1) out.push(a); });\n  return out;\n}\nfunction allC1(){\n  const c=catalog(); const set=new Set(c.singles);\n  c.duals.forEach(([a,b])=\u0026gt;{set.add(a);set.add(b);});\n  return [\u0026quot;amber\u0026quot;,\u0026quot;white\u0026quot;,\u0026quot;red\u0026quot;,\u0026quot;blue\u0026quot;,\u0026quot;green\u0026quot;].filter(x=\u0026gt;set.has(x));\n}\nfunction buildCompact(){\n  const c=document.getElementById(\u0026quot;compactSel\u0026quot;);\n  c.innerHTML=\u0026quot;\u0026quot;;\n  const mk=(col)=\u0026gt;{ const d=document.createElement(\u0026quot;div\u0026quot;); d.className=\u0026quot;sw\u0026quot;;\n    d.style.background=LEDCOLORS[col].main; d.title=LEDCOLORS[col].label; return d; };\n  const lab=document.createElement(\u0026quot;span\u0026quot;);\n  lab.style.cssText=\u0026quot;font-size:12px;color:#8a94a3\u0026quot;;\n  lab.textContent=\u0026quot;Your colors:\u0026quot;;\n  c.appendChild(lab);\n  c.appendChild(mk(S.color1));\n  if(S.color2) c.appendChild(mk(S.color2));\n  const btn=document.createElement(\u0026quot;button\u0026quot;);\n  btn.className=\u0026quot;swapBtn\u0026quot;;\n  const card=document.getElementById(\u0026quot;colorCard\u0026quot;);\n  btn.textContent = card.classList.contains(\u0026quot;expanded\u0026quot;) ? \u0026quot;Done\u0026quot; : \u0026quot;Change colors\u0026quot;;\n  btn.onclick=()=\u0026gt;{ card.classList.toggle(\u0026quot;expanded\u0026quot;); buildCompact(); };\n  c.appendChild(btn);\n}\nfunction buildSwatches(){\n  buildCompact();\n  const s1=document.getElementById(\u0026quot;sw1\u0026quot;), s2=document.getElementById(\u0026quot;sw2\u0026quot;);\n  s1.innerHTML=\u0026quot;\u0026quot;; s2.innerHTML=\u0026quot;\u0026quot;;\n  const c=catalog();\n  for(const col of allC1()){\n    const d=document.createElement(\u0026quot;div\u0026quot;);\n    d.className=\u0026quot;sw\u0026quot;+(S.color1===col?\u0026quot; sel\u0026quot;:\u0026quot;\u0026quot;);\n    d.style.background=LEDCOLORS[col].main; d.title=LEDCOLORS[col].label;\n    d.onclick=()=\u0026gt;{\n      S.color1=col;\n      const v=validC2(col);\n      if(S.color2 \u0026amp;\u0026amp; !v.includes(S.color2)) S.color2 = v.length? v[0] : null;\n      if(!S.color2 \u0026amp;\u0026amp; !c.singles.includes(col) \u0026amp;\u0026amp; v.length) S.color2=v[0];\n      buildSwatches();\n    };\n    s1.appendChild(d);\n  }\n  const v=validC2(S.color1);\n  if(c.singles.includes(S.color1)){\n    const none=document.createElement(\u0026quot;div\u0026quot;);\n    none.className=\u0026quot;sw none\u0026quot;+(S.color2===null?\u0026quot; sel\u0026quot;:\u0026quot;\u0026quot;);\n    none.title=\u0026quot;Single color\u0026quot;; none.onclick=()=\u0026gt;{S.color2=null; buildSwatches();};\n    s2.appendChild(none);\n  }\n  for(const col of [\u0026quot;amber\u0026quot;,\u0026quot;white\u0026quot;,\u0026quot;red\u0026quot;,\u0026quot;blue\u0026quot;,\u0026quot;green\u0026quot;]){\n    if(col===S.color1) continue;\n    const ok=v.includes(col);\n    const d=document.createElement(\u0026quot;div\u0026quot;);\n    d.className=\u0026quot;sw\u0026quot;+(S.color2===col?\u0026quot; sel\u0026quot;:\u0026quot;\u0026quot;)+(ok?\u0026quot;\u0026quot;:\u0026quot; dis\u0026quot;);\n    d.style.background=LEDCOLORS[col].main;\n    d.title=ok? LEDCOLORS[col].label : \u0026quot;Not offered with \u0026quot;+LEDCOLORS[S.color1].label+\u0026quot; on this size\u0026quot;;\n    if(ok) d.onclick=()=\u0026gt;{ S.color2=col; buildSwatches(); };\n    s2.appendChild(d);\n  }\n  document.getElementById(\u0026quot;colorHint\u0026quot;).innerHTML =\n    catalog().note + \u0026quot; Rocker \u0026lt;b\u0026gt;up\u0026lt;\/b\u0026gt; runs the warning patterns and the button steps through them, \u0026quot; +\n    \u0026quot;exactly like the switch built into the socket plug. Rocker \u0026lt;b\u0026gt;down\u0026lt;\/b\u0026gt; is the \u0026lt;b\u0026gt;360\u0026amp;deg; Halo scene light\u0026lt;\/b\u0026gt;: \u0026quot; +\n    \u0026quot;steady white work light, a Low Pro exclusive.\u0026quot;;\n}\ndocument.getElementById(\u0026quot;swapBtn\u0026quot;).onclick=()=\u0026gt;{\n  if(!S.color2) return;\n  const a=S.color1,b=S.color2;\n  const c=catalog();\n  const ok=c.duals.some(([x,y])=\u0026gt;(x===b\u0026amp;\u0026amp;y===a)||(x===a\u0026amp;\u0026amp;y===b));\n  if(ok){ S.color1=b; S.color2=a; buildSwatches(); }\n};\n\n\/* ---------------- Size selector (prototype only; each product page pins its size) ---------------- *\/\nfunction buildSizeBtns(){\n  const holder=document.getElementById(\u0026quot;sizeBtns\u0026quot;);\n  holder.innerHTML=\u0026quot;\u0026quot;;\n  for(const s in SIZES){\n    const b=document.createElement(\u0026quot;button\u0026quot;);\n    b.textContent=s+'\u0026quot;'; b.className=SIZE===s?\u0026quot;on\u0026quot;:\u0026quot;\u0026quot;;\n    b.onclick=()=\u0026gt;{ SIZE=s; applySize(); };\n    holder.appendChild(b);\n  }\n}\nfunction applySize(){\n  document.getElementById(\u0026quot;sizeLabel\u0026quot;).innerHTML=SIZES[SIZE].label;\n  const c=catalog();\n  \/* prefer amber\/white, the house default, when the size offers it *\/\n  const pref=c.duals.find(([a,b])=\u0026gt;(a===\u0026quot;amber\u0026quot;\u0026amp;\u0026amp;b===\u0026quot;white\u0026quot;)||(a===\u0026quot;white\u0026quot;\u0026amp;\u0026amp;b===\u0026quot;amber\u0026quot;));\n  const firstDual=pref||c.duals[0];\n  S.color1=firstDual?\u0026quot;amber\u0026quot;:(c.singles[0]||\u0026quot;amber\u0026quot;);\n  if(firstDual\u0026amp;\u0026amp;!firstDual.includes(\u0026quot;amber\u0026quot;)) S.color1=firstDual[0];\n  S.color2=firstDual?(firstDual.find(x=\u0026gt;x!==S.color1)||null):null;\n  S.pattern=1;\n  buildBar(); buildSwatches(); buildSizeBtns();\n}\n\n\/* ---------------- Attract mode ---------------- *\/\nlet interacted=false, idleTimer=null, tourTimer=null, tourActive=false;\nfunction markInteract(){\n  if(interacted) return;\n  interacted=true;\n  if(tourActive){ tourActive=false; S.pattern=1; }\n  clearTimeout(tourTimer); clearTimeout(idleTimer);\n  const h=document.getElementById(\u0026quot;tryHint\u0026quot;);\n  if(h){ h.style.transition=\u0026quot;opacity .5s\u0026quot;; h.style.opacity=\u0026quot;0\u0026quot;; setTimeout(()=\u0026gt;h.remove(),600); }\n  if(S._ring) S._ring.remove();\n}\nfunction attractSweep(){\n  if(interacted||tourActive) return;\n  tourActive=true;\n  const prev=S.pattern; S.pattern=10;      \/\/ End-to-End Sweep as the attract animation\n  tourTimer=setTimeout(()=\u0026gt;{ if(tourActive){ tourActive=false; S.pattern=prev; } scheduleIdle(); }, 3600);\n}\nfunction scheduleIdle(){\n  if(interacted) return;\n  clearTimeout(idleTimer);\n  idleTimer=setTimeout(attractSweep, 18000);\n}\n(function(){\n  let fired=false;\n  const start=()=\u0026gt;{ if(!fired){ fired=true; setTimeout(attractSweep, 700); } };\n  if(window.IntersectionObserver){\n    new IntersectionObserver((es,obs)=\u0026gt;{\n      if(es.some(e=\u0026gt;e.isIntersecting)){ start(); obs.disconnect(); }\n    },{threshold:.5}).observe(document.querySelector(\u0026quot;.stage\u0026quot;));\n  } else start();\n})();\n\n\/* ---------------- Boot + embed plumbing ---------------- *\/\nbuildController();\napplySize();\nrequestAnimationFrame(render);\n\n(function(){\n  const embedded = (window!==parent);\n  if(embedded){\n    document.querySelector(\u0026quot;header\u0026quot;).style.display=\u0026quot;none\u0026quot;;\n    document.querySelector(\u0026quot;footer\u0026quot;).style.display=\u0026quot;none\u0026quot;;\n    document.getElementById(\u0026quot;sizeBtns\u0026quot;).style.display=\u0026quot;none\u0026quot;;\n    if(window.innerWidth\u0026gt;840) document.querySelector(\u0026quot;.wrap\u0026quot;).style.padding=\u0026quot;10px 12px 14px\u0026quot;;\n  }\n  const report=()=\u0026gt;{ try{\n    parent.postMessage({type:\u0026quot;lowpro-player-height\u0026quot;,\n      height: document.querySelector(\u0026quot;.wrap\u0026quot;).scrollHeight+8}, \u0026quot;*\u0026quot;);\n  }catch(e){} };\n  if(window.ResizeObserver) new ResizeObserver(report).observe(document.querySelector(\u0026quot;.wrap\u0026quot;));\n  window.addEventListener(\u0026quot;load\u0026quot;,report); window.addEventListener(\u0026quot;pageshow\u0026quot;,report);\n  setTimeout(report,400); setTimeout(report,1500);\n  let n=0; const iv=setInterval(()=\u0026gt;{ report(); if(++n\u0026gt;10) clearInterval(iv); },1200);\n})();\n\u0026lt;\/script\u0026gt;\n\u0026lt;\/body\u0026gt;\n\u0026lt;\/html\u0026gt;\n\"\u003e\u003c\/iframe\u003e\n\u003c\/div\u003e\n\u003cstyle\u003e\n.lowpro-frame{height:775px}\n@media(max-width:840px){\n  .lowpro-cta{display:none}\n  .lowpro-frame{height:790px}\n}\n\u003c\/style\u003e\n\u003cscript\u003e\nwindow.addEventListener(\"message\",function(e){\n  if(e.data \u0026\u0026 e.data.type===\"lowpro-player-height\"){\n    var f=document.getElementById(\"lowpro-player-frame\");\n    if(f \u0026\u0026 e.data.height\u003e200) f.style.height=(e.data.height+4)+\"px\";\n  }\n});\n\u003c\/script\u003e\n\u003cdiv style=\"height:28px;\"\u003e \u003c\/div\u003e\n\u003c!-- Intro Section --\u003e\n\u003cp\u003e\u003cstrong\u003eBuilt for emergency response teams and public safety professionals, this high-intensity LED warning light bar delivers uncompromising performance in a sleek, durable design.\u003c\/strong\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp class=\"font-claude-response-body break-words whitespace-normal\" dir=\"ltr\"\u003eThe \u003cstrong\u003eBlack Oak 11\" Mini Low Pro Emergency LED Light Bar\u003c\/strong\u003e is engineered for maximum visibility, reliability, and user control in a compact, low-profile footprint. With ultra-bright LEDs, multiple selectable flash and strobe patterns, and a rugged, weather-sealed housing, this mini light bar makes sure your presence is known in any emergency or warning situation—day or night, rain or shine.\u003c\/p\u003e\n\u003cp class=\"font-claude-response-body break-words whitespace-normal\" dir=\"ltr\"\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp class=\"font-claude-response-body break-words whitespace-normal\" dir=\"ltr\"\u003eBuilt to withstand the demands of high-speed response, off-road utility, and work-site visibility, this 11-inch low-profile bar features a streamlined, aerodynamic frame and a universal mounting system for quick, easy installation on virtually any vehicle. Whether you're outfitting a patrol car, fire or EMS unit, tow truck, or utility vehicle, this mini emergency light bar delivers dependable warning performance where it matters most.\u003c\/p\u003e\n\u003cp class=\"font-claude-response-body break-words whitespace-normal\" dir=\"ltr\"\u003e \u003c\/p\u003e\n\u003c!-- TRUST STRIP --\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/Screenshot_2026-07-21_at_9.31.14_AM.png?v=1784641940\" alt=\"SAE J845 Certified, SAE J595 Class 1, IP69K Waterproof, Lifetime Warranty, -40F to +145F Rated, 50,000 Hour LEDs\" style=\"width: 100%; display: block; border-radius: 10px;\"\u003e\u003c\/p\u003e\n\u003c!-- SIZE SELECTOR --\u003e\n\u003cdiv style=\"margin: 4px 0 2px;\"\u003e\n\u003cp style=\"margin: 0 0 8px; font-weight: 600; font-size: 15px;\"\u003eAvailable sizes:\u003c\/p\u003e\n\u003cspan style=\"display: inline-block; background: #FFB300; color: #111; font-weight: bold; padding: 8px 14px; border-radius: 8px; margin: 0 6px 8px 0; font-size: 15px;\"\u003e11\"\u003c\/span\u003e \u003ca href=\"\/products\/new-17-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e17\"\u003c\/a\u003e \u003ca href=\"\/products\/new-30-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e30\"\u003c\/a\u003e \u003ca href=\"\/products\/new-43-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e43\"\u003c\/a\u003e \u003ca href=\"\/products\/low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e49\"\u003c\/a\u003e \u003ca href=\"\/products\/new-55-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e55\"\u003c\/a\u003e \u003ca href=\"\/products\/new-61-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e61\"\u003c\/a\u003e \u003ca href=\"\/products\/new-68-low-pro-emergency-light-bar\" style=\"display: inline-block; border: 2px solid #FFB300; color: #111; font-weight: bold; padding: 6px 12px; border-radius: 8px; margin: 0 6px 8px 0; text-decoration: none; font-size: 15px;\"\u003e68\"\u003c\/a\u003e\n\u003c\/div\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003c!-- Collapsable Sections --\u003e\n\u003cstyle\u003e\n#MainContent details {\n  border: 1px solid #ddd;\n  border-radius: 8px;\n  margin-bottom: 16px;\n  overflow: hidden;\n  background: #fff;\n  font-family: Arial, sans-serif;\n}\n#MainContent details summary {\n  display: flex;\n  justify-content: space-between;\n  align-items: center;\n  cursor: pointer;\n  padding: 14px 18px;\n  font-weight: 600;\n  font-size: 18px;\n  list-style: none;\n  background-color: #f9f9f9;\n  border-bottom: 1px solid #e0e0e0;\n  position: relative;\n}\n#MainContent details[open] summary {\n  background-color: #f1f1f1;\n}\n#MainContent details summary::after {\n  content: '+';\n  font-size: 20px;\n  font-weight: bold;\n  transition: transform 0.3s ease;\n}\n#MainContent details[open] summary::after {\n  content: '−';\n}\n#MainContent details .content {\n  padding: 16px 20px;\n  font-size: 16px;\n  line-height: 1.6;\n}\n\u003c\/style\u003e\n\u003cdetails\u003e\n\u003csummary\u003eFeatures\u003c\/summary\u003e\n\u003cdiv class=\"content\"\u003e\n\u003cul\u003e\n\u003cli\u003eLifetime Warranty\u003c\/li\u003e\n\u003cli\u003eSAE J845 Class 1 Certified\u003c\/li\u003e\n\u003cli\u003e360° visibility with dual-color ultra-bright LEDs\u003c\/li\u003e\n\u003cli\u003eSlim Low Profile design\u003c\/li\u003e\n\u003cli\u003e20 flash patterns with memory recall\u003c\/li\u003e\n\u003cli\u003eRugged, waterproof housing (IP69K rated)\u003c\/li\u003e\n\u003cli\u003eIntegrated controller with pattern cycling, cruise mode, and cut-off\n\u003cul\u003e\n\u003cli\u003eNote - this is built into the back of the \u003cspan style=\"text-decoration: underline;\"\u003esocket plug\u003c\/span\u003e\n\u003c\/li\u003e\n\u003cli\u003eThis bar \u003cspan style=\"text-decoration: underline;\"\u003edoes not\u003c\/span\u003e come with a standard controller!\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003c\/details\u003e\n\u003cdetails\u003e\n\u003csummary\u003eIn the Box\u003c\/summary\u003e\n\u003cdiv class=\"content\"\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cb\u003eLow Pro Light Bar\u003c\/b\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cb\u003eWiring\u003c\/b\u003e\u003c\/li\u003e\n\u003cli\u003e\u003cb\u003eMagnetic Feet\u003c\/b\u003e\u003c\/li\u003e\n\u003c\/ul\u003e\n\u003c\/div\u003e\n\u003c\/details\u003e\n\u003c!-- COMPLIANCE SECTION --\u003e\n\u003cdetails\u003e\n\u003csummary\u003eCompliance \u0026amp; Certifications\u003c\/summary\u003e\n\u003cdiv class=\"content\"\u003e\n\u003cp\u003e\u003cstrong\u003eMeets the standards your department requires.\u003c\/strong\u003e\u003c\/p\u003e\n\u003ctable class=\"spec-table\"\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth colspan=\"3\"\u003eCertification \u0026amp; Compliance\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eSAE J845\u003c\/th\u003e\n\u003ctd\u003e360° warning lamp photometric standard for light bars and beacons\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003eCertified\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eSAE J595 Class 1\u003c\/th\u003e\n\u003ctd\u003eHighest intensity class — approved for primary emergency vehicles (police, fire, EMS)\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003eCertified\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eIP69K\u003c\/th\u003e\n\u003ctd\u003eSealed against high-pressure washdown, salt, dust, and submersion\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003eRated\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eOperating Range\u003c\/th\u003e\n\u003ctd\u003eExtreme-climate duty\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e-40°F to +145°F\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eDuty Life\u003c\/th\u003e\n\u003ctd\u003eContinuous-duty LED modules\u003c\/td\u003e\n\u003ctd\u003e\u003cstrong\u003e50,000 hours\u003c\/strong\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003cp style=\"font-size: 13px; color: #666;\"\u003e\u003cem\u003eWarning-equipment regulations vary by state and jurisdiction. Verify color and mounting requirements with your local authority. Spec sheet PDF and certification documentation available on request for procurement offices.\u003c\/em\u003e\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/details\u003e\n\u003c!-- Image + Text Alternating Section --\u003e\n\u003cstyle\u003e\n.text-image-wrap {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  flex-wrap: wrap;\n  gap: 20px;\n  margin-bottom: 20px;\n}\n.text-image-wrap.text-image-right {\n  flex-direction: row-reverse;\n}\n.text-image-wrap .image-wrap {\n  flex: 1;\n  max-width: 500px;\n}\n.text-image-wrap .image-wrap img {\n  width: 100%;\n  height: auto;\n  max-height: 300px; \n  display: block;\n  object-fit: contain; \n}\n.text-image-wrap .text-wrap {\n  flex: 1;\n  min-width: 300px;\n}\n\u003c\/style\u003e\n\u003cdiv class=\"text-image-wrap text-image-right\"\u003e\n\u003cdiv class=\"image-wrap\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/255283_7703341170749_330031d5_da20_475f_887e_f1269d2ad248_1.jpg?v=1763495670\" alt=\"\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-wrap\"\u003e\n\u003ch3 class=\"text-title\"\u003eEmergency Bar + Work Light\u003c\/h3\u003e\n\u003cp class=\"text-content\"\u003eGet full 360° white-light illumination at the touch of a button. Perfect for reverse lighting, scene lighting, or any situation where you need powerful all-around visibility. It's a true dual-purpose feature you won't find on most emergency bars — and it comes standard on every one of ours.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"text-image-wrap\"\u003e\n\u003cdiv class=\"image-wrap\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/Low_Pro_Emergency_Bar_SAE_graphics.jpg?v=1758041472\" alt=\"\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-wrap\"\u003e\n\u003ch3 class=\"text-title\"\u003eBuilt Tough for Any Environment\u003c\/h3\u003e\n\u003cp class=\"text-content\"\u003eIP69K-rated waterproof housing and reinforced aluminum construction stand up to rain, snow, mud, and dust—ideal for police, fire, tow, or off-road response vehicles.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"text-image-wrap text-image-right\"\u003e\n\u003cdiv class=\"image-wrap\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/DSC00223.jpg?v=1754512314\" alt=\"\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-wrap\"\u003e\n\u003ch3 class=\"text-title\"\u003eFull 360° Warning Visibility\u003c\/h3\u003e\n\u003cp class=\"text-content\"\u003ePacked with high-output dual-color LEDs and side modules, this bar delivers all-angle visibility—ensuring you're seen from every direction, even in chaotic scenes or inclement weather.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"text-image-wrap\"\u003e\n\u003cdiv class=\"image-wrap\"\u003e\u003cimg src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/LPE_-_Driver_Side_Angle.jpg?v=1761226316\" alt=\"\"\u003e\u003c\/div\u003e\n\u003cdiv class=\"text-wrap\"\u003e\n\u003ch3 class=\"text-title\"\u003eSlim, Low-Profile Design\u003c\/h3\u003e\n\u003cp class=\"text-content\"\u003eEngineered to minimize wind resistance and visual bulk, this light bar features a sleek, aerodynamic frame that hugs your vehicle's roofline. The low-profile housing not only enhances fuel efficiency but also delivers a clean, professional look without compromising brightness or performance.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"text-image-wrap text-image-right\"\u003e\n\u003cdiv class=\"image-wrap\"\u003e\n\u003cp\u003e\u003cvideo width=\"100%\" height=\"auto\" muted=\"\" autoplay=\"autoplay\" loop=\"loop\" playsinline=\"\" controls=\"controls\"\u003e\u003csource src=\"https:\/\/cdn.shopify.com\/videos\/c\/o\/v\/4ec9ce848f5e4d2d8083da9daf4dbe78.mp4\" type=\"video\/mp4\"\u003eYour browser does not support the video tag.\u003c\/source\u003e\u003c\/video\u003e\u003c\/p\u003e\n\u003c\/div\u003e\n\u003cdiv class=\"text-wrap\"\u003e\n\u003ch3 class=\"text-title\"\u003e20 Flash Patterns with Smart Memory\u003c\/h3\u003e\n\u003cp class=\"text-content\"\u003eChoose from 20 user-selectable flash modes to fit any scenario. Built-in memory recall stores your last used setting for consistent deployment every time.\u003c\/p\u003e\n\u003c\/div\u003e\n\u003c\/div\u003e\n\u003c!-- HERO BANNER --\u003e\n\u003cp\u003e\u003cimg src=\"https:\/\/d8j0ntlcm91z4.cloudfront.net\/user_3G9nKxyaQsdrPdDsxWr4EcSl5FL\/hf_20260715_201038_0803a0cd-07a6-4508-9c7a-50d0230a94e3.png\" alt=\"Built to Code. Backed for Life. SAE J845 and J595 Class 1 compliant, IP69K sealed, lifetime warranty\" style=\"width: 100%; display: block; border-radius: 10px;\"\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003c!-- FLEET BLOCK --\u003e\n\u003cdiv style=\"padding: 8px 0; margin: 0 0 8px;\"\u003e\n\u003ch3 style=\"margin: 0 0 8px;\"\u003eOutfitting a Fleet?\u003c\/h3\u003e\n\u003cp style=\"margin: 0 0 14px; font-size: 16px; line-height: 1.6;\"\u003eVolume pricing on 5+ units, department POs accepted, W-9 on file, and spec sheets ready for your procurement office. From single patrol vehicles to full county fleets.\u003c\/p\u003e\n\u003ca href=\"\/pages\/fleet-pricing\" style=\"display: inline-block; background: #FFB300; color: #111; font-weight: bold; padding: 12px 22px; border-radius: 8px; text-decoration: none;\"\u003eRequest Fleet Pricing\u003c\/a\u003e\n\u003c\/div\u003e\n\u003c!-- Dimension --\u003e\u003c!-- Specs --\u003e\n\u003cp\u003e\u003cimg alt=\"\" src=\"https:\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/Black_Oak_-_Low_Pro_Emergency_Bar_-_All_Dimensions.jpg?v=1762971573\"\u003e\u003c\/p\u003e\n\u003ch5\u003eSpecs\u003c\/h5\u003e\n\u003cstyle\u003e\n  table.spec-table {\n    width: 100%;\n    border-collapse: collapse;\n    margin: 20px 0;\n    font-size: 15px;\n  }\n  table.spec-table th, table.spec-table td {\n    border: 1px solid #ccc;\n    padding: 10px;\n    text-align: left;\n  }\n  table.spec-table th {\n    background-color: #f7f7f7;\n    font-weight: 600;\n    width: 30%;\n  }\n  table.spec-table tr:hover {\n    background-color: #f2f2f2;\n  }\n  table.spec-table thead th {\n    background-color: #222;\n    color: #fff;\n    text-transform: uppercase;\n    letter-spacing: 0.5px;\n    text-align: center;\n  }\n\u003c\/style\u003e\n\u003ctable class=\"spec-table\"\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth colspan=\"2\"\u003ePower \u0026amp; Performance\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eTotal Wattage\u003c\/th\u003e\n\u003ctd\u003e168\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eTotal Amp Draw\u003c\/th\u003e\n\u003ctd\u003e13\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eOperating Voltage\u003c\/th\u003e\n\u003ctd\u003e10-30V DC\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eRaw Lumens\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eLED Diode Quantity\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eLED Chip\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eBeam Pattern\u003c\/th\u003e\n\u003ctd\u003eWide Angle\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eCertificate\u003c\/th\u003e\n\u003ctd\u003eSAE J845 \u0026amp; SAE J595 Class 1\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eMode\u003c\/th\u003e\n\u003ctd\u003e20 Flash Patterns\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth colspan=\"2\"\u003eDurability \u0026amp; Lifespan\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eLife Expectancy\u003c\/th\u003e\n\u003ctd\u003e50,000 Hours\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eOperating Temp\u003c\/th\u003e\n\u003ctd\u003e-40° to 145° F\u003cbr\u003e-40° to 62° C\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWaterproof Rating\u003c\/th\u003e\n\u003ctd\u003eIP69K\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWarranty\u003c\/th\u003e\n\u003ctd\u003eLimited Lifetime\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eGuarantee\u003c\/th\u003e\n\u003ctd\u003e30 Day Money Back\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth colspan=\"2\"\u003eWiring \u0026amp; Installation\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eCord Length From Light\u003c\/th\u003e\n\u003ctd\u003e9'\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWire Harness Included?\u003c\/th\u003e\n\u003ctd\u003eYes\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWire Harness Length\u003c\/th\u003e\n\u003ctd\u003e9'\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eWire Gauge\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eFuse Size\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eConnector Type\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eHole Size for Controller\u003c\/th\u003e\n\u003ctd\u003e\u003cbr\u003e\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eMounting Bolt Size\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth colspan=\"2\"\u003eGeneral\u003c\/th\u003e\n\u003c\/tr\u003e\n\u003c\/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003cth\u003eWeight\u003c\/th\u003e\n\u003ctd\u003e—\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003ctr\u003e\n\u003cth\u003eSKU\u003c\/th\u003e\n\u003ctd\u003eLP-E11-AW\u003c\/td\u003e\n\u003c\/tr\u003e\n\u003c\/tbody\u003e\n\u003c\/table\u003e\n\u003ch5\u003eFAQ\u003c\/h5\u003e\n\u003cp\u003e\u003cstrong\u003eWhat voltage and control systems does this light bar support?\u003c\/strong\u003e\u003cbr\u003eThis light bar operates on a 12 V–24 V DC power system and can be used with either push-button or wireless controllers. It's compatible with standard vehicle electrical systems, making installation straightforward for both fleet and individual applications.\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eHow durable is this light bar in harsh environments?\u003c\/strong\u003e\u003cbr\u003eThe Low Pro Emergency Light Bar is built with a rugged aluminum housing, sealed to an IP69K rating and tested to resist corrosion, vibration, and high-pressure water ingress. It's designed for demanding conditions—whether roadside, rescue, or commercial use—so you can rely on consistent performance when it counts.\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eWhat beam patterns and flash modes are included?\u003c\/strong\u003e\u003cbr\u003eA wide range of flash patterns is built into the unit—including warning, hazard, and full-output flasher modes—with memory recall so your last setting is retained even after power loss. You'll also find low-profile steady-burn mode useful for scene lighting and standby operations.\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eIs the light bar legal for use on public roads and emergency vehicles?\u003c\/strong\u003e\u003cbr\u003eYes. The unit meets SAE J595 Class 1 and other relevant emergency lighting standards for warning applications. However, regulations vary by jurisdiction, so we recommend checking your local laws before installation to ensure compliance with mounting height, color, and flash pattern requirements.\u003c\/p\u003e\n\u003cp\u003e\u003cbr\u003e\u003c\/p\u003e\n\u003cp\u003e\u003cstrong\u003eWhat's covered by the warranty?\u003c\/strong\u003e\u003cbr\u003eOur industry-leading lifetime warranty covers manufacturing defects, driver failures, and LED module performance. It does not cover damage caused by improper installation, extreme overuse beyond defined duty cycles, or wiring issues. For full warranty terms, please refer to our Warranty \u0026amp; Returns page.\u003c\/p\u003e","brand":"Black Oak LED","offers":[{"title":"Amber \u0026 White \/ Magnetic","offer_id":43435872878653,"sku":"LP-E11-AW","price":299.37,"currency_code":"USD","in_stock":true},{"title":"Amber \u0026 White \/ Headache Rack (X2)","offer_id":43558460162109,"sku":"LP-E11-AW","price":324.37,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0761\/3599\/files\/LowProEmergency-11-Side.png?v=1787078070","url":"https:\/\/www.blackoakled.com\/products\/11-mini-low-pro-emergency-light-bar","provider":"Black Oak LED","version":"1.0","type":"link"}