/**
 * Built-in preset face definitions.
 * Inspired by real iconic automotive gauge designs.
 * 18 main presets + 3 multi-value presets + 2 technical demos = 23 total.
 *
 * Available fonts: orbitron, russo, teko, rajdhani, mono, audiowide, dseg7, barlow, saira, play
 */
const PRESETS = [

// ── Round gauge styles ───────────────────────────────────────────────

{name:'Ferrari',author:'RevWatch',code:`@name "Ferrari"
@author "RevWatch"
# Classic tachometer — needle dominant, value at bottom, red zone
bg #00000000
circle 50 50 46 fill:#0A0A0A
circle 50 50 46 stroke:#DAA520 w:0.4 alpha:0.3
zone_arc 50 50 44 -225 270 3 normal:#1A1A1A warning:#2A200A danger:#3A0808
ticks 50 50 45 11 5.5 start:-225 sweep:270 stroke:#CCCCCC w:0.9
ticks 50 50 45 51 2.5 start:-225 sweep:270 stroke:#3A3A3A w:0.3
progress_arc 50 50 43 -225 270 stroke:#CC0000 w:2.5 cap:butt bg:#1A0808
needle 50 50 35 from:-225 sweep:270 w:1.2 color:#CC0000 tail:8 dot:3
circle 50 50 2.5 fill:#333333
text $value 50 64 size:13 bold color:#FFFFFF font:saira
text $unit 50 73 size:5 color:#DAA520 font:saira
if $zone==danger {
  circle 50 50 46 stroke:#FF0000 w:0.6 alpha:0.4 blink:500
}`},

{name:'Porsche',author:'RevWatch',code:`@name "Porsche"
@author "RevWatch"
# Green backlit, NO progress arc, just ticks + needle + center text
bg #00000000
circle 50 50 46 fill:#080A08
circle 50 50 46 stroke:#004D25 w:0.3
ticks 50 50 45 11 6 start:-225 sweep:270 stroke:#00CC66 w:0.8
ticks 50 50 45 51 2.5 start:-225 sweep:270 stroke:#0A3A1A w:0.3
needle 50 50 36 from:-225 sweep:270 w:0.7 color:#FFFFFF tail:8 cap:round dot:2.5
circle 50 50 2 fill:#00CC66
text $value 50 44 size:16 bold color:#00FF77 font:barlow glow:3 glow_color:#00CC66
text $unit 50 56 size:6 color:#006633 font:barlow`},

{name:'BMW',author:'RevWatch',code:`@name "BMW"
@author "RevWatch"
# Thick orange filled ring progress, not thin arc
bg #00000000
circle 50 50 46 fill:#111111
circle 50 50 46 stroke:#2A2A2A w:0.5
progress_ring 50 50 46 40 -225 270 fill:#FF6600 bg:#1A1208 alpha:0.4
ticks 50 50 47 11 5 start:-225 sweep:270 stroke:#CCCCCC w:0.8
ticks 50 50 47 51 2 start:-225 sweep:270 stroke:#333333 w:0.3
needle 50 50 32 from:-225 sweep:270 w:1.3 color:#FF6600 tail:7 dot:3
circle 50 50 2.5 fill:#444444
text $value 50 44 size:16 bold color:#FFFFFF font:barlow
text $unit 50 55 size:5 color:#888888 font:barlow`},

{name:'Mercedes',author:'RevWatch',code:`@name "Mercedes"
@author "RevWatch"
# Full 360° ring progress, ultra minimal, no ticks/needle
bg #00000000
circle 50 50 46 fill:#0A0A0C
progress_arc 50 50 44 -90 360 stroke:#FFFFFF w:1.5 cap:round bg:#151518
gradient_ring 50 50 46 44 -90 360 36 from:#0A0A0C to:$accent alpha:0.08
circle 50 50 40 stroke:#1A1A1E w:0.2
text $value 50 44 size:24 bold color:#FFFFFF font:rajdhani
text $unit 50 58 size:7 color:#555555 font:rajdhani
text $label 50 72 size:3.5 color:#333333 font:rajdhani`},

{name:'Alfa Romeo',author:'RevWatch',code:`@name "Alfa Romeo"
@author "RevWatch"
# Half circle bottom arc (180°), big value at top
bg #00000000
circle 50 50 46 fill:#120808 alpha:0.5
progress_arc 50 80 36 180 180 stroke:#8B0000 w:3 cap:round bg:#1A0808
zone_arc 50 80 38 180 180 1 normal:#1A0A0A warning:#2A1A08 danger:#3A0A0A
ticks 50 80 36 9 3 start:180 sweep:180 stroke:#C89878 w:0.5
text $value 50 38 size:28 bold color:#E8D0B0 font:saira
text $unit 50 54 size:8 color:#8B5A3A font:saira
text $label 50 92 size:3.5 color:#4A2020 font:saira`},

{name:'RX-7',author:'RevWatch',code:`@name "RX-7"
@author "RevWatch"
# No background circle — floating elements, minimal
bg #00000000
progress_arc 50 50 44 -225 270 stroke:#FFFFFF w:1.5 cap:butt bg:#111111
ticks 50 50 44 11 4 start:-225 sweep:270 stroke:#DDDDDD w:0.6
needle 50 50 36 from:-225 sweep:270 w:0.7 color:#FFFFFF tail:5 dot:1.5
text $value 50 44 size:20 bold color:#FFFFFF font:teko
text $unit 50 56 size:6 color:#555555 font:teko`},

{name:'Defi',author:'RevWatch',code:`@name "Defi"
@author "RevWatch"
# Thick cyan arc (w:5) dominates, value center with glow
bg #00000000
circle 50 50 46 fill:#081520
circle 50 50 46 stroke:#1A3050 w:0.5
progress_arc 50 50 43 -225 270 stroke:#00AAFF w:5 cap:butt bg:#0D1A2A
ticks 50 50 47 11 4 start:-225 sweep:270 stroke:#406080 w:0.8
ticks 50 50 47 51 2 start:-225 sweep:270 stroke:#182838 w:0.3
text $value 50 44 size:22 bold color:#00CCFF font:orbitron glow:3 glow_color:#00AAFF
text $unit 50 58 size:7 color:#406080 font:rajdhani
text $min 18 74 size:3 color:#203040
text $max 82 74 size:3 color:#203040`},

// ── Round animated ───────────────────────────────────────────────────

{name:'Nismo',author:'RevWatch',tags:['@var'],code:`@name "Nismo"
@author "RevWatch"
# Sweep ticks (wide LED segments) as main progress, no arc
@var $ring_a = lerp(0.15, 0.6, $progress)
@var $txt_size = lerp(18, 26, $progress)
bg #00000000
circle 50 50 46 fill:#1A0808
circle 50 50 46 stroke:#330808 w:0.5
sweep_ticks 50 50 46 36 5 start:-225 sweep:270 on:#FF0000 off:#1A0808 w:4 cap:round
circle 50 50 38 stroke:#2A0808 w:0.3
text $value 50 44 size:$txt_size bold color:#FF2222 font:russo
text $unit 50 58 size:6 color:#882222 font:russo`},

{name:'Plasma',author:'RevWatch',tags:['$time','@var'],code:`@name "Plasma"
@author "RevWatch"
# Rotating arc segments, value_dot on progress
@var $t = $time
@var $glow_a = lerp(0.15, 0.5, abs(sin($t * 80)))
@var $ring_rot = mod($t * 30, 360)
bg #00000000
circle 50 50 46 fill:#050510
progress_arc 50 50 43 -225 270 stroke:$accent w:3 cap:round bg:#0A0A15
arc 50 50 47 $ring_rot 60 stroke:$accent w:0.8 alpha:$glow_a
arc 50 50 47 $ring_rot+180 60 stroke:$accent w:0.8 alpha:$glow_a
value_dot 50 50 43 -225 270 3 fill:$accent glow:6 glow_color:$accent
text $value 50 44 size:20 bold color:#FFFFFF font:orbitron
text $unit 50 58 size:7 color:#666688 font:rajdhani`},

{name:'Vortex',author:'RevWatch',tags:['$time','@var','sin','cos'],code:`@name "Vortex"
@author "RevWatch"
# Orbiting dots with arc trails, no ticks/arc
@var $spd = lerp(10, 80, $progress)
@var $a1 = mod($time * $spd, 360)
@var $a2 = mod($time * $spd + 120, 360)
@var $a3 = mod($time * $spd + 240, 360)
@var $ox1 = 50 + cos($a1) * 38
@var $oy1 = 50 + sin($a1) * 38
@var $ox2 = 50 + cos($a2) * 38
@var $oy2 = 50 + sin($a2) * 38
@var $ox3 = 50 + cos($a3) * 38
@var $oy3 = 50 + sin($a3) * 38
@var $trail_a = lerp(0.05, 0.3, $progress)
bg #00000000
circle 50 50 46 fill:#080808
arc 50 50 38 $a1-40 40 stroke:$accent w:0.5 alpha:$trail_a
arc 50 50 38 $a2-40 40 stroke:$accent w:0.5 alpha:$trail_a
arc 50 50 38 $a3-40 40 stroke:$accent w:0.5 alpha:$trail_a
dot $ox1 $oy1 2.5 fill:$accent glow:8 glow_color:$accent
dot $ox2 $oy2 2.5 fill:$accent glow:8 glow_color:$accent
dot $ox3 $oy3 2.5 fill:$accent glow:8 glow_color:$accent
text $value 50 44 size:22 bold color:#FFFFFF font:orbitron
text $unit 50 58 size:7 color:#555555 font:rajdhani`},

// ── Square gauge styles ──────────────────────────────────────────────

{name:'GT-R',author:'RevWatch',tags:['@var','conditions','blink'],code:`@name "GT-R"
@author "RevWatch"
# Horizontal split — dseg7 top, digital bars + progress bottom
@var $pct = round($progress * 100)
bg #00000000
rect 2 2 96 96 fill:#080808 corner:3
rect 2 2 96 96 stroke:#222222 corner:3 sw:0.3
line 2 48 98 48 stroke:#1A1A1A w:0.2
text $value 50 28 size:32 bold color:#FFFFFF font:dseg7
text $unit 84 28 size:7 color:#FF4444 align:right font:mono
digital_bar 8 54 84 6 20 1 fill:#FF2020 bg:#150808 corner:0.3
progress_bar 8 68 84 3 fill:#FF2020 bg:#150808 corner:0.3
text $pct 8 76 size:3 color:#551111 align:left font:mono
text $label 50 86 size:3.5 color:#333333 font:mono
text $min 8 92 size:2.5 color:#333333 align:left font:mono
text $max 92 92 size:2.5 color:#333333 align:right font:mono
if $zone==danger {
  rect 2 2 96 96 stroke:#FF2020 corner:3 sw:1 alpha:0.5 blink:400
}`},

{name:'Type-R',author:'RevWatch',tags:['@var','conditions','blink'],code:`@name "Type-R"
@author "RevWatch"
# Red bar TOP (full width), big value center, digital_bar bottom
@var $pct = round($progress * 100)
bg #00000000
rect 0 0 100 100 fill:#0A0404 corner:5
rect 1 1 98 98 stroke:#2A0808 corner:4.5 sw:0.3
progress_bar 0 0 100 3 fill:#CC0000 bg:#1A0404
text $value 50 40 size:34 bold color:#FFFFFF font:russo
text $unit 50 58 size:10 color:#CC0000 font:russo
digital_bar 8 72 84 5 12 1.5 fill:#CC0000 bg:#1A0404 corner:0.3
text $pct 50 86 size:5 bold color:#882222 font:mono
if $zone==danger {
  rect 1 1 98 98 stroke:#FF0000 corner:4.5 sw:1 alpha:0.6 blink:300
  text "REV LIMIT" 50 86 size:5 bold color:#FF0000 blink:300 font:mono
}`},

{name:'Lambo',author:'RevWatch',tags:['@var','conditions','blink'],code:`@name "Lambo"
@author "RevWatch"
# Hexagonal outlines — no rect, unique hex silhouette
@var $hex_a = lerp(0.05, 0.25, $progress)
@var $inner_a = lerp(0.03, 0.12, $progress)
bg #00000000
polygon 50 50 49 6 rotation:-90 fill:#080804
polygon 50 50 49 6 rotation:-90 stroke:#FFD700 w:0.5 alpha:$hex_a
polygon 50 50 38 6 rotation:-90 stroke:#FFD700 w:0.3 alpha:$inner_a
polygon 50 50 26 6 rotation:-90 stroke:#FFD700 w:0.2 alpha:0.04
progress_arc 50 50 44 -90 360 stroke:#FFD700 w:2 cap:butt bg:#1A1A08 alpha:0.5
text $value 50 44 size:26 bold color:#FFD700 font:orbitron
text $unit 50 60 size:8 color:#8B7500 font:orbitron
if $zone==danger {
  polygon 50 50 49 6 rotation:-90 stroke:#FF4400 w:1 alpha:0.5 blink:400
}`},

{name:'Audi',author:'RevWatch',code:`@name "Audi"
@author "RevWatch"
# Ultra minimal — just thin line + value, almost empty
bg #00000000
rect 0 0 100 100 fill:#0A0A0C corner:5
progress_bar 10 68 80 1 fill:$accent bg:#1A1A1E corner:0.3
text $value 50 42 size:34 bold color:#FFFFFF font:play
text $unit 50 58 size:9 color:#444448 font:play
text $min 10 64 size:2.5 color:#2A2A2E align:left font:play
text $max 90 64 size:2.5 color:#2A2A2E align:right font:play`},

{name:'Defender',author:'RevWatch',tags:['@var','conditions','blink'],code:`@name "Defender"
@author "RevWatch"
# 3 stacked bars different widths — cascade pattern, military
@var $pct = round($progress * 100)
bg #00000000
rect 0 0 100 100 fill:#040804 corner:3
rect 2 2 96 96 stroke:#1A3A1A w:0.3 corner:2
text $label 10 14 size:4 color:#1A5A2A align:left font:mono
text $pct 90 14 size:4 bold color:#33AA44 align:right font:mono
progress_bar 8 20 84 5 fill:#33AA44 bg:#0A1A0A corner:0.5
progress_bar 8 30 64 3 fill:#228833 bg:#0A1A0A corner:0.3 alpha:0.6
progress_bar 8 38 44 2 fill:#1A6628 bg:#0A1A0A corner:0.2 alpha:0.4
text $value 50 58 size:28 bold color:#44CC55 font:mono
text $unit 50 72 size:10 color:#1A5A2A font:mono
text $min 8 88 size:3 color:#1A3A1A align:left font:mono
text $max 92 88 size:3 color:#1A3A1A align:right font:mono
if $zone==danger {
  rect 2 2 96 96 stroke:#FF4444 corner:2 sw:1 alpha:0.5 blink:500
  text "WARN" 90 88 size:3.5 bold color:#FF4444 align:right font:mono blink:500
}`},

{name:'Shelby',author:'RevWatch',tags:['@var','conditions','blink'],code:`@name "Shelby"
@author "RevWatch"
# Vertical split — value left, vertical bar right, asymmetric
@var $pct = round($progress * 100)
bg #00000000
rect 0 0 100 100 fill:#060810 corner:5
rect 1 1 98 98 stroke:#0A2040 corner:4.5 sw:0.3
line 68 6 68 94 stroke:#0057B8 w:0.3 alpha:0.3
progress_bar 74 8 16 84 dir:up fill:#0057B8 bg:#0A1020 corner:0.5
text $value 36 40 size:30 bold color:#FFFFFF font:teko align:center
text $unit 36 56 size:10 color:#0077CC font:teko align:center
text $label 36 70 size:4 color:#0A2040 font:mono align:center
text $pct 82 92 size:4 bold color:#0057B8 font:mono align:center
digital_bar 8 6 56 4 8 1.5 fill:$zone_color bg:#0A1020 corner:0.3
if $zone==danger {
  rect 1 1 98 98 stroke:#FF3333 corner:4.5 sw:1 alpha:0.5 blink:400
}`},

// ── Specialized ──────────────────────────────────────────────────────

{name:'Turbo',author:'RevWatch',tags:['boost','@var'],code:`@name "Turbo"
@author "RevWatch"
bg #00000000
@var $psi = round($raw * 0.145 * 10) / 10
@var $bar = round($raw * 0.01 * 100) / 100

circle 50 50 46 fill:#081020
circle 50 50 46 stroke:#1A2A4A w:0.5
ticks 49.8 50.0 46 11 5 start:-225 sweep:270 stroke:#335577 w:0.6
progress_arc 50 50 42 -225 270 stroke:#42A5F5 w:3 cap:round bg:#0D1520
text $value 54 36.0 size:16 bold color:#FFFFFF align:right font:orbitron
text $unit 60 36 size:6 color:#42A5F5 align:left font:rajdhani
text $psi 54 50.0 size:11 color:#42A5F5 align:right font:orbitron
text "PSI" 60 50 size:5 color:#335577 align:left font:rajdhani
text $bar 54 62 size:9 color:#556688 align:right font:orbitron
text "bar" 60 62 size:4 color:#334455 align:left font:rajdhani
text $min 18 78 size:3 color:#223344
text $max 82 78 size:3 color:#223344
text TURBO 50.0 89 size:5.0 font:orbitron align:center color:#42A5F5`},

{name:'Thermo',author:'RevWatch',tags:['temperature','iif','blink'],code:`@name "Thermo"
@author "RevWatch"
# Vertical thermometer with zone status
bg #00000000
rect 16 10 6 80 stroke:#1A1A1A sw:0.3 corner:1
progress_bar 16 10 6 80 dir:up fill:$zone_color bg:#0D0D0D corner:1
line 24 10 27 10 stroke:#444444 w:0.3
line 24 50 27 50 stroke:#444444 w:0.3
line 24 90 27 90 stroke:#444444 w:0.3
text $max 28 10 size:3 color:#555555 align:left
text $min 28 90 size:3 color:#555555 align:left
text $value 62 40 size:26 bold color:#FFFFFF font:rajdhani
text $unit 62 56 size:9 color:#888888 font:rajdhani
text $label 62 72 size:4 color:#444444
circle 19 88 3 fill:iif($zone==danger,#FF4444,iif($zone==warning,#FFD700,#66BB6A)) alpha:iif($zone==danger,0.6,iif($zone==warning,0.5,0.4))
text iif($zone==danger,SURCHAUFFE,iif($zone==warning,ATTENTION,OK)) 62 82 size:iif($zone==danger,3.5,4) bold color:iif($zone==danger,#FF4444,iif($zone==warning,#FFD700,#66BB6A)) font:mono blink:iif($zone==danger,400,iif($zone==warning,800,0))`},

// ── Multi-value presets ──────────────────────────────────────────────

{name:'Cockpit',author:'RevWatch',tags:['multi-value'],code:`@name "Cockpit"
@author "RevWatch"
bg #00000000
# Main gauge — arc + needle driven by primary binding
circle 50 50 46 fill:#0A0A0F
circle 50 50 46 stroke:#222233 w:0.4
zone_arc 50 50 44 -225 270 3 normal:#111118 warning:#2A200A danger:#3A0808
ticks 50 50 45 11 5 start:-225 sweep:270 stroke:#AAAAAA w:0.7
progress_arc 50 50 42 -225 270 stroke:$accent w:2.5 cap:butt bg:#0D0D14
needle 50 50 34 from:-225 sweep:270 w:1.2 color:$accent tail:8 dot:2.5
circle 50 50 2 fill:#333344
text $value 50 66 size:11 bold color:#FFFFFF font:saira
text $unit 50 74 size:4.5 color:$accent font:saira

# Secondary data — digital readout in bottom-left corner
# Requires 1 extra data binding: uses $value-1, $label-1, $unit-1, $accent-1
rect 4 78 32 18 fill:#0D0D14 corner:2 stroke:#1A1A2A sw:0.3
text $label-1 20 83 size:3 color:#555566 font:mono
text $value-1 20 92 size:8 bold color:$accent-1 font:saira
text $unit-1 34 92 size:3.5 color:#666677 align:left font:saira`},

{name:'Duo',author:'RevWatch',tags:['multi-value','@var'],code:`@name "Duo"
@author "RevWatch"
bg #00000000

# Background
circle 50 50 46 fill:#080810

# Primary gauge — outer arc
progress_arc 50 50 44 -225 270 stroke:$accent w:3.5 cap:round bg:#111118
ticks 50 50 46 11 3 start:-225 sweep:270 stroke:#444455 w:0.4
text $value 50 34 size:16 bold color:#FFFFFF font:orbitron
text $unit 50 44 size:5 color:$accent font:rajdhani
text $label 50 52 size:3.5 color:#444455 font:rajdhani

# Secondary gauge — inner arc (sweep driven by $progress-1)
# Requires 1 extra data binding
@var $sweep2 = 270 * $progress-1
arc 50 50 34 -225 0.01 stroke:#0D0D14 w:2
arc 50 50 34 -225 $sweep2 stroke:$accent-1 w:2 cap:round
text $value-1 50 68 size:10 color:$accent-1 font:orbitron
text $unit-1 50 76 size:4 color:#335577 font:rajdhani
text $label-1 50 82 size:3 color:#334455 font:rajdhani`},

{name:'HUD Multi',author:'RevWatch',tags:['multi-value','@var','conditions','blink'],code:`@name "HUD Multi"
@author "RevWatch"
bg #00000000
@var $pct = round($progress * 100)

# Background
rect 0 0 100 100 fill:#060810 corner:4
rect 1 1 98 98 stroke:#0A1530 corner:3.5 sw:0.3

# Primary data — large digital display + progress bar
text $value 50 32 size:32 bold color:#FFFFFF font:dseg7
text $unit 90 30 size:7 color:$accent align:right font:mono
text $label 10 30 size:4 color:#334455 align:left font:mono
progress_bar 6 42 88 4 fill:$accent bg:#0D1020 corner:0.5
text $pct 50 52 size:3 color:#334455 font:mono

# Separator
line 6 58 94 58 stroke:#0A1530 w:0.3

# Secondary data row 1 — requires 1 extra binding: $value-1, $label-1, $unit-1, $accent-1
rect 6 62 42 16 fill:#0A0E18 corner:2
text $label-1 12 66 size:3 color:#556677 align:left font:mono
text $value-1 27 75 size:10 bold color:$accent-1 font:orbitron
text $unit-1 43 75 size:4 color:#335577 align:left font:rajdhani

# Secondary data row 2 — requires 2 extra bindings: $value-2, $label-2, $unit-2, $accent-2
rect 52 62 42 16 fill:#0A0E18 corner:2
text $label-2 58 66 size:3 color:#556677 align:left font:mono
text $value-2 73 75 size:10 bold color:$accent-2 font:orbitron
text $unit-2 89 75 size:4 color:#335577 align:left font:rajdhani

# Bottom bar
digital_bar 6 84 88 5 12 1.5 fill:$zone_color bg:#0D1020 corner:0.3
if $zone==danger {
  rect 1 1 98 98 stroke:#FF3333 corner:3.5 sw:1 alpha:0.5 blink:400
}`},

// ── Technical demos ──────────────────────────────────────────────────

{name:'3D Cube',author:'OBD Dash',tags:['sin','cos','3D'],code:`@name "3D Cube"
@author "OBD Dash"
# Wireframe cube — uses sin/cos for real 3D rotation
# $progress controls Y rotation, slight X tilt for depth
bg #080810

# ── Rotation parameters ──
@var $a = $progress * 360
@var $ca = cos($a)
@var $sa = sin($a)
@var $tilt = 25
@var $ct = cos($tilt)
@var $st = sin($tilt)
@var $d = 5
@var $s = 16

# ── 8 projected vertices ──
# Top face (y=+1): V0(+,+,+) V1(-,+,+) V2(-,+,-) V3(+,+,-)
@var $x0 = ($ca - $sa) * $d / ($st + ($sa + $ca) * $ct + $d) * $s + 50
@var $y0 = ($ct - ($sa + $ca) * $st) * $d / ($st + ($sa + $ca) * $ct + $d) * $s + 50
@var $x1 = (0 - $ca - $sa) * $d / ($st + (0 - $sa + $ca) * $ct + $d) * $s + 50
@var $y1 = ($ct - (0 - $sa + $ca) * $st) * $d / ($st + (0 - $sa + $ca) * $ct + $d) * $s + 50
@var $x2 = (0 - $ca + $sa) * $d / ($st + (0 - $sa - $ca) * $ct + $d) * $s + 50
@var $y2 = ($ct - (0 - $sa - $ca) * $st) * $d / ($st + (0 - $sa - $ca) * $ct + $d) * $s + 50
@var $x3 = ($ca + $sa) * $d / ($st + ($sa - $ca) * $ct + $d) * $s + 50
@var $y3 = ($ct - ($sa - $ca) * $st) * $d / ($st + ($sa - $ca) * $ct + $d) * $s + 50
# Bottom face (y=-1): V4(+,-,+) V5(-,-,+) V6(-,-,-) V7(+,-,-)
@var $x4 = ($ca - $sa) * $d / (0 - $st + ($sa + $ca) * $ct + $d) * $s + 50
@var $y4 = (0 - $ct - ($sa + $ca) * $st) * $d / (0 - $st + ($sa + $ca) * $ct + $d) * $s + 50
@var $x5 = (0 - $ca - $sa) * $d / (0 - $st + (0 - $sa + $ca) * $ct + $d) * $s + 50
@var $y5 = (0 - $ct - (0 - $sa + $ca) * $st) * $d / (0 - $st + (0 - $sa + $ca) * $ct + $d) * $s + 50
@var $x6 = (0 - $ca + $sa) * $d / (0 - $st + (0 - $sa - $ca) * $ct + $d) * $s + 50
@var $y6 = (0 - $ct - (0 - $sa - $ca) * $st) * $d / (0 - $st + (0 - $sa - $ca) * $ct + $d) * $s + 50
@var $x7 = ($ca + $sa) * $d / (0 - $st + ($sa - $ca) * $ct + $d) * $s + 50
@var $y7 = (0 - $ct - ($sa - $ca) * $st) * $d / (0 - $st + ($sa - $ca) * $ct + $d) * $s + 50

# ── Ground crosshair ──
line 50 85 50 90 stroke:#1a1a2e w:0.5
line 35 88 65 88 stroke:#1a1a2e w:0.5

# ── Bottom face edges (dim) ──
line $x4 $y4 $x5 $y5 stroke:#334155 w:1.5
line $x5 $y5 $x6 $y6 stroke:#334155 w:1.5
line $x6 $y6 $x7 $y7 stroke:#334155 w:1.5
line $x7 $y7 $x4 $y4 stroke:#334155 w:1.5

# ── Vertical edges ──
line $x0 $y0 $x4 $y4 stroke:#4FC3F7 w:1.5 alpha:0.4
line $x1 $y1 $x5 $y5 stroke:#4FC3F7 w:1.5 alpha:0.4
line $x2 $y2 $x6 $y6 stroke:#4FC3F7 w:1.5 alpha:0.4
line $x3 $y3 $x7 $y7 stroke:#4FC3F7 w:1.5 alpha:0.4

# ── Top face edges (bright) ──
line $x0 $y0 $x1 $y1 stroke:#4FC3F7 w:1.5
line $x1 $y1 $x2 $y2 stroke:#4FC3F7 w:1.5
line $x2 $y2 $x3 $y3 stroke:#4FC3F7 w:1.5
line $x3 $y3 $x0 $y0 stroke:#4FC3F7 w:1.5

# ── Vertex dots ──
circle $x0 $y0 0.8 fill:#4FC3F7
circle $x1 $y1 0.8 fill:#4FC3F7
circle $x2 $y2 0.8 fill:#4FC3F7
circle $x3 $y3 0.8 fill:#4FC3F7
circle $x4 $y4 0.6 fill:#334155
circle $x5 $y5 0.6 fill:#334155
circle $x6 $y6 0.6 fill:#334155
circle $x7 $y7 0.6 fill:#334155

# ── HUD overlay ──
text $value 50 50 size:18 bold color:#FFFFFF font:orbitron
text $unit 50 62 size:6 color:#4FC3F7 font:mono
text $label 50 10 size:4 color:#334155 font:mono`}

,{name:'Singularity',author:'OBD Dash',tags:['sin','cos','3D','@var','iif','$time'],code:`@name "Singularity"
@author "OBD Dash"
# 3D holographic reactor — true perspective projection, dual gyroscope rings
# Perspective angle shifts with gauge value, continuous rotation via $time
bg #030308

# ── 3D projection engine ──
@var $t = mod($time * 50, 360)
@var $t2 = mod($time * 30 + 90, 360)
@var $tilt = lerp(25, 65, $progress)
@var $ct = cos($tilt)
@var $st = sin($tilt)
@var $cam = 4.5
@var $sc = 22
@var $col = iif($zone==danger,#FF2040,iif($zone==warning,#FFB030,$accent))

# ── Ring 1: 8 pts on XZ plane, perspective-projected with X-tilt ──
# px = 50 + cos(a)*cam/(sin(a)*ct+cam)*sc
# py = 50 - sin(a)*st*cam/(sin(a)*ct+cam)*sc
# depth d = (1-sin(a)*ct)/2  (1=near, 0=far)
@var $x0 = 50+cos($t)*$cam/(sin($t)*$ct+$cam)*$sc
@var $y0 = 50-sin($t)*$st*$cam/(sin($t)*$ct+$cam)*$sc
@var $d0 = clamp((1-sin($t)*$ct)/2,0.06,1)
@var $x1 = 50+cos($t+45)*$cam/(sin($t+45)*$ct+$cam)*$sc
@var $y1 = 50-sin($t+45)*$st*$cam/(sin($t+45)*$ct+$cam)*$sc
@var $d1 = clamp((1-sin($t+45)*$ct)/2,0.06,1)
@var $x2 = 50+cos($t+90)*$cam/(sin($t+90)*$ct+$cam)*$sc
@var $y2 = 50-sin($t+90)*$st*$cam/(sin($t+90)*$ct+$cam)*$sc
@var $d2 = clamp((1-sin($t+90)*$ct)/2,0.06,1)
@var $x3 = 50+cos($t+135)*$cam/(sin($t+135)*$ct+$cam)*$sc
@var $y3 = 50-sin($t+135)*$st*$cam/(sin($t+135)*$ct+$cam)*$sc
@var $d3 = clamp((1-sin($t+135)*$ct)/2,0.06,1)
@var $x4 = 50+cos($t+180)*$cam/(sin($t+180)*$ct+$cam)*$sc
@var $y4 = 50-sin($t+180)*$st*$cam/(sin($t+180)*$ct+$cam)*$sc
@var $d4 = clamp((1-sin($t+180)*$ct)/2,0.06,1)
@var $x5 = 50+cos($t+225)*$cam/(sin($t+225)*$ct+$cam)*$sc
@var $y5 = 50-sin($t+225)*$st*$cam/(sin($t+225)*$ct+$cam)*$sc
@var $d5 = clamp((1-sin($t+225)*$ct)/2,0.06,1)
@var $x6 = 50+cos($t+270)*$cam/(sin($t+270)*$ct+$cam)*$sc
@var $y6 = 50-sin($t+270)*$st*$cam/(sin($t+270)*$ct+$cam)*$sc
@var $d6 = clamp((1-sin($t+270)*$ct)/2,0.06,1)
@var $x7 = 50+cos($t+315)*$cam/(sin($t+315)*$ct+$cam)*$sc
@var $y7 = 50-sin($t+315)*$st*$cam/(sin($t+315)*$ct+$cam)*$sc
@var $d7 = clamp((1-sin($t+315)*$ct)/2,0.06,1)

# ── Ring 2: 4 pts on XY plane (perpendicular gyroscope ring) ──
@var $qx0 = 50+cos($t2)*$cam/(sin($t2)*$st+$cam)*$sc
@var $qy0 = 50+sin($t2)*$ct*$cam/(sin($t2)*$st+$cam)*$sc
@var $qx1 = 50+cos($t2+90)*$cam/(sin($t2+90)*$st+$cam)*$sc
@var $qy1 = 50+sin($t2+90)*$ct*$cam/(sin($t2+90)*$st+$cam)*$sc
@var $qx2 = 50+cos($t2+180)*$cam/(sin($t2+180)*$st+$cam)*$sc
@var $qy2 = 50+sin($t2+180)*$ct*$cam/(sin($t2+180)*$st+$cam)*$sc
@var $qx3 = 50+cos($t2+270)*$cam/(sin($t2+270)*$st+$cam)*$sc
@var $qy3 = 50+sin($t2+270)*$ct*$cam/(sin($t2+270)*$st+$cam)*$sc

# ── Expanding ripples ──
@var $rip1 = mod($time * 18, 42)
@var $rip2 = mod($time * 18 + 21, 42)

# ═══════════ DRAWING ═══════════

# ── Ambient grid ──
line 5 50 95 50 stroke:#060612 w:0.2
line 50 5 50 95 stroke:#060612 w:0.2
circle 50 50 42 stroke:#060612 w:0.2
circle 50 50 30 stroke:#050510 w:0.15

# ── Ripple waves ──
circle 50 50 $rip1 stroke:$col w:0.4 alpha:(42-$rip1)/42*0.05
circle 50 50 $rip2 stroke:$col w:0.3 alpha:(42-$rip2)/42*0.04

# ── Cross ring (perpendicular, ethereal) ──
line $qx0 $qy0 $qx1 $qy1 stroke:$col w:0.4 alpha:0.07
line $qx1 $qy1 $qx2 $qy2 stroke:$col w:0.4 alpha:0.07
line $qx2 $qy2 $qx3 $qy3 stroke:$col w:0.4 alpha:0.07
line $qx3 $qy3 $qx0 $qy0 stroke:$col w:0.4 alpha:0.07
circle $qx0 $qy0 1 fill:$col glow:6 glow_color:$col alpha:0.15
circle $qx1 $qy1 1 fill:$col glow:6 glow_color:$col alpha:0.15
circle $qx2 $qy2 1 fill:$col glow:6 glow_color:$col alpha:0.15
circle $qx3 $qy3 1 fill:$col glow:6 glow_color:$col alpha:0.15

# ── Main ring edges (depth-shaded wireframe) ──
line $x0 $y0 $x1 $y1 stroke:$col w:lerp(0.3,0.8,min($d0,$d1)) alpha:min($d0,$d1)*0.35
line $x1 $y1 $x2 $y2 stroke:$col w:lerp(0.3,0.8,min($d1,$d2)) alpha:min($d1,$d2)*0.35
line $x2 $y2 $x3 $y3 stroke:$col w:lerp(0.3,0.8,min($d2,$d3)) alpha:min($d2,$d3)*0.35
line $x3 $y3 $x4 $y4 stroke:$col w:lerp(0.3,0.8,min($d3,$d4)) alpha:min($d3,$d4)*0.35
line $x4 $y4 $x5 $y5 stroke:$col w:lerp(0.3,0.8,min($d4,$d5)) alpha:min($d4,$d5)*0.35
line $x5 $y5 $x6 $y6 stroke:$col w:lerp(0.3,0.8,min($d5,$d6)) alpha:min($d5,$d6)*0.35
line $x6 $y6 $x7 $y7 stroke:$col w:lerp(0.3,0.8,min($d6,$d7)) alpha:min($d6,$d7)*0.35
line $x7 $y7 $x0 $y0 stroke:$col w:lerp(0.3,0.8,min($d7,$d0)) alpha:min($d7,$d0)*0.35

# ── Energy beams (center to cardinal ring points) ──
line 50 50 $x0 $y0 stroke:$col w:0.2 alpha:$d0*0.12
line 50 50 $x2 $y2 stroke:$col w:0.2 alpha:$d2*0.12
line 50 50 $x4 $y4 stroke:$col w:0.2 alpha:$d4*0.12
line 50 50 $x6 $y6 stroke:$col w:0.2 alpha:$d6*0.12

# ── Central gauge face ──
circle 50 50 18 fill:#0A0A14
circle 50 50 18 stroke:#222240 w:0.3

# ── Zone ring ──
zone_ring 50 50 18 16 -225 270 normal:#0D0D1A warning:#1D170A danger:#1D0A0A

# ── Progress arc ──
progress_arc 50 50 17 -225 270 stroke:$col w:2.5 cap:round bg:#0C0C1A glow:8 glow_color:$col

# ── Gauge ticks ──
ticks 50 50 19.5 11 2.5 start:-225 sweep:270 stroke:#505070 w:0.5
ticks 50 50 19.5 51 1.2 start:-225 sweep:270 stroke:#1C1C30 w:0.2

# ── Value dot marker ──
value_dot 50 50 17 -225 270 1.5 fill:$col glow:10 glow_color:$col

# ── Core energy glow (intensifies with progress) ──
circle 50 50 12 fill:$col alpha:lerp(0.008,0.03,$progress)
circle 50 50 7 fill:$col alpha:lerp(0.015,0.05,$progress)
circle 50 50 3.5 fill:$col alpha:lerp(0.025,0.08,$progress)

# ── Value text ──
text $value 50 46 size:14 bold color:#FFFFFF font:orbitron glow:4 glow_color:$col
text $unit 50 57 size:5.5 color:$col font:rajdhani
text $min 18 69 size:2.5 color:#1A1A30
text $max 82 69 size:2.5 color:#1A1A30

# ── Main ring dots (holographic, depth-sized) ──
circle $x0 $y0 lerp(0.6,2,$d0) fill:$col glow:8 glow_color:$col alpha:$d0*0.75
circle $x1 $y1 lerp(0.6,2,$d1) fill:$col glow:8 glow_color:$col alpha:$d1*0.75
circle $x2 $y2 lerp(0.6,2,$d2) fill:$col glow:8 glow_color:$col alpha:$d2*0.75
circle $x3 $y3 lerp(0.6,2,$d3) fill:$col glow:8 glow_color:$col alpha:$d3*0.75
circle $x4 $y4 lerp(0.6,2,$d4) fill:$col glow:8 glow_color:$col alpha:$d4*0.75
circle $x5 $y5 lerp(0.6,2,$d5) fill:$col glow:8 glow_color:$col alpha:$d5*0.75
circle $x6 $y6 lerp(0.6,2,$d6) fill:$col glow:8 glow_color:$col alpha:$d6*0.75
circle $x7 $y7 lerp(0.6,2,$d7) fill:$col glow:8 glow_color:$col alpha:$d7*0.75

# ── Floating ambient particles ──
circle 50+38*sin($time*7) 50+38*cos($time*10) 0.5 fill:$col alpha:0.1
circle 50+30*sin($time*12+120) 50+30*cos($time*8+60) 0.4 fill:$col alpha:0.08
circle 50+44*sin($time*5+240) 50+44*cos($time*14+180) 0.3 fill:$col alpha:0.06

# ── Danger ──
if $zone==danger {
  circle 50 50 20 stroke:#FF2040 w:0.6 alpha:0.5 blink:500
  text "!" 50 68 size:4 bold color:#FF2040 blink:500 font:mono
}`}

];
