JSFiddle - React, Tailwind, and code Playground

by velo_ninja

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mold Regulation Data</title>
    <link rel="stylesheet" href="style.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
</head>
<body>
    <div class="container">
        <h1>Mold Regulation Settings</h1>

        <div class="section">
            <div class="section-title" data-target="globalParametersContent" aria-expanded="true" aria-controls="globalParametersContent">
                <div class="title-content"><i class="fas fa-globe"></i> Global Parameters</div>
                <div class="title-controls"><i class="fas fa-chevron-down"></i></div>
            </div>
            <div id="globalParametersContent" class="section-content">
                <div class="param-grid" id="globalSections">
                    <div class="input-group">
                        <label for="globalClampingForce">Clamping Force</label>
                        <div class="input-wrapper">
                            <div class="input-container">
                                <input type="number" id="globalClampingForce" data-param="clampingForce">
                                <span class="tooltip"></span>
                            </div>
                            <span class="unit"></span>
                        </div>
                        <p class="error-text" id="globalClampingForceError" style="display: none;"></p>
                    </div>
                    <div class="input-group">
                        <label for="globalInjectionPressure">Injection Pressure</label>
                        <div class="input-wrapper">
                            <div class="input-container">
                                <input type="number" id="globalInjectionPressure" data-param="injectionPressure">
                      ...

CSS

:root {
    --primary-color: #007bff;
    --secondary-color: #6c757d;
    --success-color: #28a745;
    --danger-color: #dc3545;
    --warning-color: #ffc107;
    --info-color: #17a2b8;

    --background-color: #f8f9fa;
    --surface-color: #ffffff;
    --border-color: #e9ecef;
    --shadow-color: rgba(0, 0, 0, 0.1);

    --font-color-primary: #343a40;
    --font-color-muted: #6c757d;
    --font-color-light: #f8f9fa;

    --gap-xxs: 4px;
    --gap-xs: 8px;
    --gap-sm: 12px;
    --gap-md: 16px;
    --gap-lg: 24px;
    --gap-xl: 32px;

    --border-radius-sm: 4px;
    --border-radius-md: 8px;

    --font-size-base: 1rem;
    --font-size-label: 0.9rem;
    --font-size-unit: 0.8rem;
    --font-size-h1: 2rem;
    --font-size-h3: 1.25rem;
}

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    margin: 0;
    padding: var(--gap-md);
    background-color: var(--background-color);
    color: var(--font-color-primary);
    line-height: 1.6;
    display: flex;
    justify-content: center;
    min-height: 100vh;
}

.container {
    background-color: var(--surface-color);
    padding: var(--gap-xl);
    border-radius: var(--border-radius-md);
    box-shadow: 0 0 var(--gap-xl) var(--shadow-color);
    width: 100%;
    max-width: 1200px;
    box-sizing: border-box;
}

h1 {
    text-align: center;
    color: var(--primary-color);
    margin-bottom: var(--gap-xl);
    font-size: var(--font-size-h1);
}

.section {
    border: 1px solid var(--border-color);
    border-radius: var(--border-radius-md);
    margin-bottom: var(--gap-lg);
    overflow: hidden;
    background-color: var(--surface-color);
}

.section-title {
    background-color: var(--primary-color);
    color: var(--font-color-light);
    padding: var(--gap-sm) var(--gap-md);
    display: flex;
    justify-content: space-between;
    align-items: center;
    cursor: pointer;
    font-weight: bold;
    font-size:...

JavaScript

// --- CONFIGURATION ---
const CONFIG = {
    GLOBAL_PARAMS: {
        clampingForce: { min: 120, max: 350, unit: 'kN', placeholder: 220, label: 'Clamping Force' },
        injectionPressure: { min: 50, max: 200, unit: 'bar', placeholder: 100, label: 'Injection Pressure' },
        moldTemperature: { min: 50, max: 80, unit: '°C', placeholder: 60, label: 'Mold Temperature' },
        coolingWaterTemp: { min: 5, max: 30, unit: '°C', placeholder: 15, label: 'Cooling Water Temp' },
        startBlowing: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Blowing' },
        startCorePullersOpen: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start CorePullers Open' },
        startGripperBackward: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Gripper Backward' },
        startGripperUp: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Gripper Up' },
        startGripperDown: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Gripper Down' },
        startGripperForward: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Gripper Forward' },
        startSecurityPosSpreize: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Start Security Pos. Spreize' },
        lockingPosition: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Locking Position' },
        delockingPosition: { min: 0, max: 500, unit: 'mm', placeholder: 100, label: 'Delocking Position' },
    },
    MOVEMENT_TYPES: [
        { value: 'pre-opening', text: 'Pre-Opening', icon: 'fa-arrow-right' },
        { value: 'pre-closing', text: 'Pre-Closing', icon: 'fa-arrow-left' },
        { value: 'opening', text: 'Opening', icon: 'fa-arrow-right' },
        { value: 'closing', text: 'Closing', icon: 'fa-arrow-left' },
        { value: 'venting', text: 'Venting', icon: 'fa-wind' }
    ],
    MOVEMENT_SPEED: { min: 10, max: 100, step: 0.1, unit: 'mm/s', placeholder: 50.0 },
   ...