▶️ Live demo

Try it yourself — interact with the example below.

Loading demo…

🎯 What Are We Building?

Imagine you have a time machine control panel with three controls:

THE TIME MACHINE PANEL:
┌─────────────────────────────────────────┐
│  ⏰ TIME MACHINE CONTROL PANEL          │
│                                         │
│  ┌─────────┐  ┌─────────┐  ┌────────┐ │
│  │  -  +   │  │  [___]  │  │ RESET  │ │
│  │  STEP   │  │  COUNT  │  │ BUTTON │ │
│  │  (old)  │  │  (new)  │  │ (new)  │ │
│  └─────────┘  └─────────┘  └────────┘ │
│                                         │
│  BEFORE (Part 1):                       │
│  • Step buttons only (- and +)          │
│  • Count buttons only (- and +)         │
│  • No way to jump to day 10,000!        │
│  • No reset button                      │
│                                         │
│  AFTER (Part 2 - UPGRADED):             │
│  • Step SLIDER (drag 1-10)              │
│  • Count TEXT INPUT (type any number!)  │
│  • RESET button (appears when changed)  │
│  • Jump to day 100,000 instantly!         │
│                                         │
│  The Reset Button Magic:                │
│  • Hidden when count=0 AND step=1       │
│  • Appears when you change anything!    │
│  • Click it → everything back to default│
└─────────────────────────────────────────┘

⚠️ The Big Problem: "The String Trap & The Missing Reset"

// ==========================================
// THE "STRING SLIDER" TRAP
// ==========================================

// ❌ WRONG: Slider without Number conversion
function BadCounter() {
  const [step, setStep] = useState(1);

  return (
    <input 
      type="range" 
      min="1" 
      max="10" 
      value={step}
      onChange={e => setStep(e.target.value)} // ← BUG!
    />
  );
}

// What happens:
// 1. User slides to 7
// 2. e.target.value = "7" (STRING!)
// 3. setStep("7") → state = "7"
// 4. Math: "7" + 1 = "71" (string concatenation!) ❌
// 5. Date calculation breaks!

// ==========================================
// THE "GHOST RESET" TRAP
// ==========================================

// ❌ WRONG: Reset always visible
<button onClick={handleReset}>Reset</button>
// Shows even when nothing changed!
// User clicks it → nothing happens → confusing!

// ==========================================
// THE SOLUTION: Controlled Inputs + Number + Conditional
// ==========================================

// ✅ CORRECT: Full upgrade

function GoodCounter() {
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  const date = new Date();
  date.setDate(date.getDate() + count);

  function handleReset() {
    setCount(0);
    setStep(1);
  }

  return (
    <div>
      {/* SLIDER - controlled, with Number conversion */}
      <input 
        type="range" 
        min="1" 
        max="10"
        value={step}
        onChange={e => setStep(Number(e.target.value))} // ← FIX!
      />
      <span>Step: {step}</span>

      {/* TEXT INPUT - controlled, with Number conversion */}
      <input 
        type="text"
        value={count}
        onChange={e => setCount(Number(e.target.value))} // ← FIX!
      />

      {/* DATE DISPLAY */}
      <p>{count} days from today is {date.toDateString()}</p>

      {/* RESET - conditionally rendered! */}
      {(count !== 0 || step !== 1) && (
        <button onClick={handleReset}>Reset</button>
      )}
    </div>
  );
}

📋 The 3-Step Technique (Slider & Text Input Edition)

┌─────────────────────────────────────────┐
│  CONTROLLED SLIDER (type="range"):      │
│                                          │
│  Step 1: Create state                   │
│    const [step, setStep] = useState(1);   │
│                                          │
│  Step 2: Connect value to state         │
│    <input type="range" value={step} />    │
│                                          │
│  Step 3: Update state on change         │
│    onChange={e => setStep(Number(e.target.value))}│
│                                          │
│  ⚠️ CRITICAL: Number() conversion!      │
│  Slider values are STRINGS by default!  │
└─────────────────────────────────────────┘

┌─────────────────────────────────────────┐
│  CONTROLLED TEXT INPUT (type="text"):   │
│                                          │
│  Step 1: Create state                   │
│    const [count, setCount] = useState(0);│
│                                          │
│  Step 2: Connect value to state         │
│    <input type="text" value={count} />    │
│                                          │
│  Step 3: Update state on change         │
│    onChange={e => setCount(Number(e.target.value))}│
│                                          │
│  ⚠️ CRITICAL: Number() conversion!      │
│  Even typing "100" gives string "100"!  │
└─────────────────────────────────────────┘

🔥 Complete Visual Breakdown

The State Boxes

┌─────────────────────────────────────────┐
│  REACT'S MEMORY (Two Boxes)             │
│                                          │
│  ┌─────────────┐    ┌─────────────┐    │
│  │   count     │    │    step     │    │
│  │     0       │    │     1       │    │
│  │  (default)  │    │  (default)  │    │
│  └─────────────┘    └─────────────┘    │
│                                          │
│  AFTER TYPING "100" IN COUNT INPUT:    │
│  ┌─────────────┐    ┌─────────────┐    │
│  │   count     │    │    step     │    │
│  │    100      │    │     1       │    │
│  │  (number!)  │    │  (default)  │    │
│  └─────────────┘    └─────────────┘    │
│                                          │
│  AFTER SLIDING STEP TO 5:                │
│  ┌─────────────┐    ┌─────────────┐    │
│  │   count     │    │    step     │    │
│  │    100      │    │     5       │    │
│  │  (changed)  │    │  (changed)  │    │
│  └─────────────┘    └─────────────┘    │
│                                          │
│  AFTER CLICKING RESET:                   │
│  ┌─────────────┐    ┌─────────────┐    │
│  │   count     │    │    step     │    │
│  │     0       │    │     1       │    │
│  │  (default)  │    │  (default)  │    │
│  └─────────────┘    └─────────────┘    │
│                                          │
│  RESET BUTTON VISIBILITY:                │
│  count=0 AND step=1 → HIDDEN            │
│  count≠0 OR step≠1 → VISIBLE            │
└─────────────────────────────────────────┘

The Reset Button Logic

┌─────────────────────────────────────────┐
│  WHEN DOES THE RESET BUTTON APPEAR?     │
│                                          │
│  React asks: "Should I show the button?" │
│       ↓                                  │
│  Is count different from 0?             │
│       ↓                                  │
│   YES ──→ SHOW BUTTON! ✓                │
│       ↓                                  │
│    NO ──→ Is step different from 1?     │
│              ↓                           │
│           YES ──→ SHOW BUTTON! ✓        │
│              ↓                           │
│            NO ──→ HIDE BUTTON! ❌       │
│                                          │
│  In Code:                                │
│  (count !== 0 || step !== 1) && <button>│
│                                          │
│  The || (OR) operator:                   │
│  • If EITHER side is true → show it     │
│  • Only hide if BOTH are default        │
│                                          │
│  Examples:                               │
│  count=0, step=1 → false || false → false│
│  count=5, step=1 → true  || false → true │
│  count=0, step=3 → false || true  → true │
│  count=7, step=2 → true  || true  → true │
└─────────────────────────────────────────┘

📦 Complete Code

Create file: DateCounterV2.jsx

import { useState } from "react";

// ==========================================
// DATE COUNTER CHALLENGE - PART 2 (UPGRADED)
// ==========================================

export default function DateCounter() {
  // Step 1: Create TWO pieces of state
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  // Calculate the date based on count
  const date = new Date();
  date.setDate(date.getDate() + count);

  // ==========================================
  // EVENT HANDLERS
  // ==========================================

  function handleReset() {
    // Set BOTH states back to defaults
    setCount(0);
    setStep(1);
  }

  // ==========================================
  // JSX RETURN
  // ==========================================

  return (
    <div style={{ 
      maxWidth: "600px", 
      margin: "50px auto", 
      padding: "30px",
      fontFamily: "Arial, sans-serif",
      textAlign: "center",
      background: "#f8f9fa",
      borderRadius: "15px",
      boxShadow: "0 4px 20px rgba(0,0,0,0.1)"
    }}>
      
      {/* ================================== */}
      {/* STEP SLIDER (Controlled)           */}
      {/* ================================== */}
      <div style={{ marginBottom: "20px" }}>
        <input
          type="range"
          min="1"
          max="10"
          value={step}                              // ← Step 2
          onChange={e => setStep(Number(e.target.value))} // ← Step 3 + Number()
          style={{ width: "300px", cursor: "pointer" }}
        />
        <span style={{ 
          marginLeft: "15px", 
          fontSize: "20px", 
          fontWeight: "bold",
          color: "#7950f2"
        }}>
          Step: {step}
        </span>
      </div>

      {/* ================================== */}
      {/* COUNT CONTROLS + TEXT INPUT        */}
      {/* ================================== */}
      <div style={{ 
        display: "flex", 
        alignItems: "center", 
        justifyContent: "center",
        gap: "15px",
        marginBottom: "20px"
      }}>
        
        {/* Count buttons (from Part 1) */}
        <button 
          onClick={() => setCount(c => c - step)}
          style={buttonStyle}
        >
          -
        </button>

        {/* TEXT INPUT (Controlled) */}
        <input
          type="text"
          value={count}                             // ← Step 2
          onChange={e => setCount(Number(e.target.value))} // ← Step 3 + Number()
          style={{
            padding: "10px",
            fontSize: "18px",
            width: "100px",
            textAlign: "center",
            border: "2px solid #7950f2",
            borderRadius: "8px"
          }}
        />

        <button 
          onClick={() => setCount(c => c + step)}
          style={buttonStyle}
        >
          +
        </button>
      </div>

      {/* ================================== */}
      {/* DATE DISPLAY                       */}
      {/* ================================== */}
      <p style={{ fontSize: "22px", margin: "30px 0" }}>
        <span style={{ color: "#e76f51", fontWeight: "bold" }}>
          {count === 0 
            ? "Today is " 
            : count > 0 
              ? `${count} days from today is ` 
              : `${Math.abs(count)} days ago was `
          }
        </span>
        <span style={{ color: "#264653", fontWeight: "bold" }}>
          {date.toDateString()}
        </span>
      </p>

      {/* ================================== */}
      {/* RESET BUTTON (Conditional)         */}
      {/* ================================== */}
      {(count !== 0 || step !== 1) && (
        <button 
          onClick={handleReset}
          style={{
            padding: "12px 30px",
            fontSize: "16px",
            background: "#e76f51",
            color: "white",
            border: "none",
            borderRadius: "8px",
            cursor: "pointer",
            fontWeight: "bold"
          }}
        >
          Reset
        </button>
      )}

    </div>
  );
}

// Button style helper
const buttonStyle = {
  padding: "10px 20px",
  fontSize: "20px",
  background: "#264653",
  color: "white",
  border: "none",
  borderRadius: "8px",
  cursor: "pointer",
  fontWeight: "bold"
};

🧠 Memory Aids for Poor Logic Thinking

The "Thermostat with Sticky Note" Analogy (Number Conversion)

┌─────────────────────────────────────────────────┐
│  e.target.value = THERMOSTAT WITH STICKY NOTE   │
│                                                 │
│  The thermostat always shows a STRING:          │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │  🌡️ THERMOSTAT DISPLAY                 │    │
│  │                                          │    │
│  │  Shows: "72"  ← This is TEXT!           │    │
│  │  Not: 72      ← Not a real number!      │    │
│  │                                          │    │
│  │  e.target.value always returns TEXT     │    │
│  │  Even for <input type="range">!           │    │
│  │  Even for <select> with numbers!          │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  You need to CONVERT it:                        │
│  ┌─────────────────────────────────────────┐    │
│  │  "72" (string) → Number("72") → 72    │    │
│  │                                          │    │
│  │  Like peeling off the sticky note:    │    │
│  │  "72" → 72                               │    │
│  │  Text → Real Number                      │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  Why it matters for the Date Counter:         │
│  "10" + 1 = "101"  (string concatenation!)    │
│  10 + 1 = 11        (number addition!)        │
│                                                 │
│  If you don't convert:                        │
│  count = "100"                                  │
│  date.setDate(date.getDate() + "100")         │
│  → CRASH or WRONG DATE!                        │
│                                                 │
│  If you convert:                              │
│  count = 100                                    │
│  date.setDate(date.getDate() + 100)            │
│  → Perfect date calculation! ✓                 │
└─────────────────────────────────────────────────┘

The "Security Guard" Analogy (Conditional Reset)

┌─────────────────────────────────────────────────┐
│  RESET BUTTON = SECURITY GUARD AT A CLUB       │
│                                                 │
│  The guard has a rule: "Only show the exit     │
│  button if someone has moved from their seat!"  │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │  🛡️ SECURITY GUARD CHECKLIST           │    │
│  │                                          │    │
│  │  Guest asks: "Where's the reset button?"│    │
│  │                                          │    │
│  │  Guard checks:                         │    │
│  │  1. Has count moved from 0?             │    │
│  │  2. Has step moved from 1?              │    │
│  │                                          │    │
│  │  If NO to both → "No reset needed!      │    │
│  │                   You're at default!"     │    │
│  │                   → Button HIDDEN         │    │
│  │                                          │    │
│  │  If YES to either → "Here's the reset!" │    │
│  │                     → Button VISIBLE      │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  The || (OR) is like asking:                   │
│  "Did you move OR did you change the step?"    │
│  Only need ONE yes to show the button!         │
│                                                 │
│  The && (AND) with the button:                 │
│  "If condition is true, THEN show button"      │
│  condition && <button>                         │
│  true && button → shows button                 │
│  false && button → shows nothing (false)       │
└─────────────────────────────────────────────────┘

The "Time Machine Dials" Analogy

┌─────────────────────────────────────────────────┐
│  THE TIME MACHINE CONTROL PANEL                 │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │  ⏰ TIME MACHINE                        │    │
│  │                                          │    │
│  │  Dial 1: STEP (how big are your jumps?) │    │
│  │  ┌─────────────────────────────────┐   │    │
│  │  │  [====●====]  Slider 1-10     │   │    │
│  │  │        ↑                        │   │    │
│  │  │  Currently at: 5                │   │    │
│  │  │  (Each button press = 5 days)   │   │    │
│  │  └─────────────────────────────────┘   │    │
│  │                                          │    │
│  │  Dial 2: COUNT (how far from today?)    │    │
│  │  ┌─────────────────────────────────┐   │    │
│  │  │  [  100  ]  Type any number!    │   │    │
│  │  │        ↑                        │   │    │
│  │  │  Currently at: 100              │   │    │
│  │  │  (100 days from today)          │   │    │
│  │  └─────────────────────────────────┘   │    │
│  │                                          │    │
│  │  Display: "100 days from today is..."   │    │
│  │                                          │    │
│  │  [ RESET ] ← Emergency button!          │    │
│  │  Only appears when dials are moved!     │    │
│  │  Press it → Dial 1 back to 1            │    │
│  │           → Dial 2 back to 0            │    │
│  │           → Button disappears!          │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  In React:                                      │
│  • step = Dial 1 setting                        │
│  • count = Dial 2 setting                       │
│  • setStep = Turn Dial 1                        │
│  • setCount = Turn Dial 2                       │
│  • handleReset = Emergency reset button           │
│  • (count!==0 || step!==1) = Guard's checklist │
└─────────────────────────────────────────────────┘

The "Slider as a String" Analogy

┌─────────────────────────────────────────────────┐
│  WHY THE SLIDER GIVES STRINGS                  │
│                                                 │
│  Imagine the slider is a mail slot:            │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │  📮 MAIL SLOT (HTML Input)              │    │
│  │                                          │    │
│  │  You slide to position 7...             │    │
│  │  The slot spits out a letter: "7"       │    │
│  │  Not a number 7, but the TEXT "7"!     │    │
│  │                                          │    │
│  │  Why? Because HTML was invented before  │    │
│  │  JavaScript numbers existed!             │    │
│  │  (Not really, but it acts like it!)      │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  ┌─────────────────────────────────────────┐    │
│  │  🏭 NUMBER FACTORY (Number())           │    │
│  │                                          │    │
│  │  "7" (string) enters the factory...      │    │
│  │  [CONVERSION MACHINE] → 7 (number) exits│    │
│  │                                          │    │
│  │  Without the factory:                   │    │
│  │  "7" + 1 = "71"  (text glued together!) │    │
│  │                                          │    │
│  │  With the factory:                      │    │
│  │  7 + 1 = 8       (real math!)           │    │
│  └─────────────────────────────────────────┘    │
│                                                 │
│  ALWAYS wrap e.target.value with Number()!     │
│  Even for sliders! Even if it looks numeric!   │
└─────────────────────────────────────────────────┘

🎓 Practice Exercises

Exercise 1: Basic Controlled Slider

Create a slider that controls font size:

function FontSizeSlider() {
  // TODO: Create state for fontSize (default 16)
  // TODO: Connect slider value to state
  // TODO: Convert e.target.value to Number
  // TODO: Show text with that font size

  return (
    <div>
      <input type="range" min="10" max="50" />
      <p style={{ /* fontSize here */ }}>
        This text changes size!
      </p>
    </div>
  );
}

Solution:

import { useState } from "react";

function FontSizeSlider() {
  const [fontSize, setFontSize] = useState(16);

  return (
    <div style={{ textAlign: "center", padding: "40px" }}>
      <input
        type="range"
        min="10"
        max="50"
        value={fontSize}
        onChange={e => setFontSize(Number(e.target.value))}
        style={{ width: "300px" }}
      />
      <p style={{ fontSize: `${fontSize}px`, marginTop: "30px" }}>
        This text is {fontSize}px big!
      </p>
    </div>
  );
}

Exercise 2: Controlled Text Input with Validation

Create an input that only accepts numbers and shows a message:

function NumberInput() {
  // TODO: State for number (default 0)
  // TODO: Controlled input with Number conversion
  // TODO: Show "Positive!", "Negative!", or "Zero!"

  return (
    <div>
      <input type="text" />
      <p>{/* message here */}</p>
    </div>
  );
}

Solution:

import { useState } from "react";

function NumberInput() {
  const [num, setNum] = useState(0);

  let message;
  if (num > 0) message = "Positive! 📈";
  else if (num < 0) message = "Negative! 📉";
  else message = "Zero! ⭕";

  return (
    <div style={{ textAlign: "center", padding: "40px" }}>
      <input
        type="text"
        value={num}
        onChange={e => setNum(Number(e.target.value))}
        style={{
          padding: "15px",
          fontSize: "24px",
          width: "150px",
          textAlign: "center",
          border: "2px solid #7950f2",
          borderRadius: "8px"
        }}
      />
      <p style={{ fontSize: "24px", marginTop: "20px", fontWeight: "bold" }}>
        {message}
      </p>
    </div>
  );
}

Exercise 3: Reset Button with Conditional Rendering

Build a color picker that shows a reset button only when changed:

function ColorPicker() {
  // TODO: State for color (default "black")
  // TODO: Input to type color
  // TODO: Show colored box
  // TODO: Show reset button ONLY if color !== "black"

  return (
    <div>
      {/* Your code here */}
    </div>
  );
}

Solution:

import { useState } from "react";

function ColorPicker() {
  const [color, setColor] = useState("black");

  function handleReset() {
    setColor("black");
  }

  return (
    <div style={{ textAlign: "center", padding: "40px" }}>
      <input
        type="text"
        value={color}
        onChange={e => setColor(e.target.value)}
        placeholder="Enter a color..."
        style={{
          padding: "12px",
          fontSize: "18px",
          width: "200px",
          borderRadius: "8px",
          border: "2px solid #7950f2"
        }}
      />

      <div style={{
        width: "100px",
        height: "100px",
        backgroundColor: color,
        margin: "20px auto",
        borderRadius: "10px",
        border: "3px solid #ccc"
      }} />

      {color !== "black" && (
        <button
          onClick={handleReset}
          style={{
            padding: "10px 25px",
            background: "#e76f51",
            color: "white",
            border: "none",
            borderRadius: "8px",
            cursor: "pointer",
            fontSize: "16px"
          }}
        >
          Reset to Black
        </button>
      )}
    </div>
  );
}

Exercise 4: Fix the Broken Counter

This code has 4 bugs. Find and fix them:

function BrokenCounter() {
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  function handleReset() {
    setCount(0);
    // Missing step reset?
  }

  return (
    <div>
      <input 
        type="range" 
        value={step} 
        onChange={e => setStep(e.target.value)} // Bug 1?
      />
      
      <input 
        type="text" 
        value={count} 
        onChange={e => setCount(e.target.value)} // Bug 2?
      />
      
      <p>{count} days from today</p>
      
      <button onClick={handleReset()}>Reset</button> // Bug 3?
      
      {count === 0 && step === 1 && <button>Reset</button>} // Bug 4?
    </div>
  );
}

Solution:

function FixedCounter() {
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  function handleReset() {
    setCount(0);
    setStep(1); // Fix 1: Reset BOTH states!
  }

  return (
    <div>
      {/* Fix 2: Number() conversion for slider */}
      <input 
        type="range" 
        min="1"
        max="10"
        value={step} 
        onChange={e => setStep(Number(e.target.value))}
      />
      
      {/* Fix 3: Number() conversion for text input */}
      <input 
        type="text" 
        value={count} 
        onChange={e => setCount(Number(e.target.value))}
      />
      
      <p>{count} days from today</p>
      
      {/* Fix 4: Pass function reference, don't call it! */}
      {/* Fix 5: Show when CHANGED, not when default! */}
      {(count !== 0 || step !== 1) && (
        <button onClick={handleReset}>Reset</button>
      )}
    </div>
  );
}

💡 Key Takeaways

ConceptWhat It MeansExample
Slider inputtype="range" for numeric selection<input type="range" min="1" max="10" />
Text input for numberstype="text" but convert to NumberNumber(e.target.value)
Number conversione.target.value is ALWAYS stringNumber("7") → 7
Multiple statesEach independent value needs its own useStateconst [count, setCount] = useState(0)
Reset functionSets multiple states back to defaultsetCount(0); setStep(1);
Conditional renderingShow/hide based on state`{(count !== 0 \\step !== 1) && <button>}`
**OR operator `\\`**True if EITHER condition is true`true \\false → true`
AND operator &&Renders element if condition is truecondition && <element>
Date calculationsetDate(date.getDate() + count)Adds days to current date

The Complete Pattern:

function DateCounter() {
  // 1. Create states
  const [count, setCount] = useState(0);
  const [step, setStep] = useState(1);

  // 2. Calculate derived values
  const date = new Date();
  date.setDate(date.getDate() + count);

  // 3. Reset handler
  function handleReset() {
    setCount(0);
    setStep(1);
  }

  return (
    <div>
      {/* 4. Controlled slider with Number() */}
      <input 
        type="range" 
        value={step}
        onChange={e => setStep(Number(e.target.value))}
      />

      {/* 5. Controlled text input with Number() */}
      <input 
        type="text"
        value={count}
        onChange={e => setCount(Number(e.target.value))}
      />

      {/* 6. Display */}
      <p>{count} days from today is {date.toDateString()}</p>

      {/* 7. Conditional reset */}
      {(count !== 0 || step !== 1) && (
        <button onClick={handleReset}>Reset</button>
      )}
    </div>
  );
}

Golden Rules:

  1. Always convert with Number()e.target.value is always a string, even for sliders!
  2. One state per independent valuecount and step need separate useState
  3. Reset sets ALL states — Don't forget to reset every piece of state
  4. Conditional render with &&condition && <element> shows only if true
  5. Use || for "either" conditions — Show button if count changed OR step changed
  6. Pass function reference to onClickonClick={handleReset} not onClick={handleReset()}
  7. Derived state is calculated, not stored — Date is computed from count, not stored in state
  8. Slider needs min and max — Always set min and max attributes on range inputs

One Sentence Summary: > "The upgraded date counter uses two independent pieces of state — count for days and step for increment size — where both the slider and text input are controlled components with Number(e.target.value) conversion because e.target.value is always a string, and a reset button is conditionally rendered using (count !== 0 || step !== 1) && <button> so it only appears when the user has changed from default values, while handleReset sets both states back to their initial values simultaneously!"