SVG element, dynamic color change - Need help

Node-red 5.0.8
Flowfuse dashboard 1.33.0
node.js 22.15.0

I would appreciate help in configuring @hotnipi "Yet another gauge aka 'Plums'" gauge, to dynamically change the value text color, linked to the value. The gauge is displaying wind gust speed and would like the value color to reflect the Beaufort scale.

The label, units, min, max, and segments colors have been customized but otherwise the code is unchanged from this post

Results of online search/research;
The text is a svg element and 'fill' is used to set/override the color.
Fill can be set as a variable from CSS using something like var(--svg-fill-color).
The color changing function cannot be in the svg section, as svg is not a programming language.
I believe the color changing function would be placed in the computed section of the script.

This is the end of my ability, I don't even know if i am on the right track.

What I have tried;
Set an id in the svg element.
Referenced the id from CSS.
Set the color (successfully) as a variable from CSS.

Can this goal be achieved? all of the examples I have found are static not dynamic.
How is the variable set from the function?
How is the function called from the html/svg code?
Is there a better way to accomplish this goal?

Please set me straight.

The document is long but useful to read

Guidance for solving your problem can be found at the end of the document.

Hint:
.... style.setProperty("--my-var" .....

Maybe also check out this forum post:

@TotallyInformation, thanks for the info. I did find online that svg.img require different method of changing the color. The svg in hotNipi is inline, therefor a correctly crafted CSS snipit will change the color. I have done this and verified it works.
@hotNipi I got the CSS variable to work, thanks for your tip. I created this function to equate speed values with colors:

            speedcolors:function(){
                const s = this.value;
                if (s <= 1){
                    return "#FFFFFF";
                }
                if (s > 1 && s <= 3){
                    return "#AEF1F9";
                }
                if (s > 3 && s <= 7){
                    return "#96F7DC";
                }
                if (s > 7 && s <= 12){
                    return "#96F7B4";
                }
                if (s > 12 && s <= 18){
                    return "#6FF46F";
                }
                if (s > 18 && s <= 24){
                    return "#73ED12";
                }
                if (s > 24 && s <= 31){
                    return "#A4ED12";
                }
                if (s > 31 && s <= 38){
                    return "#DAED12";
                }
                if (s > 38 && s <= 46){
                    return "#EDC212";
                }
                if (s > 46 && s <= 54){
                    return "#ED8F12";
                }
                if (s > 54 && s <= 63){
                    return "#ED6312";
                }
                if (s > 63 && s <= 72){
                    return "#ED2912";
                }
                if (s > 72 && s <= 100){
                    return "#D5102D";
                }
                if (s > 100){
                    return "#FF0068";
                }
            }

How do i change the CSS variable with this function, what am I missing?
Is that what the element.style.setProperty() is for?
If so, does it go at the end of the function?
This is my first attempt at javascript, excuse the beginner questions.
Also feel free to point out errors or omissions.

This is the way to change value of the CSS variable.

Where and how to use it?
It must be called every time when the change of the (measured/readed) value is significant enough to make the change. As there's not much workload, it is safe enough to call it every time when the actual value changes.

There is some sort of freedom where you define the CSS variable so that it still can be used down in hierarhy but still, the JavaScript can only change it if you have reference to the element where it is defined.

Changes i have made to your original gauge:
1. added an id to the element as shown below:

<text id="valuetext" class="value" y="88" x="50%" text-anchor="middle">{{formattedValue}}</text>

i did it this way due to their being more than one text elements, and this is the only one i want to change color.
2. added the following to the CSS style block:

    :root {
        --svg-fill-color: gold;
    }

    #valuetext {
        fill: var(--svg-fill-color);
    }

The variable works insofar as the text changed from white currentColor to the gold called out in the root CSS value.
3. added function shown a few posts back to equate this.value to a color.
NOTE: this.value is from your msg:function()

More questions:

element.style.setProperty("var(--svg-fill-color)","speedcolors");

the code above should replace the var(--svg-fill-color) with the output of the speedcolors:function is it formatted correctly?

Is a document.querySelector() required?

Regarding calling element.style.setProperty(), The most common way i have found is using addEventListener(), but that relies on user input.
The 'node chain' in use refreshes the page every 300 seconds with an automated injection.
I would like speed/color calculated when the page is refreshed, based on this where would you place element.style.setProperty()?

Thanks for your patience.

You define CSS variable for ":root"
:root is a pseudo-class that targets this top-level <html> element.
Refference in Javascript to that element is document.documentElement

So the syuntax is document.documentElement.style.setProperty("--svg-fill-color", this.speedcolors())

So in your example document. is similar to :root in as it refers to the top-level, documentElement. refers to the specific element.
You wrote the setProperty() value as this.speedcolors().
My understanding is that this. is used in a function to refer to itself, is that correct?

It'll be better for world if I don't try to explain the this in JavaScript. There are tons of free to read documents to examine. I saw the function you try to use, it does return color so it should work. But there's a lot of things what can be wrong. I'm really bad on blind debugging.

This is what I've got so far

<script>
    export default{
        data(){
            return {
                //define me here
                min:0,
                max:100,
                label:"Gusts",
                measurement:"Speed",
                unit:"MPH",
                majorDivision:10, // number of input units for each (numbered) major division
                minorDivision: 2, // number of input units for each minor division
                //sectors:[{start:0,end:20,color:"forestgreen"},{start:20,end:40,color:"skyblue"},{start:40,end:60,color:"gold"},{start:60,end:80,color:"#e99200"},{start:80,end:100,color:"red"}],
                valueDecimalPlaces: 1,
                majorDecimalPlaces:0,
                allowOverflow:true, // needle can travel over scale boundaries
                showUpdate:true,
                updateLabel:"Last update:",               
                
                //no need to change
                value:0,
                updateTime:0               
            }
        }
    }
</script>
<template>
    <div class="hn-sng">
        <div class="label">{{label}}</div>
        <svg ref="hn-gauge" width="100%" height="97.8%" viewBox="0 0 100 100">
            <g>
                <path v-for="(item, index) in sectors" :key="index" :ref="'sector-' + index" class="sector"
                    stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90"></path>
            </g>
            <g>
                <path class="tick-minor" :style="{'stroke-dasharray':minor }" pathLength="492" stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90" ></path>
                <path ref="arc" class="tick-major" :style="{'stroke-dasharray':major }" pathLength="246" stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90"></path>
            </g>
            <g>
                <text v-for="(item, index) in numbers" :key="index" class="num" text-anchor="middle" y="-37"
                    :style="`rotate: ${item.r}deg;`">{{item.n}}</text>
            </g>
            <g>
                <text class="measurement" y="75" x="50%" text-anchor="middle">{{measurement}}</text>
                <text class="unit" y="50" x="50%" text-anchor="middle">{{unit}}</text>
                <text id="valuetext" class="value" y="88" x="50%" text-anchor="middle">{{formattedValue}}</text>
                <!--<text v-if="showUpdate" ref="update" class="update" y="100" x="0"
                    text-anchor="left">{{formattedUpdate}}</text>-->
            </g>
            <g ref="o-needle" class="o-needle">
                <path d="M 0,0 -1.5,0 -0.25,-43 0.25,-43 1.5,0 z"></path>
                <circle cx="0" cy="0" r="3"></circle>
            </g>
        </svg>
    </div>
</template>

<script>
    export default{ 
        methods:{
            getElement: function(name,base){
                if(base){
                    return this.$refs[name]
                }
                return this.$refs[name][0]
            },
            validate: function(data){
                let ret                
                if(typeof data !== "number"){
                    ret = parseFloat(data)
                    if(isNaN(ret)){
                        console.log("BAD DATA! gauge id:",this.id,"data:",data)
                        return null
                    }
                }                    
                else{
                    ret = data
                }                
                return ret
            },
            range:function (n, p, r) {           
                if (p.maxIn > p.minIn) {
                    n = Math.min(n, p.maxIn)
                    n = Math.max(n, p.minIn)
                } else {
                    n = Math.min(n, p.minIn)
                    n = Math.max(n, p.maxIn)
                }
                if(r){
                    return Math.round(((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut);
                }
                return ((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut;
            },
            generateNumbers:function(min,max){               
               
                let nums = []
                let t = (max - min) / this.divisors.major;
                let i = min;
                let ro = -123
                let rp = 246 / this.divisors.major
               
                for (let e = 0; e < this.divisors.major + 1; ++e){
                    if(this.min > this.max){
                        nums.unshift({n: i.toFixed(this.majorDecimalPlaces),r: ro + (e * rp) })
                    }
                    else{
                        nums.push({n: i.toFixed(this.majorDecimalPlaces),r: ro + (e * rp) })
                    }
                    
                    i = parseFloat(i + t);                   
                }
                return nums 
            },
            sectorData:function(full){  

                let ret = []
                this.sectors.forEach((sector,idx) => {
                    let sec = {name:'sector-'+idx,color:sector.color}
                    const params = {minIn:this.min, maxIn:this.max, minOut:0, maxOut:full}
                    const start = this.range(sector.start,params,false)
                    const end = this.range(sector.end,params,false)
                    const pos = Math.min(start, end)
                    const span = Math.max(start, end) - pos
                    sec.css = `0 ${pos} ${span} var(--dash)`
                    ret.push(sec)
                })
                return ret
            },
            rotation:function(v){
                const overflow = this.allowOverflow ? (this.max-this.min) * 0.1 : 0
                const maxRotation = this.allowOverflow ? (123 * 1.2) : 123
                const min = this.min - overflow
                const max = this.max + overflow
                const params = {minIn:min, maxIn:max, minOut:-maxRotation, maxOut:maxRotation};
                if (v === null) {
                    v = Math.min(min, max)
                }
                return this.range(v,params,false) +'deg'          
            }

        },
        watch: {
            msg: function(){
                if(this.msg.payload != undefined){
                    this.value = this.validate(this.msg.payload)
                    this.updateTime = Date.now()                    
                    this.getElement('o-needle',true).style.rotate = this.rotation(this.value)                    
                }
            }
        },
        computed: {            
            formattedValue: function () {
                return this.value !== null ? this.value.toFixed(this.valueDecimalPlaces) : "---"
            },
            formattedUpdate:function (){
                return this.updateLabel+" "+this.time
            },
            time:function(){
                return new Intl.DateTimeFormat('default', {hour: 'numeric', minute: 'numeric',second: 'numeric'}).format(this.updateTime);
            },
            numbers:function(){
                return this.generateNumbers(this.min,this.max)
            },
            major:function(){
                return "2," + ((246 / this.divisors.major)-2)           
            },
            minor:function(){
                let step = 492 / this.divisors.major / this.divisors.minor
                let line = "0," + step + ","
                step --
                for(let i=0;i<this.divisors.minor-1;++i){
                    line += "1,"+step+","
                }
                line = line.slice(0, -1);

                return line
            },
            offset:function(){
                return -1
            },
            divisors:function(){
                let span
                if(this.max > this.min){
                    span = this.max - this.min
                }
                else{
                    span = this.min - this.max                
                }
                const mad = this.majorDivision <= 0 ? 1 : this.majorDivision;
                const mid = this.minorDivision <= 0 ? 1 : this.minorDivision;
                const ma = span / mad
                const mi = span / ma / mid
                return {major:ma,minor:mi}
            },
            //value text color to Beaufort Scale function
            speedcolors:function(){
                const s = this.value;
                if (s <= 1){
                    return "#FFFFFF";
                }
                if (s > 1 && s <= 3){
                    return "#AEF1F9";
                }
                if (s > 3 && s <= 7){
                    return "#96F7DC";
                }
                if (s > 7 && s <= 12){
                    return "#96F7B4";
                }
                if (s > 12 && s <= 18){
                    return "#6FF46F";
                }
                if (s > 18 && s <= 24){
                    return "#73ED12";
                }
                if (s > 24 && s <= 31){
                    return "#A4ED12";
                }
                if (s > 31 && s <= 38){
                    return "#DAED12";
                }
                if (s > 38 && s <= 46){
                    return "#EDC212";
                }
                if (s > 46 && s <= 54){
                    return "#ED8F12";
                }
                if (s > 54 && s <= 63){
                    return "#ED6312";
                }
                if (s > 63 && s <= 72){
                    return "#ED2912";
                }
                if (s > 72 && s <= 100){
                    return "#D5102D";
                }
                if (s > 100){
                    return "#FF0068";
                };
                document.documentElement.style.setProperty("var(--svg-fill-color)", this.speedcolors())
            },
        },
        mounted(){
           
            const dal = this.getElement('arc',true).getTotalLength()
            const sec = this.sectorData(dal)              
            const gauge = this.getElement('hn-gauge',true)
            gauge.style.setProperty('--dash',dal)
            // two lines added below
            const root = this.getElementById('valuetext')
            sec.forEach(s =>{
                const sector = this.getElement(s.name,false)
                sector.style.setProperty("stroke-dasharray",s.css)
                sector.style.setProperty("stroke",s.color)
            })
            this.getElement('o-needle',true).style.rotate = this.rotation(null)
            this.$nextTick(() => {
                this.getElement('o-needle',true).style.transition= "rotate .5s"
            })
        }
    }
</script>
<style>
    .hn-sng {
        position: relative;
        user-select: none;
    }

    .hn-sng .label {
        position: absolute;
        font-size: 1rem;
        color: currentColor;
        text-align: center;
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    .hn-sng .value {
        //fill: gold;
        font-weigth: 600;
    }

    :root {
        --svg-fill-color: gold;
    }

    #valuetext {
        fill: var(--svg-fill-color);
    }

    .hn-sng .unit {
        fill: currentColor;
        font-size: 0.6rem;
    }

    .hn-sng .measurement {
        fill: none;
        font-size: 0.5rem;
    }

    .hn-sng .update {
        fill: currentColor;
        fill-opacity: 0.6;
        font-size: 0.35rem;
    }

    .hn-sng .num {
        transform-origin: center 64.15%;
        transform: translate(50%, 64.15%);
        fill: currentColor;
        fill-opacity: 0.6;
        font-size: .35rem;
    }

    .hn-sng .tick-minor {       
        stroke-dashoffset: 0;
        fill: none;
        stroke: currentColor;
        stroke-opacity: 0.6;
    }

    .hn-sng .tick-major {
        stroke-dashoffset: 0.75;
        fill: none;
        stroke: currentColor;
    }

    .hn-sng .sector {
        fill: none;
        stroke: transparent;
    }
    .hn-sng .sector:first-of-type {
        stroke-dashoffset:-0.5;
    }

    .hn-sng .o-needle {
        transform-origin: center 64.15%;
        transform: translate(50%, 64.15%);
        transition: unset;
    }

    .hn-sng .o-needle path,
    .hn-sng .o-needle circle {
        fill: currentColor;
    }
</style>

Changes I made to your gauge:
line 13 - comment out
line 46 - added id="valuetext"
lines 195-241 - add speedcolors:function()
line 280 - comment out
lines 285-291 - added CSS

I believe I am missing a way to call the speedcolors:function()
Possibly missing more, I don't know.
Guidance would be great

The speedcolors function is built as computed property
Reasonable.
in taht case you don't need to call it as a function but have that property usage defined in component
Hwre's how:

<svg ref="hn-gauge" width="100%" height="97.8%" viewBox="0 0 100 100" :style="{'--svg-fill-color':speedcolors }">

And you defenetely need to remove the ... setProperty thingy completely

Thank you! - that did it!
I had tried adding a :style="" but inserted it in the text element. I didn't try it in the <svg line.

For any one who wants the gauge with a color value text, here is the code in its entirety:

<script>
    export default{
        data(){
            return {
                //define me here
                min:0,
                max:100,
                label:"Gusts",
                measurement:"Speed",
                unit:"MPH",
                majorDivision:10, // number of input units for each (numbered) major division
                minorDivision: 2, // number of input units for each minor division
                //sectors:[{start:0,end:1,color:"#FFFFFF"},
                    //{start:1,end:4,color:"#AEF1F9"},
                    //{start:4,end:8,color:"#96F7DC"},
                    //{start:8,end:13,color:"#96F7B4"},
                    //{start:13,end:19,color:"#6FF46F"},
                    //{start:19,end:25,color:"#73ED12"},
                    //{start:25,end:32,color:"#A4ED12"},
                    //{start:32,end:39,color:"#DAED12"},
                    //{start:39,end:47,color:"#EDC212"},
                    //{start:47,end:55,color:"#ED8F12"},
                    //{start:55,end:64,color:"#ED6312"},
                    //{start:64,end:73,color:"#ED2912"},
                    //{start:73,end:100,color:"#D5102D"}],
                valueDecimalPlaces: 1,
                majorDecimalPlaces:0,
                allowOverflow:true, // needle can travel over scale boundaries
                showUpdate:true,
                updateLabel:"Last update:",               
                
                //no need to change
                value:0,
                updateTime:0               
            }
        }
    }
</script>
<template>
    <div class="hn-sng">
        <div class="label">{{label}}</div>
        <svg ref="hn-gauge" width="100%" height="97.8%" viewBox="0 0 100 100" :style="{'--svg-fill-color':speedcolors }">
            <g>
                <path v-for="(item, index) in sectors" :key="index" :ref="'sector-' + index" class="sector"
                    stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90"></path>
            </g>
            <g>
                <path class="tick-minor" :style="{'stroke-dasharray':minor }" pathLength="492" stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90" ></path>
                <path ref="arc" class="tick-major" :style="{'stroke-dasharray':major }" pathLength="246" stroke-width="5" d="M 10 90 A 47.5 47.5 25 1 1 90 90"></path>
            </g>
            <g>
                <text v-for="(item, index) in numbers" :key="index" class="num" text-anchor="middle" y="-37"
                    :style="`rotate: ${item.r}deg;`">{{item.n}}</text>
            </g>
            <g>
                <text class="measurement" y="75" x="50%" text-anchor="middle">{{measurement}}</text>
                <text class="unit" y="50" x="50%" text-anchor="middle">{{unit}}</text>
                <text id="valuetext" class="value" y="88" x="50%" text-anchor="middle">{{formattedValue}}</text>
                <!--<text v-if="showUpdate" ref="update" class="update" y="100" x="0"
                    text-anchor="left">{{formattedUpdate}}</text>-->
            </g>
            <g ref="o-needle" class="o-needle">
                <path d="M 0,0 -1.5,0 -0.25,-43 0.25,-43 1.5,0 z"></path>
                <circle cx="0" cy="0" r="3"></circle>
            </g>
        </svg>
    </div>
</template>

<script>
    export default{ 
        methods:{
            getElement: function(name,base){
                if(base){
                    return this.$refs[name]
                }
                return this.$refs[name][0]
            },
            validate: function(data){
                let ret                
                if(typeof data !== "number"){
                    ret = parseFloat(data)
                    if(isNaN(ret)){
                        console.log("BAD DATA! gauge id:",this.id,"data:",data)
                        return null
                    }
                }                    
                else{
                    ret = data
                }                
                return ret
            },
            range:function (n, p, r) {           
                if (p.maxIn > p.minIn) {
                    n = Math.min(n, p.maxIn)
                    n = Math.max(n, p.minIn)
                } else {
                    n = Math.min(n, p.minIn)
                    n = Math.max(n, p.maxIn)
                }
                if(r){
                    return Math.round(((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut);
                }
                return ((n - p.minIn) / (p.maxIn - p.minIn) * (p.maxOut - p.minOut)) + p.minOut;
            },
            generateNumbers:function(min,max){               
               
                let nums = []
                let t = (max - min) / this.divisors.major;
                let i = min;
                let ro = -123
                let rp = 246 / this.divisors.major
               
                for (let e = 0; e < this.divisors.major + 1; ++e){
                    if(this.min > this.max){
                        nums.unshift({n: i.toFixed(this.majorDecimalPlaces),r: ro + (e * rp) })
                    }
                    else{
                        nums.push({n: i.toFixed(this.majorDecimalPlaces),r: ro + (e * rp) })
                    }
                    
                    i = parseFloat(i + t);                   
                }
                return nums 
            },
            sectorData:function(full){  

                let ret = []
                this.sectors.forEach((sector,idx) => {
                    let sec = {name:'sector-'+idx,color:sector.color}
                    const params = {minIn:this.min, maxIn:this.max, minOut:0, maxOut:full}
                    const start = this.range(sector.start,params,false)
                    const end = this.range(sector.end,params,false)
                    const pos = Math.min(start, end)
                    const span = Math.max(start, end) - pos
                    sec.css = `0 ${pos} ${span} var(--dash)`
                    ret.push(sec)
                })
                return ret
            },
            rotation:function(v){
                const overflow = this.allowOverflow ? (this.max-this.min) * 0.1 : 0
                const maxRotation = this.allowOverflow ? (123 * 1.2) : 123
                const min = this.min - overflow
                const max = this.max + overflow
                const params = {minIn:min, maxIn:max, minOut:-maxRotation, maxOut:maxRotation};
                if (v === null) {
                    v = Math.min(min, max)
                }
                return this.range(v,params,false) +'deg'          
            }

        },
        watch: {
            msg: function(){
                if(this.msg.payload != undefined){
                    this.value = this.validate(this.msg.payload)
                    this.updateTime = Date.now()                    
                    this.getElement('o-needle',true).style.rotate = this.rotation(this.value)                    
                }
            }
        },
        computed: {            
            formattedValue: function () {
                return this.value !== null ? this.value.toFixed(this.valueDecimalPlaces) : "---"
            },
            formattedUpdate:function (){
                return this.updateLabel+" "+this.time
            },
            time:function(){
                return new Intl.DateTimeFormat('default', {hour: 'numeric', minute: 'numeric',second: 'numeric'}).format(this.updateTime);
            },
            numbers:function(){
                return this.generateNumbers(this.min,this.max)
            },
            major:function(){
                return "2," + ((246 / this.divisors.major)-2)           
            },
            minor:function(){
                let step = 492 / this.divisors.major / this.divisors.minor
                let line = "0," + step + ","
                step --
                for(let i=0;i<this.divisors.minor-1;++i){
                    line += "1,"+step+","
                }
                line = line.slice(0, -1);

                return line
            },
            offset:function(){
                return -1
            },
            divisors:function(){
                let span
                if(this.max > this.min){
                    span = this.max - this.min
                }
                else{
                    span = this.min - this.max                
                }
                const mad = this.majorDivision <= 0 ? 1 : this.majorDivision;
                const mid = this.minorDivision <= 0 ? 1 : this.minorDivision;
                const ma = span / mad
                const mi = span / ma / mid
                return {major:ma,minor:mi}
            },
            speedcolors:function(color){
                const s = this.value;
                if (s <= 1){
                    return "#FFFFFF";
                }
                if (s > 1 && s <= 3){
                    return "#AEF1F9";
                }
                if (s > 3 && s <= 7){
                    return "#96F7DC";
                }
                if (s > 7 && s <= 12){
                    return "#96F7B4";
                }
                if (s > 12 && s <= 18){
                    return "#6FF46F";
                }
                if (s > 18 && s <= 24){
                    return "#73ED12";
                }
                if (s > 24 && s <= 31){
                    return "#A4ED12";
                }
                if (s > 31 && s <= 38){
                    return "#DAED12";
                }
                if (s > 38 && s <= 46){
                    return "#EDC212";
                }
                if (s > 46 && s <= 54){
                    return "#ED8F12";
                }
                if (s > 54 && s <= 63){
                    return "#ED6312";
                }
                if (s > 63 && s <= 72){
                    return "#ED2912";
                }
                if (s > 72 && s <= 100){
                    return "#D5102D";
                }
                if (s > 100){
                    return "#FF0068";
                }
            }
        },
        mounted(){
           
            const dal = this.getElement('arc',true).getTotalLength()
            const sec = this.sectorData(dal)              
            const gauge = this.getElement('hn-gauge',true)
            gauge.style.setProperty('--dash',dal)
           
            sec.forEach(s =>{
                const sector = this.getElement(s.name,false)
                sector.style.setProperty("stroke-dasharray",s.css)
                sector.style.setProperty("stroke",s.color)
            })
            this.getElement('o-needle',true).style.rotate = this.rotation(null)
            this.$nextTick(() => {
                this.getElement('o-needle',true).style.transition= "rotate .5s"
            })
        }
    }
</script>
<style>
    .hn-sng {
        position: relative;
        user-select: none;
    }

    .hn-sng .label {
        position: absolute;
        font-size: 1rem;
        color: currentColor;
        text-align: center;
        width: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    .hn-sng .value {
        //fill: currentColor;
        font-weigth: 600;
    }

    :root {
        --svg-fill-color: currentColor;
    }

/* Comment out the three lines below to return to white text */
    #valuetext {
        fill: var(--svg-fill-color);
    }

    .hn-sng .unit {
        fill: currentColor;
        font-size: 0.6rem;
    }

    .hn-sng .measurement {
        fill: none;
        font-size: 0.5rem;
    }

    .hn-sng .update {
        fill: currentColor;
        fill-opacity: 0.6;
        font-size: 0.35rem;
    }

    .hn-sng .num {
        transform-origin: center 64.15%;
        transform: translate(50%, 64.15%);
        fill: currentColor;
        fill-opacity: 0.6;
        font-size: .35rem;
    }

    .hn-sng .tick-minor {       
        stroke-dashoffset: 0;
        fill: none;
        stroke: currentColor;
        stroke-opacity: 0.6;
    }

    .hn-sng .tick-major {
        stroke-dashoffset: 0.75;
        fill: none;
        stroke: currentColor;
    }

    .hn-sng .sector {
        fill: none;
        stroke: transparent;
    }
    .hn-sng .sector:first-of-type {
        stroke-dashoffset:-0.5;
    }

    .hn-sng .o-needle {
        transform-origin: center 64.15%;
        transform: translate(50%, 64.15%);
        transition: unset;
    }

    .hn-sng .o-needle path,
    .hn-sng .o-needle circle {
        fill: currentColor;
    }
</style>

Credit for this goes to @hotNipi for the original code and the fix that made it work!

A few notes;
Uncomment the sectors: section to have the 'tic' ring colored, sector colors are defined here
The speedcolors:function(color) equates input value to color, text colors are defined here
comment out the #valuetext CSS section to return the value text to white

Have fun with it!