# rftools/_catalog.py
# AUTO-GENERATED by scripts/generate_stubs.py — DO NOT EDIT
# Regenerate with: python scripts/generate_stubs.py --frontend-dir /path/to/frontend
from rftools.types import CalculatorInfo, InputField, OutputField

CALCULATORS: dict[str, CalculatorInfo] = {
    'microstrip-impedance': CalculatorInfo(
        slug='microstrip-impedance',
        title='Microstrip Impedance Calculator',
        category='rf',
        description='Calculate microstrip transmission line impedance using Hammerstad-Jensen equations. Get Z₀, effective dielectric constant, and propagation delay for PCB trace design.',
        inputs=(
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=1.2, min=0.01, max=50.0, description='Width of the copper trace on top of the substrate'),
            InputField(key='substrateHeight', label='Substrate Height', unit='mm', default=1.6, min=0.05, max=10.0, description='Dielectric thickness between trace and ground plane'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=4.2, min=1.0, max=100.0, description='Relative permittivity of the substrate material'),
            InputField(key='copperThickness', label='Copper Thickness', unit='μm', default=35.0, min=1.0, max=200.0, description='Thickness of the copper trace'),
        ),
        outputs=(
            OutputField(key='impedance', label='Characteristic Impedance', unit='Ω', description=''),
            OutputField(key='effectiveDielectric', label='Effective Dielectric', unit='', description=''),
            OutputField(key='propagationDelay', label='Propagation Delay', unit='ps/mm', description=''),
        ),
        keywords=('microstrip impedance calculator', 'pcb trace impedance', 'microstrip Z0', 'transmission line impedance', 'pcb impedance', 'characteristic impedance',),
    ),
    'rf-link-budget': CalculatorInfo(
        slug='rf-link-budget',
        title='RF Link Budget Calculator',
        category='rf',
        description='Calculate RF link budget: transmit power, free space path loss, antenna gains, and received signal level. Determine link margin and maximum range.',
        inputs=(
            InputField(key='txPower', label='TX Power', unit='dBm', default=30.0, min=-30.0, max=100.0, description='Transmitter output power'),
            InputField(key='txGain', label='TX Antenna Gain', unit='dBi', default=3.0, min=-30.0, max=60.0, description='TX antenna gain in dBi'),
            InputField(key='txCableLoss', label='TX Cable Loss', unit='dB', default=1.0, min=0.0, max=20.0, description='TX cable + connector losses (positive value)'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=2400.0, min=0.1, max=1000000.0, description='Center frequency'),
            InputField(key='distance', label='Distance', unit='km', default=1.0, min=0.001, max=1000000.0, description='Distance between TX and RX'),
            InputField(key='rainFade', label='Rain Fade', unit='dB', default=0.0, min=0.0, max=50.0, description='Rain attenuation per ITU-R P.838. Use 0 for line-of-sight ground links; 3–20 dB for satellite links above 10 GHz in heavy rain zones.'),
            InputField(key='atmosphericLoss', label='Atmospheric Loss', unit='dB', default=0.5, min=0.0, max=20.0, description='Gaseous absorption (O₂ at 60 GHz: ~15 dB/km; H₂O at 22 GHz: ~0.2 dB/km). Use 0.5 dB typical for sub-6 GHz terrestrial links.'),
            InputField(key='pointingLoss', label='Pointing Loss', unit='dB', default=0.0, min=0.0, max=10.0, description='Antenna misalignment loss. Pencil-beam dishes: 0.5–3 dB. Omnidirectional or wide-beam antennas: 0 dB.'),
            InputField(key='rxGain', label='RX Antenna Gain', unit='dBi', default=3.0, min=-30.0, max=60.0, description='RX antenna gain in dBi'),
            InputField(key='rxCableLoss', label='RX Cable Loss', unit='dB', default=1.0, min=0.0, max=20.0, description='RX cable + connector losses'),
            InputField(key='rxSensitivity', label='RX Sensitivity', unit='dBm', default=-90.0, min=-160.0, max=0.0, description='Minimum receivable signal level'),
        ),
        outputs=(
            OutputField(key='fspl', label='Free Space Path Loss', unit='dB', description=''),
            OutputField(key='eirp', label='EIRP', unit='dBm', description='Effective Isotropic Radiated Power'),
            OutputField(key='rxPower', label='Received Power', unit='dBm', description=''),
            OutputField(key='linkMargin', label='Link Margin', unit='dB', description=''),
            OutputField(key='maxRangeKm', label='Max Range', unit='km', description=''),
            OutputField(key='totalAdditionalLoss', label='Total Additional Loss', unit='dB', description='Sum of rain fade + atmospheric loss + pointing loss'),
        ),
        keywords=('rf link budget calculator', 'free space path loss', 'fspl calculator', 'link margin', 'received signal level', 'friis equation',),
    ),
    'vswr-return-loss': CalculatorInfo(
        slug='vswr-return-loss',
        title='VSWR & Return Loss Calculator',
        category='rf',
        description='Convert between VSWR, return loss, reflection coefficient, mismatch loss, and reflected/transmitted power percentage for RF impedance matching.',
        inputs=(
            InputField(key='vswr', label='VSWR', unit=':1', default=1.5, min=1.0, max=100.0, description='Voltage Standing Wave Ratio (1:1 = perfect match)'),
        ),
        outputs=(
            OutputField(key='returnLoss', label='Return Loss', unit='dB', description=''),
            OutputField(key='gamma', label='Reflection Coefficient', unit='', description=''),
            OutputField(key='mismatchLoss', label='Mismatch Loss', unit='dB', description=''),
            OutputField(key='reflectedPct', label='Reflected Power', unit='%', description=''),
            OutputField(key='transmittedPct', label='Transmitted Power', unit='%', description=''),
        ),
        keywords=('vswr calculator', 'return loss calculator', 'reflection coefficient', 'mismatch loss', 'vswr to return loss', 'rf impedance matching',),
    ),
    'db-converter': CalculatorInfo(
        slug='db-converter',
        title='dBm Power Converter',
        category='rf',
        description='Convert dBm to watts, milliwatts, dBW, dBμV, and volts RMS. Essential RF power unit conversion tool for signal levels and link budgets.',
        inputs=(
            InputField(key='dbm', label='Power Level', unit='dBm', default=0.0, min=-150.0, max=100.0, description='Power in dBm (0 dBm = 1 mW)'),
            InputField(key='impedance', label='System Impedance', unit='Ω', default=50.0, min=1.0, max=10000.0, description='Reference impedance for voltage conversion (typically 50Ω or 75Ω)'),
        ),
        outputs=(
            OutputField(key='dbw', label='Power', unit='dBW', description=''),
            OutputField(key='watts', label='Power', unit='W', description=''),
            OutputField(key='mwatts', label='Power', unit='mW', description=''),
            OutputField(key='uwatts', label='Power', unit='μW', description=''),
            OutputField(key='vrms', label='Voltage', unit='V RMS', description=''),
            OutputField(key='mvrms', label='Voltage', unit='mV RMS', description=''),
            OutputField(key='dbuv', label='Voltage', unit='dBμV', description=''),
        ),
        keywords=('dbm to watts', 'dbm converter', 'power unit converter', 'dbm to mw', 'rf power converter', 'dbm dBW',),
    ),
    'noise-figure-cascade': CalculatorInfo(
        slug='noise-figure-cascade',
        title='Cascaded Noise Figure Calculator',
        category='rf',
        description='Calculate cascaded noise figure for a chain of RF stages using the Friis formula. Essential for LNA and receiver chain design.',
        inputs=(
            InputField(key='numStages', label='Number of Stages', unit='', default=3.0, min=1.0, max=4.0, description='Number of cascaded RF stages (1–4)'),
            InputField(key='stage1NF', label='Stage 1 Noise Figure', unit='dB', default=1.5, min=0.0, max=30.0, description='Noise figure of stage 1 (typically the LNA)'),
            InputField(key='stage1Gain', label='Stage 1 Gain', unit='dB', default=15.0, min=-20.0, max=40.0, description='Gain of stage 1'),
            InputField(key='stage1IIP3', label='Stage 1 IIP3', unit='dBm', default=-5.0, min=-40.0, max=50.0, description='Input third-order intercept point of stage 1 (LNA). Typical LNA: −5 to +10 dBm.'),
            InputField(key='stage2NF', label='Stage 2 Noise Figure', unit='dB', default=8.0, min=0.0, max=30.0, description='Noise figure of stage 2 (e.g. mixer)'),
            InputField(key='stage2Gain', label='Stage 2 Gain', unit='dB', default=-6.0, min=-20.0, max=40.0, description='Gain of stage 2 (may be negative for a mixer)'),
            InputField(key='stage2IIP3', label='Stage 2 IIP3', unit='dBm', default=10.0, min=-40.0, max=50.0, description='Input third-order intercept point of stage 2 (e.g. mixer). Typical passive mixer: +10 to +20 dBm.'),
            InputField(key='stage3NF', label='Stage 3 Noise Figure', unit='dB', default=6.0, min=0.0, max=30.0, description='Noise figure of stage 3 (e.g. IF amplifier)'),
            InputField(key='stage3Gain', label='Stage 3 Gain', unit='dB', default=20.0, min=-20.0, max=40.0, description='Gain of stage 3'),
            InputField(key='stage3IIP3', label='Stage 3 IIP3', unit='dBm', default=20.0, min=-40.0, max=50.0, description='Input third-order intercept point of stage 3 (IF amplifier). Typical: +15 to +25 dBm.'),
            InputField(key='stage4NF', label='Stage 4 Noise Figure', unit='dB', default=3.0, min=0.0, max=30.0, description='Noise figure of stage 4'),
            InputField(key='stage4Gain', label='Stage 4 Gain', unit='dB', default=10.0, min=-20.0, max=40.0, description='Gain of stage 4'),
            InputField(key='stage4IIP3', label='Stage 4 IIP3', unit='dBm', default=25.0, min=-40.0, max=50.0, description='Input third-order intercept point of stage 4.'),
        ),
        outputs=(
            OutputField(key='cascadedNF', label='Cascaded Noise Figure', unit='dB', description='Total cascaded noise figure of the signal chain'),
            OutputField(key='cascadedF', label='Cascaded Noise Factor', unit='', description='Total cascaded noise factor (linear)'),
            OutputField(key='stage1Contribution', label='Stage 1 NF Contribution', unit='dB', description='Noise figure contribution from stage 1'),
            OutputField(key='stage2Contribution', label='Stage 2 NF Contribution', unit='dB', description='Noise figure contribution of stage 2 (referred to input)'),
            OutputField(key='stage3Contribution', label='Stage 3 NF Contribution', unit='dB', description='Noise figure contribution of stage 3 (referred to input)'),
            OutputField(key='cascadedIIP3', label='Cascaded IIP3', unit='dBm', description='Input-referred third-order intercept point of the cascade. Higher is better (less intermodulation distortion).'),
            OutputField(key='cascadedOIP3', label='Cascaded OIP3', unit='dBm', description='Output-referred third-order intercept point. OIP3 = IIP3 + cascaded gain.'),
        ),
        keywords=('noise figure calculator', 'cascaded noise figure', 'friis formula', 'NF cascade', 'receiver noise figure', 'LNA design',),
    ),
    'skin-depth': CalculatorInfo(
        slug='skin-depth',
        title='Skin Depth Calculator',
        category='rf',
        description='Calculate the skin depth (penetration depth) of electromagnetic fields in conductors as a function of frequency and material properties.',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=1000.0, min=0.001, max=1000000.0, description='Operating frequency'),
            InputField(key='conductivity', label='Conductivity', unit='S/m', default=58000000.0, min=1000.0, max=100000000.0, description='Electrical conductivity of the conductor material'),
            InputField(key='relativePermeability', label='Relative Permeability', unit='', default=1.0, min=1.0, max=100000.0, description='Relative magnetic permeability of the conductor (1 for non-magnetic materials)'),
        ),
        outputs=(
            OutputField(key='skinDepthUm', label='Skin Depth', unit='μm', description='Skin depth (1/e penetration depth) in micrometers'),
            OutputField(key='skinDepthNm', label='Skin Depth', unit='nm', description='Skin depth in nanometers'),
            OutputField(key='surfaceResistance', label='Surface Resistance', unit='mΩ/□', description='Sheet resistance of the conductor surface (Rs = 1/(σ·δ))'),
        ),
        keywords=('skin depth calculator', 'penetration depth', 'skin effect', 'conductor loss', 'rf skin depth', 'electromagnetic skin depth',),
    ),
    'wavelength-frequency': CalculatorInfo(
        slug='wavelength-frequency',
        title='Wavelength & Frequency Calculator',
        category='rf',
        description='Convert between frequency, wavelength, and wave number in free space or medium. Calculate half-wave and quarter-wave lengths for antenna and transmission line design.',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=2400.0, min=0.001, max=1000000.0, description='Operating frequency'),
            InputField(key='medium', label='Relative Permittivity', unit='', default=1.0, min=1.0, max=100.0, description='Relative permittivity εᵣ of the medium (1 = free space/air)'),
        ),
        outputs=(
            OutputField(key='wavelengthMm', label='Free-Space Wavelength', unit='mm', description='Wavelength in free space (air)'),
            OutputField(key='actualWavelengthMm', label='Wavelength in Medium', unit='mm', description='Wavelength in the specified dielectric medium'),
            OutputField(key='halfWaveMm', label='Half-Wave Length', unit='mm', description='Half-wavelength in medium (λ/2 dipole reference)'),
            OutputField(key='quarterWaveMm', label='Quarter-Wave Length', unit='mm', description='Quarter-wavelength in medium (λ/4 monopole / stub reference)'),
            OutputField(key='wavenumber', label='Wavenumber', unit='rad/m', description='Wave number k = 2π/λ in the medium'),
        ),
        keywords=('wavelength calculator', 'frequency wavelength calculator', 'rf wavelength', 'antenna wavelength', 'half wavelength', 'quarter wave',),
    ),
    'coax-impedance': CalculatorInfo(
        slug='coax-impedance',
        title='Coaxial Cable Impedance Calculator',
        category='rf',
        description='Calculate coaxial cable characteristic impedance, capacitance, inductance per unit length, and cutoff frequency from inner/outer conductor dimensions and dielectric.',
        inputs=(
            InputField(key='innerDiameter', label='Inner Conductor Diameter', unit='mm', default=0.9, min=0.01, max=100.0, description='Outer diameter of the inner conductor'),
            InputField(key='outerDiameter', label='Outer Conductor Inner Diameter', unit='mm', default=2.95, min=0.1, max=200.0, description='Inner diameter of the outer conductor (shield)'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=2.2, min=1.0, max=20.0, description='Relative permittivity of the insulating dielectric between conductors'),
        ),
        outputs=(
            OutputField(key='impedance', label='Characteristic Impedance', unit='Ω', description='Characteristic impedance of the coaxial cable'),
            OutputField(key='capacitancePFm', label='Capacitance', unit='pF/m', description='Distributed capacitance per meter of cable length'),
            OutputField(key='inductanceNHm', label='Inductance', unit='nH/m', description='Distributed inductance per meter of cable length'),
            OutputField(key='velocityFactor', label='Velocity Factor', unit='', description='Signal propagation speed as fraction of speed of light (1/sqrt(εᵣ))'),
            OutputField(key='cutoffFreqGHz', label='TE11 Cutoff Frequency', unit='GHz', description='Frequency above which higher-order modes can propagate (TE11 mode)'),
        ),
        keywords=('coax impedance calculator', 'coaxial cable impedance', 'coax characteristic impedance', 'rg-58', 'transmission line calculator',),
    ),
    'coax-loss': CalculatorInfo(
        slug='coax-loss',
        title='Coaxial Cable Loss Calculator',
        category='rf',
        description='Calculate RF attenuation for common coaxial cables (LMR-400, RG-58, RG-213, and more). Enter cable type, frequency, and run length to get insertion loss in dB.',
        inputs=(
            InputField(key='cableIndex', label='Cable Type', unit='', default=0.0, min=0.0, max=9.0, description='0=LMR-400, 1=LMR-240, ... 9=Andrew LDF4-50A (7/8")'),
            InputField(key='frequencyMHz', label='Frequency', unit='MHz', default=435.0, min=1.0, max=6000.0, description=''),
            InputField(key='lengthM', label='Cable Length', unit='m', default=10.0, min=0.1, max=10000.0, description=''),
        ),
        outputs=(
            OutputField(key='attenuation_dB', label='Insertion Loss', unit='dB', description=''),
            OutputField(key='lossPer100m', label='Loss per 100 m', unit='dB/100m', description=''),
            OutputField(key='powerRemaining_pct', label='Power at Load', unit='%', description=''),
            OutputField(key='voltageRemaining_pct', label='Voltage at Load', unit='%', description=''),
        ),
        keywords=('coax', 'cable', 'attenuation', 'loss', 'LMR-400', 'RG-58', 'insertion loss', 'RF cable',),
    ),
    'ism-coexistence': CalculatorInfo(
        slug='ism-coexistence',
        title='ISM Band Wireless Coexistence Calculator',
        category='rf',
        description='Estimate collision probability and throughput impact when WiFi, Bluetooth, Zigbee, LoRa, or other protocols share the same ISM band. Enter duty cycles, channel counts, and power offset.',
        inputs=(
            InputField(key='bandIndex', label='ISM Band', unit='', default=0.0, min=0.0, max=4.0, description=''),
            InputField(key='dutyCycle1_pct', label='Protocol 1 Duty Cycle', unit='%', default=50.0, min=0.01, max=100.0, description='WiFi at moderate load ≈ 20–60%, BLE advertising ≈ 0.5–5%, Zigbee ≈ 1%'),
            InputField(key='channels1', label='Protocol 1 Channels', unit='', default=3.0, min=1.0, max=100.0, description='WiFi: 3 non-overlapping (1/6/11), BLE data: 37 channels, LoRaWAN EU: 8 channels'),
            InputField(key='dutyCycle2_pct', label='Protocol 2 Duty Cycle', unit='%', default=5.0, min=0.01, max=100.0, description=''),
            InputField(key='channels2', label='Protocol 2 Channels', unit='', default=37.0, min=1.0, max=100.0, description=''),
            InputField(key='txPowerOffset_dB', label='TX Power Offset (P1−P2)', unit='dB', default=10.0, min=-30.0, max=40.0, description='Positive = Protocol 1 is stronger. WiFi (20 dBm) vs BLE (10 dBm) = +10 dB'),
        ),
        outputs=(
            OutputField(key='effectiveCollision_pct', label='Effective Collision Rate', unit='%', description=''),
            OutputField(key='collisionProb_pct', label='Raw Collision Probability', unit='%', description=''),
            OutputField(key='throughputImpact_pct', label='Throughput Impact', unit='%', description=''),
            OutputField(key='sharedChannelFraction', label='Shared Channel Fraction', unit='%', description=''),
        ),
        keywords=('ISM band', 'coexistence', 'WiFi', 'Bluetooth', 'Zigbee', 'LoRa', '2.4 GHz', 'interference', 'collision',),
    ),
    'attenuator-designer': CalculatorInfo(
        slug='attenuator-designer',
        title='RF Attenuator Designer',
        category='rf',
        description='Design Pi (π) and T attenuator pads for any attenuation value and impedance. Returns standard resistor values for both topologies with nearest E24 values.',
        inputs=(
            InputField(key='attenuation', label='Attenuation', unit='dB', default=6.0, min=0.1, max=40.0, description='Desired attenuation in dB'),
            InputField(key='impedance', label='System Impedance', unit='Ω', default=50.0, min=1.0, max=1000.0, description='Source and load impedance (must be equal for a matched pad)'),
        ),
        outputs=(
            OutputField(key='piR1', label='Pi Shunt Resistor (exact)', unit='Ω', description='Pi topology: two equal shunt resistors (exact value)'),
            OutputField(key='piR1Nearest', label='Pi Shunt Resistor (E24)', unit='Ω', description='Pi topology: nearest E24 standard value for shunt resistors'),
            OutputField(key='piR2', label='Pi Series Resistor (exact)', unit='Ω', description='Pi topology: series resistor (exact value)'),
            OutputField(key='piR2Nearest', label='Pi Series Resistor (E24)', unit='Ω', description='Pi topology: nearest E24 standard value for series resistor'),
            OutputField(key='tR1', label='T Series Resistor (exact)', unit='Ω', description='T topology: two equal series resistors (exact value)'),
            OutputField(key='tR1Nearest', label='T Series Resistor (E24)', unit='Ω', description='T topology: nearest E24 standard value for series resistors'),
            OutputField(key='tR2', label='T Shunt Resistor (exact)', unit='Ω', description='T topology: shunt resistor (exact value)'),
            OutputField(key='tR2Nearest', label='T Shunt Resistor (E24)', unit='Ω', description='T topology: nearest E24 standard value for shunt resistor'),
        ),
        keywords=('attenuator calculator', 'rf attenuator design', 'pi attenuator', 't attenuator', 'pad calculator', 'resistive attenuator',),
    ),
    'smith-chart': CalculatorInfo(
        slug='smith-chart',
        title='Smith Chart Calculator',
        category='rf',
        description='Interactive Smith Chart for impedance matching and RF network analysis. Enter load impedance to visualize reflection coefficient, VSWR circle, and normalized impedance.',
        inputs=(
            InputField(key='resistance', label='Resistance', unit='Ω', default=50.0, min=0.0, max=None, description='Real part of load impedance (must be ≥ 0)'),
            InputField(key='reactance', label='Reactance', unit='Ω', default=0.0, min=None, max=None, description='Imaginary part of load impedance. Positive = inductive, negative = capacitive.'),
            InputField(key='referenceImpedance', label='Reference Impedance', unit='Ω', default=50.0, min=1.0, max=None, description='System characteristic impedance (typically 50 Ω for RF, 75 Ω for cable TV)'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=1000.0, min=0.001, max=None, description='Operating frequency (informational — does not affect Smith Chart position)'),
        ),
        outputs=(
            OutputField(key='gamma_mag', label='Reflection Coefficient |Γ|', unit='', description=''),
            OutputField(key='gamma_ang', label='Angle ∠Γ', unit='°', description=''),
            OutputField(key='vswr', label='VSWR', unit=':1', description=''),
            OutputField(key='returnLoss', label='Return Loss', unit='dB', description=''),
            OutputField(key='mismatchLoss', label='Mismatch Loss', unit='dB', description=''),
            OutputField(key='normalizedR', label='Normalized Resistance r', unit='', description=''),
            OutputField(key='normalizedX', label='Normalized Reactance x', unit='', description=''),
        ),
        keywords=('smith chart', 'impedance matching', 'reflection coefficient', 'VSWR', 'RF', 'transmission line', 'normalized impedance', 'return loss', 'microwave', 'S11',),
    ),
    'trace-width-current': CalculatorInfo(
        slug='trace-width-current',
        title='PCB Trace Width Calculator (IPC-2221 / IPC-2152)',
        category='pcb',
        description='Calculate minimum PCB trace width for a given current, copper weight, and temperature rise per IPC-2221 and IPC-2152 standards. Includes resistance and voltage drop.',
        inputs=(
            InputField(key='current', label='Current', unit='A', default=1.0, min=0.01, max=100.0, description='RMS current through the trace'),
            InputField(key='copperWeight', label='Copper Weight', unit='oz', default=1.0, min=0.5, max=4.0, description='Copper thickness (1 oz = 35 μm = 1.37 mil)'),
            InputField(key='tempRise', label='Temperature Rise', unit='°C', default=10.0, min=1.0, max=100.0, description='Allowed temperature rise above ambient'),
            InputField(key='traceLength', label='Trace Length', unit='mm', default=100.0, min=1.0, max=10000.0, description='Length of the trace (for resistance/voltage drop)'),
            InputField(key='isExternal', label='Layer Type', unit='', default=1.0, min=0.0, max=1.0, description='1 = external (outer) layer, 0 = internal layer'),
        ),
        outputs=(
            OutputField(key='width2221mm', label='Min Width (IPC-2221)', unit='mm', description=''),
            OutputField(key='width2152mm', label='Min Width (IPC-2152)', unit='mm', description=''),
            OutputField(key='resistance', label='DC Resistance', unit='Ω', description=''),
            OutputField(key='voltageDrop', label='Voltage Drop', unit='V', description=''),
            OutputField(key='powerDiss', label='Power Dissipation', unit='W', description=''),
        ),
        keywords=('trace width calculator', 'pcb trace current', 'ipc-2221 calculator', 'ipc-2152', 'pcb current capacity', 'trace ampacity',),
    ),
    'trace-resistance': CalculatorInfo(
        slug='trace-resistance',
        title='PCB Trace Resistance Calculator',
        category='pcb',
        description='Calculate PCB copper trace DC resistance from width, length, thickness, and temperature. Includes sheet resistance and temperature coefficient.',
        inputs=(
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=0.5, min=0.05, max=50.0, description=''),
            InputField(key='traceLength', label='Trace Length', unit='mm', default=100.0, min=0.1, max=10000.0, description=''),
            InputField(key='copperThickness', label='Copper Thickness', unit='μm', default=35.0, min=1.0, max=200.0, description=''),
            InputField(key='temperature', label='Temperature', unit='°C', default=25.0, min=-55.0, max=150.0, description=''),
        ),
        outputs=(
            OutputField(key='resistance', label='Resistance', unit='Ω', description=''),
            OutputField(key='resistanceMOhm', label='Resistance', unit='mΩ', description=''),
            OutputField(key='sheetResistance', label='Sheet Resistance', unit='mΩ/□', description=''),
        ),
        keywords=('pcb trace resistance', 'copper trace resistance', 'trace impedance dc', 'pcb resistance calculator',),
    ),
    'differential-pair': CalculatorInfo(
        slug='differential-pair',
        title='Differential Pair Impedance Calculator',
        category='pcb',
        description='Calculate differential (Zdiff) and common-mode (Zcom) impedance for edge-coupled microstrip differential pairs used in USB, HDMI, Ethernet, and high-speed serial interfaces.',
        inputs=(
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=0.15, min=0.05, max=5.0, description='Width of each individual trace in the differential pair'),
            InputField(key='traceSpacing', label='Trace Spacing (edge-to-edge)', unit='mm', default=0.15, min=0.05, max=5.0, description='Edge-to-edge gap between the two traces'),
            InputField(key='substrateHeight', label='Substrate Height', unit='mm', default=0.1, min=0.05, max=5.0, description='Dielectric thickness between trace and ground plane'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=4.2, min=1.0, max=20.0, description='Relative permittivity of the substrate material'),
            InputField(key='copperThickness', label='Copper Thickness', unit='μm', default=17.5, min=5.0, max=200.0, description='Thickness of the copper trace (plating + base)'),
        ),
        outputs=(
            OutputField(key='zdiff', label='Differential Impedance', unit='Ω', description='Differential impedance (2 × Zodd)'),
            OutputField(key='zcom', label='Common-Mode Impedance', unit='Ω', description='Common-mode impedance (Zeven / 2)'),
            OutputField(key='z0single', label='Single-Ended Impedance', unit='Ω', description='Uncoupled single-ended impedance (Hammerstad-Jensen)'),
            OutputField(key='zodd', label='Odd-Mode Impedance', unit='Ω', description='Odd-mode impedance (Zdiff / 2)'),
            OutputField(key='zeven', label='Even-Mode Impedance', unit='Ω', description='Even-mode impedance (2 × Zcom)'),
        ),
        keywords=('differential pair calculator', 'zdiff calculator', 'differential impedance pcb', 'edge coupled microstrip', 'usb impedance', 'hdmi impedance',),
    ),
    'via-calculator': CalculatorInfo(
        slug='via-calculator',
        title='PCB Via Calculator',
        category='pcb',
        description='Calculate PCB via impedance, capacitance, inductance, current capacity, aspect ratio, and DFM warnings. Covers through-hole and blind/buried vias.',
        inputs=(
            InputField(key='viaDiameter', label='Via Drill Diameter', unit='mm', default=0.3, min=0.1, max=6.0, description='Finished drill diameter of the via hole'),
            InputField(key='padDiameter', label='Pad Diameter', unit='mm', default=0.6, min=0.2, max=10.0, description='Copper pad diameter surrounding the via'),
            InputField(key='boardThickness', label='Board Thickness', unit='mm', default=1.6, min=0.1, max=10.0, description='Total PCB thickness (for aspect ratio and inductance)'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=4.2, min=1.0, max=20.0, description='Relative permittivity of the board material'),
            InputField(key='copperThickness', label='Copper Plating Thickness', unit='μm', default=25.0, min=5.0, max=100.0, description='Plated copper wall thickness inside the via barrel'),
            InputField(key='signalLayer', label='Signal Layer', unit='', default=0.0, min=0.0, max=1.0, description='0 = inner layer, 1 = outer layer'),
        ),
        outputs=(
            OutputField(key='impedance', label='Via Impedance', unit='Ω', description='Characteristic impedance of the via (coaxial approximation)'),
            OutputField(key='capacitancePF', label='Via Capacitance', unit='pF', description='Parasitic capacitance of the via (IPC-2141A)'),
            OutputField(key='inductanceNH', label='Via Inductance', unit='nH', description='Parasitic inductance of the via (Wheeler)'),
            OutputField(key='aspectRatio', label='Aspect Ratio', unit='', description='Board thickness / drill diameter. Keep ≤ 10:1 for reliable plating.'),
            OutputField(key='currentCapacityA', label='Current Capacity', unit='A', description='Estimated maximum current at 10°C temperature rise (IPC-2221)'),
        ),
        keywords=('pcb via calculator', 'via impedance', 'via capacitance', 'via inductance', 'via current capacity', 'pcb via design',),
    ),
    'stackup-builder': CalculatorInfo(
        slug='stackup-builder',
        title='PCB Stackup Impedance Calculator',
        category='pcb',
        description='Calculate characteristic impedance for common PCB stackup configurations. Select layer count, dielectric thickness, and copper weight to get target trace width for 50Ω or custom impedance.',
        inputs=(
            InputField(key='layerCount', label='Layer Count', unit='', default=4.0, min=2.0, max=8.0, description='Number of copper layers (even numbers only)'),
            InputField(key='targetImpedance', label='Target Impedance', unit='Ω', default=50.0, min=25.0, max=150.0, description='Target characteristic impedance for trace width calculation'),
            InputField(key='dielectricH1', label='Dielectric H1 (L1 to L2)', unit='mm', default=0.2, min=0.05, max=2.0, description='Prepreg thickness between L1 (top) and L2'),
            InputField(key='dielectricH2', label='Dielectric H2 (L2 to L3 core)', unit='mm', default=1.2, min=0.1, max=5.0, description='Core thickness between L2 and L3'),
            InputField(key='dielectricH3', label='Dielectric H3 (L3 to L4)', unit='mm', default=0.2, min=0.05, max=2.0, description='Prepreg thickness between L3 and L4 (bottom)'),
            InputField(key='copperWeight', label='Copper Weight', unit='oz', default=1.0, min=0.5, max=3.0, description='Copper foil weight (1 oz = 35 μm)'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=4.2, min=2.0, max=12.0, description='Relative permittivity of the board material at design frequency'),
        ),
        outputs=(
            OutputField(key='traceWidthL1mm', label='Trace Width L1 (surface)', unit='mm', description='Trace width for target impedance on L1 (surface microstrip over L2)'),
            OutputField(key='traceWidthL3mm', label='Trace Width L3 (inner)', unit='mm', description='Trace width for target impedance on L3 (inner microstrip referencing L2)'),
            OutputField(key='achievedImpedanceL1', label='Achieved Z₀ L1', unit='Ω', description='Actual impedance achieved with calculated L1 trace width (Hammerstad-Jensen verification)'),
            OutputField(key='achievedImpedanceL3', label='Achieved Z₀ L3', unit='Ω', description='Actual impedance achieved with calculated L3 trace width (Hammerstad-Jensen verification)'),
            OutputField(key='totalThicknessMm', label='Total Board Thickness', unit='mm', description='Sum of all dielectric layers (H1 + H2 + H3)'),
        ),
        keywords=('pcb stackup calculator', 'pcb layer stack', 'stackup impedance', 'pcb dielectric thickness', 'impedance control stackup',),
    ),
    'voltage-divider': CalculatorInfo(
        slug='voltage-divider',
        title='Voltage Divider Calculator',
        category='power',
        description='Calculate voltage divider output voltage, current, Thévenin impedance, and power dissipation from Vin, R1, and R2. Ideal for bias networks and level shifting.',
        inputs=(
            InputField(key='vin', label='Input Voltage', unit='V', default=5.0, min=0.0, max=1000.0, description=''),
            InputField(key='r1', label='R1 (top)', unit='Ω', default=10000.0, min=1.0, max=10000000.0, description=''),
            InputField(key='r2', label='R2 (bottom)', unit='Ω', default=10000.0, min=1.0, max=10000000.0, description=''),
        ),
        outputs=(
            OutputField(key='vout', label='Output Voltage', unit='V', description=''),
            OutputField(key='ratio', label='Division Ratio', unit='', description=''),
            OutputField(key='current', label='Quiescent Current', unit='A', description=''),
            OutputField(key='rThev', label='Thévenin Impedance', unit='Ω', description=''),
            OutputField(key='powerR1', label='Power in R1', unit='W', description=''),
            OutputField(key='powerR2', label='Power in R2', unit='W', description=''),
        ),
        keywords=('voltage divider calculator', 'resistor divider', 'voltage divider formula', 'thevenin impedance', 'vout calculator',),
    ),
    'led-resistor': CalculatorInfo(
        slug='led-resistor',
        title='LED Current Limiting Resistor Calculator',
        category='power',
        description='Calculate the correct current limiting resistor for an LED. Shows exact value, nearest E24 standard, actual current, and power dissipation.',
        inputs=(
            InputField(key='vSupply', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=48.0, description=''),
            InputField(key='vForward', label='LED Forward Voltage', unit='V', default=2.0, min=0.5, max=5.0, description=''),
            InputField(key='iForward', label='Desired Current', unit='mA', default=20.0, min=0.1, max=1000.0, description=''),
        ),
        outputs=(
            OutputField(key='rExact', label='Exact Resistance', unit='Ω', description=''),
            OutputField(key='rNearest', label='Nearest E24', unit='Ω', description=''),
            OutputField(key='iActual', label='Actual Current', unit='mA', description=''),
            OutputField(key='power', label='Power (exact R)', unit='W', description=''),
            OutputField(key='pNearest', label='Power (E24 R)', unit='W', description=''),
        ),
        keywords=('led resistor calculator', 'led current limiting resistor', 'led series resistor', 'led circuit calculator',),
    ),
    'buck-converter': CalculatorInfo(
        slug='buck-converter',
        title='Buck Converter Design Calculator',
        category='power',
        description='Design a synchronous buck (step-down) converter: calculate duty cycle, inductor value, output capacitor, input capacitor, and theoretical efficiency.',
        inputs=(
            InputField(key='vin', label='Input Voltage', unit='V', default=12.0, min=1.0, max=100.0, description=''),
            InputField(key='vout', label='Output Voltage', unit='V', default=5.0, min=0.5, max=99.0, description=''),
            InputField(key='iout', label='Output Current', unit='A', default=1.0, min=0.01, max=50.0, description=''),
            InputField(key='fsw', label='Switching Frequency', unit='kHz', default=500.0, min=10.0, max=5000.0, description=''),
            InputField(key='deltaIL', label='Inductor Current Ripple', unit='%', default=30.0, min=5.0, max=80.0, description='Inductor current ripple as % of output current. Typical: 20-40%.'),
            InputField(key='deltaVout', label='Output Voltage Ripple', unit='%', default=1.0, min=0.1, max=10.0, description='Output voltage ripple as % of Vout. Typical: 0.5-2%.'),
        ),
        outputs=(
            OutputField(key='dutyCycle', label='Duty Cycle', unit='%', description=''),
            OutputField(key='inductorUH', label='Minimum Inductance', unit='μH', description=''),
            OutputField(key='coutUF', label='Output Capacitance', unit='μF', description=''),
            OutputField(key='cinUF', label='Input Capacitance', unit='μF', description=''),
            OutputField(key='ilPeak', label='Peak Inductor Current', unit='A', description=''),
            OutputField(key='efficiency', label='Theoretical Efficiency', unit='%', description=''),
        ),
        keywords=('buck converter calculator', 'step down converter', 'dc dc converter design', 'inductor value buck', 'duty cycle calculator', 'switching regulator design',),
    ),
    'ldo-thermal': CalculatorInfo(
        slug='ldo-thermal',
        title='LDO Thermal Calculator',
        category='power',
        description='Calculate LDO regulator power dissipation, junction temperature, thermal margin, and minimum dropout voltage for thermal design validation.',
        inputs=(
            InputField(key='vin', label='Input Voltage', unit='V', default=5.0, min=0.5, max=60.0, description=''),
            InputField(key='vout', label='Output Voltage', unit='V', default=3.3, min=0.5, max=59.0, description=''),
            InputField(key='iload', label='Load Current', unit='mA', default=500.0, min=1.0, max=5000.0, description=''),
            InputField(key='thetaJA', label='Thermal Resistance θJA', unit='°C/W', default=50.0, min=1.0, max=500.0, description='θJA from datasheet. SOT-23: ~150°C/W, TO-252: ~50°C/W, TO-220: ~5°C/W'),
            InputField(key='tamb', label='Ambient Temperature', unit='°C', default=25.0, min=-40.0, max=85.0, description=''),
            InputField(key='tjMax', label='Max Junction Temperature', unit='°C', default=125.0, min=85.0, max=175.0, description=''),
        ),
        outputs=(
            OutputField(key='pdiss', label='Power Dissipation', unit='W', description=''),
            OutputField(key='tj', label='Junction Temperature', unit='°C', description=''),
            OutputField(key='margin', label='Thermal Headroom', unit='°C', description=''),
            OutputField(key='dropoutV', label='Dropout Voltage', unit='V', description=''),
            OutputField(key='efficiencyPct', label='Efficiency', unit='%', description=''),
        ),
        keywords=('ldo thermal calculator', 'linear regulator thermal', 'junction temperature', 'power dissipation ldo', 'thermal resistance', 'dropout voltage',),
    ),
    'battery-life': CalculatorInfo(
        slug='battery-life',
        title='Battery Life Calculator',
        category='power',
        description='Estimate battery runtime for IoT and portable devices given average current draw, duty cycle, self-discharge rate, and depth-of-discharge cutoff. Suitable for LiPo, alkaline, NiMH, and coin-cell batte',
        inputs=(
            InputField(key='capacity', label='Battery Capacity', unit='mAh', default=2000.0, min=1.0, max=100000.0, description=''),
            InputField(key='avgCurrent', label='Average Current Draw', unit='mA', default=100.0, min=0.001, max=10000.0, description='Average current drawn by the device during active operation'),
            InputField(key='dutyCycle', label='Duty Cycle', unit='%', default=100.0, min=0.001, max=100.0, description='Percentage of time the device is active and drawing current. 100% = continuous operation.'),
            InputField(key='selfDischarge', label='Self-Discharge Rate', unit='%/month', default=2.0, min=0.0, max=30.0, description='Monthly self-discharge rate of the battery. LiPo: ~2%, NiMH: ~15%, Alkaline: ~1%'),
            InputField(key='cutoffSoc', label='Cutoff State of Charge', unit='%', default=20.0, min=0.0, max=80.0, description='Minimum state of charge at which the device stops operating. 20% = device shuts off with 20% capacity remaining.'),
        ),
        outputs=(
            OutputField(key='runtimeHours', label='Runtime', unit='h', description='Estimated battery runtime in hours'),
            OutputField(key='runtimeDays', label='Runtime', unit='days', description='Estimated battery runtime in days'),
            OutputField(key='effectiveCurrent', label='Effective Current', unit='mA', description='Actual average current after applying duty cycle'),
            OutputField(key='usableCapacityMAh', label='Usable Capacity', unit='mAh', description='Capacity available after accounting for the cutoff state of charge'),
        ),
        keywords=('battery life calculator', 'battery runtime', 'iot battery life', 'duty cycle battery', 'mah runtime calculator', 'self-discharge battery', 'battery capacity hours',),
    ),
    'filter-designer': CalculatorInfo(
        slug='filter-designer',
        title='Passive RC/LC Filter Designer',
        category='signal',
        description='Design passive Butterworth and Chebyshev Type I (0.5 dB ripple) low-pass, high-pass, and band-pass filters up to order 10. Calculates all LC ladder element values, time constant, and stopband attenuat',
        inputs=(
            InputField(key='responseType', label='Response Type', unit='', default=0.0, min=0.0, max=1.0, description='0 = Butterworth (maximally flat), 1 = Chebyshev Type I (0.5 dB ripple, steeper rolloff)'),
            InputField(key='filterType', label='Filter Type', unit='', default=0.0, min=0.0, max=2.0, description='0 = Low-pass, 1 = High-pass, 2 = Band-pass'),
            InputField(key='fc', label='Cutoff Frequency', unit='Hz', default=1000.0, min=1.0, max=10000000.0, description='Filter cutoff frequency (-3dB point)'),
            InputField(key='order', label='Filter Order', unit='', default=2.0, min=1.0, max=10.0, description='Filter order (1–10). Higher orders give steeper rolloff: n × 20 dB/decade.'),
            InputField(key='impedance', label='Characteristic Impedance', unit='Ω', default=50.0, min=1.0, max=10000.0, description='Source/load impedance. 50 Ω is standard for RF systems; 600 Ω for audio.'),
            InputField(key='qFactor', label='Quality Factor', unit='', default=1.0, min=0.1, max=100.0, description='Higher Q = narrower bandwidth. Relevant for band-pass filter type (type=2).'),
            InputField(key='eSeries', label='E-Series Snapping', unit='', default=0.0, min=0.0, max=96.0, description='0 = Ideal values, 12 = E12 (10%), 24 = E24 (5%), 48 = E48 (2%), 96 = E96 (1%). Snaps component values to nearest standard value.'),
        ),
        outputs=(
            OutputField(key='C1_nF', label='Element 1 (C₁)', unit='nF', description='First shunt capacitor value for the filter prototype'),
            OutputField(key='L1_uH', label='Element 2 (L₂)', unit='μH', description='Second element — series inductor for the filter prototype'),
            OutputField(key='C3_nF', label='Element 3 (C₃)', unit='nF', description='Third element — shunt capacitor (order ≥ 3)'),
            OutputField(key='L4_uH', label='Element 4 (L₄)', unit='μH', description='Fourth element — series inductor (order ≥ 4)'),
            OutputField(key='C5_nF', label='Element 5 (C₅)', unit='nF', description='Fifth element — shunt capacitor (order ≥ 5)'),
            OutputField(key='L6_uH', label='Element 6 (L₆)', unit='μH', description='Sixth element — series inductor (order ≥ 6)'),
            OutputField(key='C7_nF', label='Element 7 (C₇)', unit='nF', description='Seventh element — shunt capacitor (order ≥ 7)'),
            OutputField(key='L8_uH', label='Element 8 (L₈)', unit='μH', description='Eighth element — series inductor (order ≥ 8)'),
            OutputField(key='C9_nF', label='Element 9 (C₉)', unit='nF', description='Ninth element — shunt capacitor (order ≥ 9)'),
            OutputField(key='L10_uH', label='Element 10 (L₁₀)', unit='μH', description='Tenth element — series inductor (order = 10)'),
            OutputField(key='tau_ns', label='Time Constant τ', unit='ns', description='RC time constant (1st-order Butterworth only)'),
            OutputField(key='attenuation_at_2fc', label='Attenuation at 2×fc', unit='dB', description='Stopband attenuation at twice the cutoff frequency'),
            OutputField(key='bandwidth_Hz', label='Bandwidth', unit='Hz', description='Band-pass filter 3dB bandwidth (band-pass mode only)'),
            OutputField(key='fLow_Hz', label='Lower -3dB Frequency', unit='Hz', description='Lower -3dB corner frequency (band-pass mode only)'),
            OutputField(key='fHigh_Hz', label='Upper -3dB Frequency', unit='Hz', description='Upper -3dB corner frequency (band-pass mode only)'),
            OutputField(key='maxComponentError', label='Max Component Error', unit='%', description='Largest deviation from ideal value after E-series snapping'),
            OutputField(key='fcShiftPercent', label='Est. Cutoff Shift', unit='%', description='Estimated shift in -3dB frequency due to component rounding'),
        ),
        keywords=('filter designer', 'rc filter calculator', 'lc filter', 'butterworth filter', 'chebyshev filter', 'low pass filter design', 'high pass filter', 'band pass filter', 'passive filter components', 'lc ladder',),
    ),
    'sampling-nyquist': CalculatorInfo(
        slug='sampling-nyquist',
        title='Nyquist Sampling Theorem Calculator',
        category='signal',
        description='Calculate Nyquist sampling rate, oversampling ratio, aliasing frequency, ADC dynamic range, SNR, and data rate. Verify that your sampling rate satisfies the Nyquist criterion and avoid aliasing in you',
        inputs=(
            InputField(key='signalFreq', label='Signal Bandwidth / Max Frequency', unit='Hz', default=10000.0, min=1.0, max=1000000000.0, description='Maximum frequency component in the signal (or signal bandwidth for baseband signals)'),
            InputField(key='samplingRate', label='Sampling Rate', unit='Sa/s', default=44100.0, min=1.0, max=1000000000000.0, description='Number of samples taken per second'),
            InputField(key='adcBits', label='ADC Resolution', unit='bits', default=16.0, min=4.0, max=24.0, description='Number of bits in the ADC. Each additional bit adds ~6 dB of dynamic range.'),
            InputField(key='channels', label='Number of Channels', unit='', default=1.0, min=1.0, max=32.0, description='Number of parallel ADC channels (e.g., 2 for stereo, 1 for mono)'),
        ),
        outputs=(
            OutputField(key='nyquistRate_Hz', label='Nyquist Rate', unit='Hz', description='Minimum sampling rate required to avoid aliasing (= 2 × signal bandwidth)'),
            OutputField(key='oversamplingRatio', label='Oversampling Ratio', unit='', description='Ratio of actual sampling rate to Nyquist rate. Values < 1 indicate aliasing.'),
            OutputField(key='aliasFreq_Hz', label='Alias Frequency', unit='Hz', description='Frequency at which aliased signal appears. Zero if no aliasing.'),
            OutputField(key='dynamicRangeDB', label='Dynamic Range', unit='dB', description='Theoretical dynamic range of the ADC: DR = 6.02×N + 1.76 dB'),
            OutputField(key='snr_dB', label='Ideal SNR', unit='dB', description='Signal-to-quantization-noise ratio for an ideal ADC at full scale'),
            OutputField(key='dataRateMbps', label='Raw Data Rate', unit='Mbps', description='Uncompressed raw data rate = sampling rate × ADC bits × channels'),
            OutputField(key='antiAliasingFC_Hz', label='Anti-Aliasing Filter fc', unit='Hz', description='Maximum anti-aliasing filter cutoff frequency (= fs / 2, the Nyquist frequency)'),
        ),
        keywords=('nyquist theorem calculator', 'sampling rate calculator', 'aliasing calculator', 'adc dynamic range', 'oversampling ratio', 'nyquist frequency', 'snr calculator', 'data rate calculator',),
    ),
    'dipole-antenna': CalculatorInfo(
        slug='dipole-antenna',
        title='Half-Wave Dipole Antenna Calculator',
        category='antenna',
        description='Calculate the physical length, wavelength, gain, radiation resistance, and 50Ω VSWR for a half-wave dipole antenna at any frequency. Supports velocity factor for insulated wire.',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=433.0, min=1.0, max=6000.0, description='Operating frequency in MHz'),
            InputField(key='velocityFactor', label='Velocity Factor', unit='', default=0.97, min=0.5, max=1.0, description='Free space ≈ 0.97; with insulation ~0.95'),
        ),
        outputs=(
            OutputField(key='halfWaveLength_mm', label='Half-Wave Length', unit='mm', description='Total dipole length for half-wave resonance'),
            OutputField(key='quarterWaveLength_mm', label='Quarter-Wave Length', unit='mm', description='Each dipole arm length (quarter wavelength)'),
            OutputField(key='gainDbi', label='Antenna Gain', unit='dBi', description='Theoretical gain of half-wave dipole (2.15 dBi)'),
            OutputField(key='inputImpedance_ohm', label='Input Impedance', unit='Ω', description='Centre-fed radiation resistance ≈ 73.1 Ω'),
            OutputField(key='feedpointVswr_50', label='VSWR (vs 50Ω)', unit=':1', description='VSWR when fed directly with 50Ω coax (no matching)'),
            OutputField(key='lambda_m', label='Free-Space Wavelength', unit='m', description=''),
        ),
        keywords=('dipole antenna calculator', 'half wave dipole', 'antenna length calculator', 'dipole length frequency', 'antenna design', 'radiation resistance', 'dipole gain dbi',),
    ),
    'patch-antenna': CalculatorInfo(
        slug='patch-antenna',
        title='Microstrip Patch Antenna Calculator',
        category='antenna',
        description='Calculate rectangular microstrip patch antenna dimensions (width, length) using the Transmission Line Model. Outputs effective dielectric constant, edge-feed impedance, and nominal gain for common sub',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='GHz', default=2.45, min=0.1, max=100.0, description='Operating frequency in GHz'),
            InputField(key='dielectricConstant', label='Dielectric Constant', unit='', default=4.4, min=1.0, max=30.0, description='FR4 ≈ 4.4; Rogers RO4003C ≈ 3.55; Air = 1'),
            InputField(key='substrateHeight', label='Substrate Height', unit='mm', default=1.6, min=0.1, max=10.0, description='Dielectric substrate thickness'),
            InputField(key='feedOffset', label='Feed Offset', unit='mm', default=0.0, min=0.0, max=50.0, description='0 = edge feed; adjust for 50Ω match (inset feed position)'),
        ),
        outputs=(
            OutputField(key='patchWidth_mm', label='Patch Width', unit='mm', description='Resonant patch width (determines polarisation direction)'),
            OutputField(key='patchLength_mm', label='Patch Length', unit='mm', description='Resonant patch length (determines resonant frequency)'),
            OutputField(key='effectiveDielectric', label='Effective Dielectric', unit='', description='Effective dielectric constant accounting for fringing fields'),
            OutputField(key='edgeFeedImpedance_ohm', label='Edge Feed Impedance', unit='Ω', description='Input impedance at the radiating edge (typically 100–300Ω)'),
            OutputField(key='gainDbi', label='Nominal Gain', unit='dBi', description='Typical single-element patch gain (6–8 dBi)'),
        ),
        keywords=('patch antenna calculator', 'microstrip patch antenna', 'patch antenna dimensions', 'rectangular patch antenna', 'antenna substrate', 'effective dielectric constant', 'fr4 antenna design',),
    ),
    'eirp-calculator': CalculatorInfo(
        slug='eirp-calculator',
        title='EIRP / ERP Regulatory Calculator',
        category='antenna',
        description='Calculate Effective Isotropic Radiated Power (EIRP) and ERP from transmit power, cable loss, and antenna gain. Check compliance against FCC, ETSI, and ISM-band regulatory limits.',
        inputs=(
            InputField(key='txPower_dbm', label='TX Power', unit='dBm', default=20.0, min=-30.0, max=60.0, description='Transmitter output power at the RF connector'),
            InputField(key='cableLoss_db', label='Cable / Connector Loss', unit='dB', default=1.0, min=0.0, max=30.0, description='Total feedline and connector losses (positive value)'),
            InputField(key='antennaGain_dbi', label='Antenna Gain', unit='dBi', default=2.15, min=-20.0, max=40.0, description='Antenna gain in dBi; 2.15 dBi = half-wave dipole'),
            InputField(key='regulatoryLimit_dbm', label='Regulatory EIRP Limit', unit='dBm', default=36.0, min=-20.0, max=60.0, description='Maximum permitted EIRP per applicable regulation'),
        ),
        outputs=(
            OutputField(key='eirp_dbm', label='EIRP', unit='dBm', description='Effective Isotropic Radiated Power = P_TX − L_cable + G_ant'),
            OutputField(key='erp_dbm', label='ERP', unit='dBm', description='Effective Radiated Power (relative to half-wave dipole): EIRP − 2.15 dB'),
            OutputField(key='eirp_w', label='EIRP', unit='W', description='EIRP in watts'),
            OutputField(key='margin_db', label='Regulatory Margin', unit='dB', description='Headroom below the regulatory limit; negative = non-compliant'),
            OutputField(key='maxPermittedGain_dbi', label='Max Permitted Antenna Gain', unit='dBi', description='Highest antenna gain that keeps EIRP within the regulatory limit'),
        ),
        keywords=('eirp calculator', 'effective isotropic radiated power', 'erp calculator', 'fcc part 15 eirp', 'etsi eirp limit', 'regulatory compliance rf', 'antenna gain eirp', 'transmit power calculator',),
    ),
    'ohms-law': CalculatorInfo(
        slug='ohms-law',
        title="Ohm's Law Calculator",
        category='general',
        description="Calculate voltage, current, resistance, and power using Ohm's Law. Enter any two values to solve for the remaining two quantities.",
        inputs=(
            InputField(key='voltage', label='Voltage', unit='V', default=5.0, min=0.0, max=1000000.0, description='Set to -1 to solve for this value'),
            InputField(key='current', label='Current', unit='A', default=-1.0, min=-1.0, max=1000000.0, description='Set to -1 to solve for this value'),
            InputField(key='resistance', label='Resistance', unit='Ω', default=1000.0, min=-1.0, max=1000000000000.0, description='Set to -1 to solve for this value'),
            InputField(key='power', label='Power', unit='W', default=-1.0, min=-1.0, max=1000000000000.0, description='Set to -1 to solve for this value'),
        ),
        outputs=(
            OutputField(key='voltage', label='Voltage', unit='V', description=''),
            OutputField(key='current', label='Current', unit='A', description=''),
            OutputField(key='resistance', label='Resistance', unit='Ω', description=''),
            OutputField(key='power', label='Power', unit='W', description=''),
        ),
        keywords=("ohm's law calculator", 'voltage current resistance', 'ohms law formula', 'V=IR calculator', 'power dissipation calculator',),
    ),
    'resistor-color-code': CalculatorInfo(
        slug='resistor-color-code',
        title='Resistor Color Code Calculator',
        category='general',
        description='Decode resistor color bands to resistance value and tolerance. Supports 4-band, 5-band, and 6-band resistors. Instant color band to ohms conversion.',
        inputs=(
            InputField(key='numBands', label='Number of Bands', unit='', default=4.0, min=4.0, max=6.0, description=''),
            InputField(key='band1', label='Band 1 (1st digit)', unit='', default=1.0, min=0.0, max=9.0, description='Color: 0=Blk 1=Brn 2=Red 3=Org 4=Yel 5=Grn 6=Blu 7=Vio 8=Gry 9=Wht'),
            InputField(key='band2', label='Band 2 (2nd digit)', unit='', default=0.0, min=0.0, max=9.0, description=''),
            InputField(key='band3', label='Band 3 (3rd digit / multiplier for 4-band)', unit='', default=4.0, min=0.0, max=11.0, description='For 4-band resistors this is actually the multiplier; for 5-band it is the 3rd digit'),
            InputField(key='multiplier', label='Multiplier Band', unit='', default=2.0, min=0.0, max=11.0, description='10=Gold(×0.1) 11=Silver(×0.01)'),
            InputField(key='tolerance', label='Tolerance Band', unit='', default=10.0, min=1.0, max=11.0, description=''),
        ),
        outputs=(
            OutputField(key='resistance', label='Resistance', unit='Ω', description=''),
            OutputField(key='tolerance', label='Tolerance', unit='%', description=''),
            OutputField(key='minResistance', label='Min Value', unit='Ω', description=''),
            OutputField(key='maxResistance', label='Max Value', unit='Ω', description=''),
        ),
        keywords=('resistor color code', 'resistor color calculator', 'color band resistor', 'resistor bands decoder', '4 band resistor', '5 band resistor',),
    ),
    'rc-time-constant': CalculatorInfo(
        slug='rc-time-constant',
        title='RC Time Constant Calculator',
        category='general',
        description='Calculate RC circuit time constant τ, charge time to 63.2% and 99%, and −3dB cutoff frequency. Essential for filter and timing circuit design.',
        inputs=(
            InputField(key='resistance', label='Resistance', unit='Ω', default=10000.0, min=1.0, max=1000000000.0, description=''),
            InputField(key='capacitance', label='Capacitance', unit='nF', default=100.0, min=0.001, max=1000000000.0, description=''),
        ),
        outputs=(
            OutputField(key='tauUs', label='Time Constant τ', unit='μs', description=''),
            OutputField(key='t63us', label='Time to 63.2%', unit='μs', description=''),
            OutputField(key='t99us', label='Time to 99%', unit='μs', description=''),
            OutputField(key='f3db', label='−3dB Frequency', unit='Hz', description=''),
        ),
        keywords=('rc time constant calculator', 'rc circuit', 'time constant tau', 'rc filter cutoff frequency', 'capacitor charge time',),
    ),
    'series-parallel-resistor': CalculatorInfo(
        slug='series-parallel-resistor',
        title='Series / Parallel Resistor, Capacitor & Inductor Calculator',
        category='general',
        description='Calculate the equivalent series and parallel combination of up to four resistors, capacitors, or inductors. Also computes the voltage divider ratio for two-resistor networks.',
        inputs=(
            InputField(key='r1', label='R1 (or C1 in nF / L1 in μH)', unit='Ω', default=1000.0, min=0.001, max=1000000000.0, description=''),
            InputField(key='r2', label='R2 (or C2 in nF / L2 in μH)', unit='Ω', default=1000.0, min=0.0, max=1000000000.0, description=''),
            InputField(key='r3', label='R3 (optional)', unit='Ω', default=0.0, min=0.0, max=1000000000.0, description='Set to 0 to ignore. R3 for 3-resistor combinations.'),
            InputField(key='r4', label='R4 (optional)', unit='Ω', default=0.0, min=0.0, max=1000000000.0, description='Set to 0 to ignore.'),
            InputField(key='componentType', label='Component Type', unit='', default=0.0, min=0.0, max=2.0, description='0=Resistor (Ω), 1=Capacitor (nF), 2=Inductor (μH)'),
        ),
        outputs=(
            OutputField(key='seriesTotal', label='Series Total', unit='Ω / nF / μH', description='Series Resistance (Ω) / Series Capacitance (nF) / Series Inductance (μH)'),
            OutputField(key='parallelTotal', label='Parallel Total', unit='Ω / nF / μH', description='Parallel Resistance (Ω) / Parallel Capacitance (nF) / Parallel Inductance (μH)'),
            OutputField(key='voltDividerRatio', label='Voltage Divider Ratio (R2 only)', unit='V/V', description='Output voltage as a fraction of input voltage (Vout/Vin = R2/(R1+R2)). Only valid for two-resistor networks.'),
        ),
        keywords=('series parallel resistor calculator', 'parallel resistor calculator', 'capacitor in series', 'capacitor in parallel', 'inductor series parallel', 'voltage divider ratio', 'equivalent resistance',),
    ),
    'lc-resonance': CalculatorInfo(
        slug='lc-resonance',
        title='LC Resonance Calculator',
        category='general',
        description='Calculate the resonant frequency, characteristic impedance, Q factor, and bandwidth of a series or parallel LC tank circuit. Enter inductance, capacitance, and optional series resistance.',
        inputs=(
            InputField(key='inductance', label='Inductance', unit='μH', default=10.0, min=0.001, max=1000000.0, description=''),
            InputField(key='capacitance', label='Capacitance', unit='pF', default=100.0, min=0.01, max=1000000000.0, description=''),
            InputField(key='resistance', label='Series Resistance', unit='Ω', default=0.0, min=0.0, max=10000.0, description='Series resistance for Q and bandwidth. Set 0 for ideal LC.'),
            InputField(key='circuitType', label='Circuit Type', unit='', default=0.0, min=0.0, max=1.0, description='0=Series LC, 1=Parallel LC (tank)'),
        ),
        outputs=(
            OutputField(key='f0_MHz', label='Resonant Frequency', unit='MHz', description=''),
            OutputField(key='characteristicImpedance_ohm', label='Characteristic Impedance', unit='Ω', description='Z₀ = √(L/C)'),
            OutputField(key='qFactor', label='Q Factor', unit='', description=''),
            OutputField(key='bandwidth_kHz', label='−3 dB Bandwidth', unit='kHz', description=''),
            OutputField(key='wavelength_m', label='Free-Space Wavelength', unit='m', description='Free-space wavelength at the resonant frequency: λ = c / f₀'),
        ),
        keywords=('lc resonance calculator', 'tank circuit frequency', 'lc circuit calculator', 'resonant frequency formula', 'q factor calculator', 'lc bandwidth', 'parallel resonance', 'series resonance',),
    ),
    'opamp-gain': CalculatorInfo(
        slug='opamp-gain',
        title='Op-Amp Gain & Bandwidth Calculator',
        category='general',
        description='Calculate op-amp voltage gain, gain in dB, −3 dB bandwidth, and input impedance for inverting, non-inverting, and differential amplifier configurations.',
        inputs=(
            InputField(key='configuration', label='Amplifier Configuration', unit='', default=1.0, min=0.0, max=2.0, description='0=Inverting, 1=Non-inverting, 2=Differential'),
            InputField(key='r1', label='R1 (feedback resistor Rf)', unit='kΩ', default=10.0, min=0.001, max=10000.0, description=''),
            InputField(key='r2', label='R2 (input resistor Rin)', unit='kΩ', default=1.0, min=0.001, max=10000.0, description=''),
            InputField(key='gbwProduct', label='Gain-Bandwidth Product', unit='MHz', default=1.0, min=0.001, max=10000.0, description='Op-amp gain-bandwidth product from datasheet. LM741=1MHz, TL071=3MHz, NE5534=10MHz'),
            InputField(key='supplyVoltage', label='Supply Voltage (total)', unit='V', default=15.0, min=1.8, max=60.0, description='Total supply: ±15V → enter 30V'),
        ),
        outputs=(
            OutputField(key='gain', label='Voltage Gain (V/V)', unit='V/V', description='Negative value indicates phase inversion (inverting configuration)'),
            OutputField(key='gainDb', label='Voltage Gain', unit='dB', description='Gain above 60 dB may cause instability or oscillation'),
            OutputField(key='f3db_kHz', label='−3 dB Bandwidth', unit='kHz', description=''),
            OutputField(key='inputImpedance_kohm', label='Input Impedance', unit='kΩ', description='Non-inverting ≈ ∞ (shown as 1e9 kΩ); Inverting = Rin; Differential = 2×Rin'),
            OutputField(key='maxOutputVpp', label='Max Output Swing (typ)', unit='Vpp', description='Typical maximum output swing ≈ 80% of total supply voltage'),
        ),
        keywords=('op amp gain calculator', 'operational amplifier gain', 'inverting amplifier gain', 'non-inverting amplifier', 'gain bandwidth product', 'opamp bandwidth calculator', 'differential amplifier gain',),
    ),
    'uart-baud-rate': CalculatorInfo(
        slug='uart-baud-rate',
        title='UART Baud Rate & Frame Timing Calculator',
        category='protocol',
        description='Calculate UART frame timing, throughput, and USART BRR register divisor from baud rate, data format, and MCU clock frequency. Identify baud rate error for reliable serial communication.',
        inputs=(
            InputField(key='baudRate', label='Baud Rate', unit='bps', default=115200.0, min=300.0, max=4000000.0, description='Serial baud rate in bits per second'),
            InputField(key='dataBits', label='Data Bits', unit='bits', default=8.0, min=5.0, max=9.0, description='Number of data bits per frame (typically 8)'),
            InputField(key='stopBits', label='Stop Bits', unit='bits', default=1.0, min=1.0, max=2.0, description='1 stop bit is standard; 2 may be used for slow receivers'),
            InputField(key='parity', label='Parity Bits', unit='bits', default=0.0, min=0.0, max=2.0, description='0 = None, 1 = Even or Odd parity (1 bit), 2 = Mark/Space (rare)'),
            InputField(key='clockFreq', label='MCU Clock Frequency', unit='MHz', default=16.0, min=1.0, max=1000.0, description='MCU peripheral (APB) clock frequency used for BRR divisor calculation'),
        ),
        outputs=(
            OutputField(key='frameBits', label='Bits per Frame', unit='bits', description='1 start + data bits + parity + stop bits'),
            OutputField(key='bitPeriod_us', label='Bit Period', unit='µs', description=''),
            OutputField(key='framePeriod_us', label='Frame Period', unit='µs', description=''),
            OutputField(key='framesPerSecond', label='Frames per Second', unit='fps', description=''),
            OutputField(key='throughputKbps', label='Data Throughput', unit='kbps', description='Effective data rate (data bits only, not overhead)'),
            OutputField(key='brrDivisor', label='BRR Divisor', unit='', description='USART BRR register value (16× oversampling); round to nearest integer'),
            OutputField(key='actualBaudRate', label='Actual Baud Rate', unit='bps', description='Baud rate achieved with the rounded integer BRR divisor'),
            OutputField(key='baudRateError_pct', label='Baud Rate Error', unit='%', description='Deviation of actual from target baud rate; keep below 2% for reliable operation'),
        ),
        keywords=('uart baud rate calculator', 'uart frame timing', 'usart brr register', 'baud rate error', 'serial communication calculator', 'uart bit period', 'uart throughput',),
    ),
    'i2c-pullup': CalculatorInfo(
        slug='i2c-pullup',
        title='I2C Pull-Up Resistor Calculator',
        category='protocol',
        description='Calculate I2C pull-up resistor values for Standard (100 kHz), Fast (400 kHz), and Fast-Plus (1 MHz) modes. Derives minimum, maximum, and recommended resistance from supply voltage and bus capacitance ',
        inputs=(
            InputField(key='vdd', label='Supply Voltage', unit='V', default=3.3, min=1.8, max=5.5, description='I2C bus supply voltage (pull-up rail)'),
            InputField(key='speedMode', label='Speed Mode', unit='', default=1.0, min=0.0, max=2.0, description='0 = Standard 100 kHz, 1 = Fast 400 kHz, 2 = Fast-Plus 1 MHz'),
            InputField(key='busCap', label='Bus Capacitance', unit='pF', default=100.0, min=10.0, max=400.0, description='Total bus capacitance including PCB traces and device pins'),
            InputField(key='numDevices', label='Number of Devices', unit='', default=2.0, min=1.0, max=16.0, description='Number of I2C devices on the bus (informational; affects stray capacitance estimate)'),
        ),
        outputs=(
            OutputField(key='R_max_ohm', label='R_pull Maximum', unit='Ω', description='Maximum pull-up for required rise time (t_r / (0.8473 × C_bus))'),
            OutputField(key='R_min_ohm', label='R_pull Minimum', unit='Ω', description='Minimum pull-up from sink current limit ((V_DD − V_OL) / I_OL)'),
            OutputField(key='R_recommended_ohm', label='Recommended R_pull', unit='Ω', description='Geometric mean of R_min and R_max; choose nearest standard E24/E96 value'),
            OutputField(key='current_ma', label='Bus Current (per line)', unit='mA', description='Static current drawn per line when the bus is at V_DD'),
            OutputField(key='powerPerLine_mw', label='Power per Line (low)', unit='mW', description='Approximate power dissipated in pull-up when line is held low'),
            OutputField(key='riseTimeTarget_ns', label='Rise Time Target', unit='ns', description='Maximum permitted rise time for the selected speed mode (NXP UM10204)'),
        ),
        keywords=('i2c pull up resistor calculator', 'i2c pullup resistor', 'i2c bus capacitance', 'i2c rise time', 'scl sda pull up', 'nxp um10204', 'i2c fast mode', 'i2c fast-plus',),
    ),
    'clock-jitter': CalculatorInfo(
        slug='clock-jitter',
        title='Clock Tree Jitter Budget Calculator',
        category='protocol',
        description='Calculate clock tree timing budget for FPGA and SoC designs. Enter reference oscillator jitter, PLL noise floor, buffer stages, and target clock frequency to compute setup margin.',
        inputs=(
            InputField(key='clockFreqMHz', label='Clock Frequency', unit='MHz', default=200.0, min=0.001, max=10000.0, description='Target clock frequency at the destination register'),
            InputField(key='setupTime_ps', label='Register Setup Time', unit='ps', default=80.0, min=0.0, max=5000.0, description='From device datasheet — minimum setup time before clock edge'),
            InputField(key='holdTime_ps', label='Register Hold Time', unit='ps', default=40.0, min=0.0, max=5000.0, description='From device datasheet — minimum hold time after clock edge'),
            InputField(key='refJitter_ps', label='Reference Oscillator Jitter', unit='ps', default=50.0, min=0.0, max=10000.0, description='RMS jitter of TCXO or VCTCXO — from oscillator datasheet'),
            InputField(key='pllJitter_ps', label='PLL Added Jitter', unit='ps', default=100.0, min=0.0, max=10000.0, description='RMS jitter added by PLL — from PLL datasheet or simulation'),
            InputField(key='bufferJitter_ps', label='Clock Buffer Jitter', unit='ps', default=25.0, min=0.0, max=1000.0, description='Additive jitter per clock buffer stage (e.g. CDCLVP1204: 20 ps)'),
            InputField(key='bufferStages', label='Buffer Stages', unit='', default=2.0, min=0.0, max=10.0, description='Number of clock buffer/fanout stages between PLL and destination'),
            InputField(key='traceDelay_ps', label='PCB Trace Skew', unit='ps', default=20.0, min=0.0, max=1000.0, description='Clock tree routing skew — 150 ps/inch on FR4 at 6 mil trace'),
        ),
        outputs=(
            OutputField(key='setupMargin_ps', label='Setup Margin', unit='ps', description=''),
            OutputField(key='totalJitter_ps', label='Total Jitter', unit='ps', description=''),
            OutputField(key='budgetUsed_pct', label='Budget Used', unit='%', description=''),
            OutputField(key='availableBudget_ps', label='Available Budget', unit='ps', description=''),
            OutputField(key='periodPs', label='Clock Period', unit='ps', description=''),
        ),
        keywords=('clock jitter', 'timing budget', 'setup time', 'hold time', 'PLL jitter', 'clock tree', 'FPGA timing', 'phase noise',),
    ),
    'heatsink-calculator': CalculatorInfo(
        slug='heatsink-calculator',
        title='Heatsink Calculator',
        category='thermal',
        description='Calculate required heatsink thermal resistance and junction temperature for power devices',
        inputs=(
            InputField(key='powerDissipation', label='Power Dissipation', unit='W', default=5.0, min=0.0, max=None, description=''),
            InputField(key='maxJunctionTemp', label='Max Junction Temperature', unit='°C', default=125.0, min=25.0, max=200.0, description=''),
            InputField(key='ambientTemp', label='Ambient Temperature', unit='°C', default=25.0, min=-40.0, max=85.0, description=''),
            InputField(key='thetaJC', label='Junction-to-Case Resistance', unit='°C/W', default=2.0, min=0.1, max=None, description='Junction-to-case thermal resistance from datasheet'),
            InputField(key='thetaCS', label='Case-to-Heatsink Resistance', unit='°C/W', default=0.5, min=0.0, max=None, description='Case-to-heatsink thermal resistance (thermal pad/grease)'),
        ),
        outputs=(
            OutputField(key='thetaSA_required', label='Required θ_SA', unit='°C/W', description='Required heatsink-to-ambient thermal resistance — lower is better'),
            OutputField(key='junctionTemp', label='Junction Temperature', unit='°C', description=''),
            OutputField(key='thetaJA_total', label='Total θ_JA', unit='°C/W', description=''),
            OutputField(key='tempRise', label='Temperature Rise', unit='°C', description=''),
        ),
        keywords=('heatsink', 'thermal resistance', 'junction temperature', 'θJA', 'θJC', 'θCS', 'thermal management', 'power dissipation',),
    ),
    'pcb-trace-temp': CalculatorInfo(
        slug='pcb-trace-temp',
        title='PCB Trace Temperature Rise',
        category='thermal',
        description='Calculate PCB copper trace temperature rise under load current using IPC-2152',
        inputs=(
            InputField(key='current', label='Current', unit='A', default=3.0, min=0.0, max=None, description=''),
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=2.0, min=0.1, max=None, description=''),
            InputField(key='copperWeight', label='Copper Weight', unit='oz', default=1.0, min=0.5, max=None, description=''),
            InputField(key='ambientTemp', label='Ambient Temperature', unit='°C', default=25.0, min=None, max=None, description=''),
            InputField(key='traceLength', label='Trace Length', unit='mm', default=100.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='tempRise', label='Temperature Rise', unit='°C', description=''),
            OutputField(key='maxTemp', label='Maximum Trace Temperature', unit='°C', description=''),
            OutputField(key='traceResistance', label='Trace Resistance', unit='mΩ', description=''),
            OutputField(key='powerDissipated', label='Power Dissipated', unit='mW', description=''),
            OutputField(key='currentCapacity', label='Current Capacity (ΔT=10°C)', unit='A', description=''),
        ),
        keywords=('PCB trace temperature', 'IPC-2152', 'trace heating', 'copper trace', 'current capacity', 'thermal',),
    ),
    'dc-motor-speed': CalculatorInfo(
        slug='dc-motor-speed',
        title='DC Motor Speed Calculator',
        category='motor',
        description='Calculate DC motor speed, torque, power, and efficiency from electrical parameters',
        inputs=(
            InputField(key='voltage', label='Supply Voltage', unit='V', default=12.0, min=0.0, max=None, description=''),
            InputField(key='resistance', label='Armature Resistance', unit='Ω', default=0.5, min=0.01, max=None, description='Armature resistance'),
            InputField(key='backEmfConst', label='Back-EMF Constant', unit='V/RPM', default=0.01, min=0.0001, max=None, description='Back-EMF constant'),
            InputField(key='torqueConst', label='Torque Constant', unit='N·m/A', default=0.1, min=0.001, max=None, description='Torque constant'),
            InputField(key='loadTorque', label='Load Torque', unit='N·m', default=0.1, min=0.0, max=None, description=''),
            InputField(key='efficiency', label='Mechanical Efficiency', unit='%', default=85.0, min=10.0, max=100.0, description=''),
        ),
        outputs=(
            OutputField(key='noLoadSpeed', label='No-Load Speed', unit='RPM', description=''),
            OutputField(key='loadSpeed', label='Speed Under Load', unit='RPM', description=''),
            OutputField(key='current', label='Armature Current', unit='A', description=''),
            OutputField(key='outputPower', label='Output Power', unit='W', description=''),
            OutputField(key='inputPower', label='Input Power', unit='W', description=''),
            OutputField(key='torque', label='Torque', unit='N·m', description=''),
            OutputField(key='efficiencyPct', label='Overall Efficiency', unit='%', description=''),
        ),
        keywords=('DC motor', 'motor speed', 'RPM', 'motor torque', 'back EMF', 'motor efficiency', 'BLDC',),
    ),
    'stepper-motor': CalculatorInfo(
        slug='stepper-motor',
        title='Stepper Motor Calculator',
        category='motor',
        description='Calculate stepper motor speed, step frequency, and travel per revolution',
        inputs=(
            InputField(key='stepsPerRev', label='Steps per Revolution', unit='steps', default=200.0, min=4.0, max=None, description=''),
            InputField(key='microstepping', label='Microstepping Divisor', unit='', default=16.0, min=1.0, max=None, description=''),
            InputField(key='targetRPM', label='Target Speed', unit='RPM', default=60.0, min=0.1, max=None, description=''),
            InputField(key='leadScrewPitch', label='Lead Screw Pitch', unit='mm/rev', default=2.0, min=0.0, max=None, description='Lead screw pitch — set to 0 for rotation only'),
        ),
        outputs=(
            OutputField(key='stepFrequency', label='Step Frequency', unit='Hz', description=''),
            OutputField(key='effectiveSteps', label='Effective Steps/Rev', unit='steps', description=''),
            OutputField(key='linearSpeed', label='Linear Speed', unit='mm/s', description=''),
            OutputField(key='stepAngle', label='Step Angle', unit='°', description=''),
        ),
        keywords=('stepper motor', 'steps per revolution', 'step frequency', 'motor speed', 'microstepping', 'CNC', '3D printer',),
    ),
    'shielding-effectiveness': CalculatorInfo(
        slug='shielding-effectiveness',
        title='Shielding Effectiveness Calculator',
        category='emc',
        description='Calculate electromagnetic shielding effectiveness of conductive enclosures',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=1000.0, min=0.001, max=None, description=''),
            InputField(key='thickness', label='Shield Thickness', unit='mm', default=1.0, min=0.001, max=None, description=''),
            InputField(key='conductivity', label='Conductivity', unit='MS/m', default=59.6, min=0.001, max=None, description=''),
            InputField(key='permeability', label='Relative Permeability', unit='', default=1.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='absorptionLoss', label='Absorption Loss', unit='dB', description=''),
            OutputField(key='reflectionLoss', label='Reflection Loss', unit='dB', description=''),
            OutputField(key='totalSE', label='Total Shielding Effectiveness', unit='dB', description=''),
            OutputField(key='skinDepth', label='Skin Depth', unit='μm', description=''),
            OutputField(key='thicknessVsSkin', label='Thickness / Skin Depth Ratio', unit='', description=''),
        ),
        keywords=('shielding effectiveness', 'EMC', 'EMI shielding', 'RF enclosure', 'skin depth', 'absorption loss', 'reflection loss',),
    ),
    'wire-gauge': CalculatorInfo(
        slug='wire-gauge',
        title='Wire Gauge Calculator (AWG)',
        category='general',
        description='Convert between AWG and mm², calculate wire current capacity, resistance, and voltage drop',
        inputs=(
            InputField(key='awg', label='Wire Gauge', unit='AWG', default=22.0, min=0.0, max=40.0, description=''),
            InputField(key='current', label='Current', unit='A', default=1.0, min=0.0, max=None, description=''),
            InputField(key='length', label='Wire Length', unit='m', default=1.0, min=0.0, max=None, description=''),
            InputField(key='resistivity', label='Resistivity', unit='Ω·mm²/m', default=0.01724, min=None, max=None, description='Copper = 0.01724, Aluminum = 0.0282'),
        ),
        outputs=(
            OutputField(key='diameter', label='Wire Diameter', unit='mm', description=''),
            OutputField(key='crossSection', label='Cross-Section Area', unit='mm²', description=''),
            OutputField(key='resistance', label='Wire Resistance', unit='Ω', description=''),
            OutputField(key='voltageDrop', label='Voltage Drop', unit='V', description=''),
            OutputField(key='currentCapacity', label='Current Capacity', unit='A', description=''),
        ),
        keywords=('AWG', 'wire gauge', 'wire current capacity', 'wire resistance', 'American Wire Gauge', 'mm2 to AWG', 'cable sizing',),
    ),
    'capacitor-energy': CalculatorInfo(
        slug='capacitor-energy',
        title='Capacitor Energy & Charge Calculator',
        category='general',
        description='Calculate energy stored, charge, and current in capacitors for power supply design',
        inputs=(
            InputField(key='capacitance', label='Capacitance', unit='μF', default=100.0, min=0.001, max=None, description=''),
            InputField(key='voltage', label='Voltage', unit='V', default=12.0, min=0.0, max=None, description=''),
            InputField(key='chargeTime', label='Charge Time', unit='ms', default=10.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='energy', label='Stored Energy', unit='mJ', description=''),
            OutputField(key='charge', label='Stored Charge', unit='mC', description=''),
            OutputField(key='avgChargeCurrent', label='Average Charge Current', unit='mA', description=''),
            OutputField(key='chargePower', label='Charge Power', unit='mW', description=''),
        ),
        keywords=('capacitor energy', 'capacitor charge', 'E = 1/2 CV^2', 'capacitor calculator', 'capacitor current', 'energy storage',),
    ),
    'power-factor': CalculatorInfo(
        slug='power-factor',
        title='Power Factor Calculator',
        category='power',
        description='Calculate power factor, reactive power, and correction capacitor for AC circuits',
        inputs=(
            InputField(key='apparentPower', label='Apparent Power', unit='VA', default=1000.0, min=0.0, max=None, description=''),
            InputField(key='powerFactor', label='Power Factor', unit='', default=0.8, min=0.01, max=1.0, description=''),
            InputField(key='voltage', label='Supply Voltage', unit='V', default=230.0, min=1.0, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='Hz', default=50.0, min=1.0, max=None, description=''),
            InputField(key='targetPF', label='Target Power Factor', unit='', default=0.95, min=0.5, max=1.0, description='Target power factor after correction'),
        ),
        outputs=(
            OutputField(key='realPower', label='Real Power', unit='W', description=''),
            OutputField(key='reactivePower', label='Reactive Power', unit='VAR', description=''),
            OutputField(key='pfAngle', label='Phase Angle', unit='°', description=''),
            OutputField(key='correctionCapacitor', label='Correction Capacitor', unit='μF', description=''),
        ),
        keywords=('power factor', 'reactive power', 'apparent power', 'VAR', 'power factor correction', 'capacitor bank', 'AC power',),
    ),
    'q-factor': CalculatorInfo(
        slug='q-factor',
        title='Q Factor Calculator for Inductors & Capacitors',
        category='rf',
        description='Calculate quality factor (Q) for inductors and capacitors, resonant circuit bandwidth, and equivalent series resistance',
        inputs=(
            InputField(key='componentType', label='Component Type', unit='', default=0.0, min=0.0, max=1.0, description=''),
            InputField(key='value', label='Inductance / Capacitance', unit='μH / nF', default=10.0, min=0.001, max=None, description=''),
            InputField(key='esr', label='Equivalent Series Resistance', unit='Ω', default=0.5, min=0.001, max=None, description='Equivalent Series Resistance from datasheet'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=10.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='qFactor', label='Q Factor', unit='', description=''),
            OutputField(key='reactance', label='Reactance', unit='Ω', description=''),
            OutputField(key='bandwidth', label='Bandwidth', unit='kHz', description=''),
            OutputField(key='halfPowerFreqLow', label='Lower Half-Power Frequency', unit='MHz', description=''),
            OutputField(key='halfPowerFreqHigh', label='Upper Half-Power Frequency', unit='MHz', description=''),
        ),
        keywords=('Q factor', 'quality factor', 'inductor Q', 'capacitor Q', 'ESR', 'bandwidth', 'resonant circuit', 'tank circuit',),
    ),
    'waveguide-cutoff': CalculatorInfo(
        slug='waveguide-cutoff',
        title='Rectangular Waveguide Cutoff Frequency Calculator',
        category='rf',
        description='Calculate cutoff frequencies for rectangular waveguide TE and TM modes, guide wavelength, and phase velocity',
        inputs=(
            InputField(key='width', label='Waveguide Width', unit='mm', default=22.86, min=0.1, max=None, description=''),
            InputField(key='height', label='Waveguide Height', unit='mm', default=10.16, min=0.1, max=None, description=''),
            InputField(key='frequency', label='Operating Frequency', unit='GHz', default=10.0, min=0.1, max=None, description=''),
            InputField(key='modeM', label='Mode Index m', unit='', default=1.0, min=0.0, max=5.0, description=''),
            InputField(key='modeN', label='Mode Index n', unit='', default=0.0, min=0.0, max=5.0, description=''),
        ),
        outputs=(
            OutputField(key='cutoffFreq', label='Cutoff Frequency', unit='GHz', description=''),
            OutputField(key='guideWavelength', label='Guide Wavelength', unit='mm', description=''),
            OutputField(key='phaseVelocity', label='Phase Velocity', unit='×c', description=''),
            OutputField(key='groupVelocity', label='Group Velocity', unit='×c', description=''),
            OutputField(key='betaPropagates', label='Propagating', unit='(1=yes)', description=''),
        ),
        keywords=('waveguide', 'cutoff frequency', 'TE10 mode', 'rectangular waveguide', 'guide wavelength', 'phase velocity', 'microwave',),
    ),
    'zener-diode': CalculatorInfo(
        slug='zener-diode',
        title='Zener Diode Voltage Regulator Calculator',
        category='general',
        description='Calculate series resistor, power dissipation, and load current for zener diode voltage regulators',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage', unit='V', default=12.0, min=0.0, max=None, description=''),
            InputField(key='zenerVoltage', label='Zener Voltage', unit='V', default=5.1, min=0.1, max=None, description=''),
            InputField(key='loadCurrent', label='Load Current', unit='mA', default=20.0, min=0.0, max=None, description=''),
            InputField(key='zenerCurrentMin', label='Minimum Zener Current', unit='mA', default=5.0, min=0.1, max=None, description='Minimum zener current for regulation (from datasheet)'),
            InputField(key='zenerPowerMax', label='Max Zener Power Rating', unit='mW', default=500.0, min=10.0, max=None, description='Maximum zener power rating'),
        ),
        outputs=(
            OutputField(key='seriesResistor', label='Series Resistor', unit='Ω', description=''),
            OutputField(key='zenerCurrent', label='Zener Current', unit='mA', description=''),
            OutputField(key='zenerPower', label='Zener Power Dissipation', unit='mW', description=''),
            OutputField(key='totalCurrent', label='Total Current', unit='mA', description=''),
            OutputField(key='e24Resistor', label='Nearest E24 Resistor', unit='Ω', description=''),
        ),
        keywords=('zener diode', 'voltage regulator', 'zener voltage', 'series resistor', 'voltage stabilizer', '5.1V zener', 'shunt regulator',),
    ),
    'inductor-energy': CalculatorInfo(
        slug='inductor-energy',
        title='Inductor Energy & Time Constant Calculator',
        category='general',
        description='Calculate energy stored in an inductor, L/R time constant, and current rise time',
        inputs=(
            InputField(key='inductance', label='Inductance', unit='μH', default=100.0, min=0.001, max=None, description=''),
            InputField(key='current', label='Current', unit='A', default=1.0, min=0.0, max=None, description=''),
            InputField(key='resistance', label='Series Resistance', unit='Ω', default=10.0, min=0.001, max=None, description='Series resistance (winding + external)'),
            InputField(key='targetCurrent', label='Target Current', unit='%', default=63.2, min=1.0, max=99.0, description='Target current as % of final value'),
        ),
        outputs=(
            OutputField(key='energy', label='Stored Energy', unit='μJ', description=''),
            OutputField(key='timeConst', label='Time Constant', unit='μs', description=''),
            OutputField(key='riseTime', label='Rise Time to Target', unit='μs', description=''),
            OutputField(key='peakVoltage', label='Initial Back-EMF', unit='V', description=''),
            OutputField(key='saturationCheck', label='Saturation Check (I × L)', unit='μH·A', description=''),
        ),
        keywords=('inductor energy', 'L/R time constant', 'E = 1/2 LI^2', 'inductor current', 'inductor calculator', 'energy storage', 'flyback',),
    ),
    'boost-converter': CalculatorInfo(
        slug='boost-converter',
        title='Boost Converter Design Calculator',
        category='power',
        description='Calculate duty cycle, inductor value, and output capacitor for boost (step-up) DC-DC converter design',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage', unit='V', default=5.0, min=0.5, max=None, description=''),
            InputField(key='outputVoltage', label='Output Voltage', unit='V', default=12.0, min=1.0, max=None, description=''),
            InputField(key='outputCurrent', label='Output Current', unit='A', default=0.5, min=0.01, max=None, description=''),
            InputField(key='switchFreq', label='Switching Frequency', unit='kHz', default=100.0, min=1.0, max=None, description=''),
            InputField(key='ripplePct', label='Inductor Current Ripple', unit='%', default=30.0, min=5.0, max=80.0, description='Inductor current ripple as % of average inductor current'),
            InputField(key='efficiency', label='Estimated Efficiency', unit='%', default=88.0, min=50.0, max=99.0, description=''),
        ),
        outputs=(
            OutputField(key='dutyCycle', label='Duty Cycle', unit='%', description=''),
            OutputField(key='inductorCurrent', label='Average Inductor Current', unit='A', description=''),
            OutputField(key='inductorValue', label='Inductor Value', unit='μH', description=''),
            OutputField(key='outputCapacitor', label='Output Capacitor', unit='μF', description=''),
            OutputField(key='peakCurrent', label='Peak Inductor Current', unit='A', description=''),
        ),
        keywords=('boost converter', 'step-up converter', 'duty cycle', 'inductor selection', 'output capacitor', 'SMPS', 'DC-DC',),
    ),
    'three-phase-power': CalculatorInfo(
        slug='three-phase-power',
        title='Three-Phase Power Calculator',
        category='power',
        description='Calculate three-phase real power, reactive power, apparent power, current, and power factor from line or phase values',
        inputs=(
            InputField(key='connectionType', label='Connection Type', unit='', default=0.0, min=0.0, max=1.0, description=''),
            InputField(key='lineVoltage', label='Line Voltage', unit='V', default=400.0, min=1.0, max=None, description=''),
            InputField(key='current', label='Line Current', unit='A', default=10.0, min=0.0, max=None, description=''),
            InputField(key='powerFactor', label='Power Factor', unit='', default=0.85, min=0.01, max=1.0, description=''),
        ),
        outputs=(
            OutputField(key='phaseVoltage', label='Phase Voltage', unit='V', description=''),
            OutputField(key='realPower', label='Real Power', unit='kW', description=''),
            OutputField(key='reactivePower', label='Reactive Power', unit='kVAR', description=''),
            OutputField(key='apparentPower', label='Apparent Power', unit='kVA', description=''),
            OutputField(key='pfAngle', label='Power Factor Angle', unit='°', description=''),
        ),
        keywords=('three phase power', '3 phase', 'line voltage', 'phase voltage', 'kVA', 'kW', 'kVAR', 'motor power', 'industrial power',),
    ),
    'antenna-beamwidth': CalculatorInfo(
        slug='antenna-beamwidth',
        title='Antenna Beamwidth & Gain Calculator',
        category='antenna',
        description='Calculate antenna 3dB beamwidth from gain, aperture efficiency, and frequency for aperture antennas',
        inputs=(
            InputField(key='gain', label='Antenna Gain', unit='dBi', default=20.0, min=0.0, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='GHz', default=10.0, min=0.1, max=None, description=''),
            InputField(key='apertureDiameter', label='Aperture Diameter', unit='m', default=0.3, min=0.001, max=None, description='Physical aperture diameter (for dish/horn antennas)'),
            InputField(key='apertureEfficiency', label='Aperture Efficiency', unit='%', default=55.0, min=10.0, max=100.0, description='Typical: 55-65% for parabolic dish'),
        ),
        outputs=(
            OutputField(key='beamwidthHPBW', label='3 dB Beamwidth', unit='°', description=''),
            OutputField(key='beamwidthNulls', label='First Null Beamwidth', unit='°', description=''),
            OutputField(key='effectiveArea', label='Effective Aperture Area', unit='m²', description=''),
            OutputField(key='wavelength', label='Wavelength', unit='mm', description=''),
            OutputField(key='gainFromAperture', label='Gain from Aperture', unit='dBi', description=''),
        ),
        keywords=('antenna beamwidth', '3dB beamwidth', 'antenna gain', 'aperture antenna', 'half-power beamwidth', 'HPBW', 'directivity',),
    ),
    'snr-calculator': CalculatorInfo(
        slug='snr-calculator',
        title='Signal-to-Noise Ratio (SNR) Calculator',
        category='signal',
        description='Calculate SNR, noise floor, sensitivity, and dynamic range for RF receivers and signal chains',
        inputs=(
            InputField(key='bandwidth', label='Bandwidth', unit='MHz', default=1.0, min=0.001, max=None, description=''),
            InputField(key='noiseFigure', label='Noise Figure', unit='dB', default=6.0, min=0.0, max=None, description=''),
            InputField(key='signalPower', label='Signal Power', unit='dBm', default=-60.0, min=-160.0, max=30.0, description=''),
            InputField(key='temperature', label='Temperature', unit='K', default=290.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='noiseFloor', label='Noise Floor', unit='dBm', description=''),
            OutputField(key='snr', label='Signal-to-Noise Ratio', unit='dB', description=''),
            OutputField(key='sensitivity', label='Receiver Sensitivity', unit='dBm', description=''),
            OutputField(key='dynamicRange', label='Dynamic Range', unit='dB', description=''),
            OutputField(key='thermalNoise', label='Thermal Noise (kTB)', unit='dBm', description=''),
        ),
        keywords=('SNR', 'signal to noise ratio', 'noise floor', 'receiver sensitivity', 'dynamic range', 'noise figure', 'kTB',),
    ),
    'controlled-impedance': CalculatorInfo(
        slug='controlled-impedance',
        title='PCB Controlled Impedance Calculator',
        category='pcb',
        description='Calculate characteristic impedance for surface microstrip, embedded microstrip, and stripline PCB traces',
        inputs=(
            InputField(key='traceType', label='Trace Type', unit='', default=0.0, min=0.0, max=2.0, description=''),
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=1.8, min=0.05, max=None, description=''),
            InputField(key='substrateHeight', label='Substrate Height', unit='mm', default=0.2, min=0.01, max=None, description=''),
            InputField(key='dielectricConst', label='Dielectric Constant', unit='', default=4.4, min=1.0, max=None, description=''),
            InputField(key='copperThickness', label='Copper Thickness', unit='μm', default=35.0, min=5.0, max=None, description=''),
            InputField(key='coverHeight', label='Cover Layer Height', unit='mm', default=0.1, min=0.01, max=None, description='Cover layer height (for embedded microstrip only)'),
        ),
        outputs=(
            OutputField(key='impedance', label='Characteristic Impedance', unit='Ω', description=''),
            OutputField(key='effectiveDielectric', label='Effective Dielectric Constant', unit='', description=''),
            OutputField(key='propagationDelay', label='Propagation Delay', unit='ps/mm', description=''),
            OutputField(key='traceWidthFor50', label='Trace Width for 50Ω', unit='mm', description=''),
        ),
        keywords=('controlled impedance', 'microstrip impedance', 'stripline impedance', 'PCB impedance', 'signal integrity', '50 ohm trace',),
    ),
    'ferrite-bead': CalculatorInfo(
        slug='ferrite-bead',
        title='Ferrite Bead Filter Calculator',
        category='emc',
        description='Calculate ferrite bead filter effectiveness, impedance at frequency, and insertion loss for EMI suppression',
        inputs=(
            InputField(key='impedance100MHz', label='Impedance at 100 MHz', unit='Ω', default=600.0, min=1.0, max=None, description='Ferrite bead impedance at 100 MHz from datasheet (e.g. 600Ω for Murata BLM18PG601SN1)'),
            InputField(key='dcResistance', label='DC Resistance', unit='Ω', default=0.3, min=0.001, max=None, description='DC resistance from datasheet'),
            InputField(key='loadImpedance', label='Load Impedance', unit='Ω', default=50.0, min=1.0, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='MHz', default=100.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='beadImpedance', label='Bead Impedance at f', unit='Ω', description=''),
            OutputField(key='insertionLoss', label='Insertion Loss', unit='dB', description=''),
            OutputField(key='voltageDivider', label='Voltage Ratio', unit='%', description=''),
            OutputField(key='dcVoltageDrop', label='DC Voltage Drop', unit='mV/A', description=''),
        ),
        keywords=('ferrite bead', 'EMI filter', 'ferrite impedance', 'common mode choke', 'EMC', 'power line filter', 'Murata BLM',),
    ),
    'free-space-path-loss': CalculatorInfo(
        slug='free-space-path-loss',
        title='Free-Space Path Loss Calculator',
        category='rf',
        description='Calculate free-space path loss (FSPL) using the Friis transmission equation for wireless link budget analysis',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=2400.0, min=0.1, max=None, description='Signal frequency in MHz'),
            InputField(key='distance', label='Distance', unit='km', default=1.0, min=0.001, max=None, description='Distance between transmitter and receiver in km'),
        ),
        outputs=(
            OutputField(key='fspl_dB', label='Free-Space Path Loss', unit='dB', description=''),
            OutputField(key='fspl_linear', label='FSPL (linear ratio)', unit='', description=''),
        ),
        keywords=('free space path loss', 'Friis', 'FSPL', 'RF propagation', 'wireless link', 'path loss', 'link budget', 'propagation loss',),
    ),
    'radar-range-equation': CalculatorInfo(
        slug='radar-range-equation',
        title='Radar Range Equation Calculator',
        category='rf',
        description='Calculate maximum radar detection range using the radar range equation, including RCS, antenna gain, noise figure, and bandwidth parameters',
        inputs=(
            InputField(key='peakPower', label='Peak Transmit Power', unit='kW', default=100.0, min=0.001, max=None, description='Peak transmitter output power in kilowatts'),
            InputField(key='gain', label='Antenna Gain', unit='dBi', default=30.0, min=0.0, max=None, description='Transmit/receive antenna gain (same antenna assumed)'),
            InputField(key='frequency', label='Frequency', unit='GHz', default=3.0, min=0.1, max=None, description=''),
            InputField(key='rcs', label='Radar Cross Section (RCS)', unit='m²', default=1.0, min=0.001, max=None, description='Target radar cross section in square meters'),
            InputField(key='noiseFigure', label='Receiver Noise Figure', unit='dB', default=6.0, min=0.0, max=None, description='Receiver noise figure in dB'),
            InputField(key='bandwidth', label='Receiver Bandwidth', unit='MHz', default=1.0, min=0.001, max=None, description='Receiver noise bandwidth in MHz'),
        ),
        outputs=(
            OutputField(key='maxRange', label='Maximum Detection Range', unit='km', description=''),
            OutputField(key='snrAtMaxRange', label='SNR at Max Range', unit='dB', description='SNR equals 0 dB (unity) at maximum detection range by definition'),
            OutputField(key='receivedPower', label='Received Power at 1 km', unit='dBm', description=''),
        ),
        keywords=('radar range equation', 'radar cross section', 'RCS', 'radar SNR', 'maximum range', 'radar sensitivity', 'target detection',),
    ),
    'power-amplifier-efficiency': CalculatorInfo(
        slug='power-amplifier-efficiency',
        title='Power Amplifier Efficiency Calculator (PAE & Drain Efficiency)',
        category='rf',
        description='Calculate RF power amplifier efficiency including power-added efficiency (PAE), drain efficiency, DC power consumption, and heat dissipation',
        inputs=(
            InputField(key='outputPower', label='Output Power', unit='dBm', default=30.0, min=None, max=None, description='RF output power in dBm (30 dBm = 1 W)'),
            InputField(key='inputPower', label='Input Power', unit='dBm', default=0.0, min=None, max=None, description='RF input drive power in dBm'),
            InputField(key='dcVoltage', label='DC Supply Voltage', unit='V', default=5.0, min=0.1, max=None, description='DC bias supply voltage'),
            InputField(key='dcCurrent', label='DC Supply Current', unit='mA', default=500.0, min=0.1, max=None, description='DC current draw from supply in mA'),
        ),
        outputs=(
            OutputField(key='gain', label='Gain', unit='dB', description=''),
            OutputField(key='dcPower', label='DC Power Consumed', unit='mW', description=''),
            OutputField(key='pae', label='Power-Added Efficiency', unit='%', description=''),
            OutputField(key='drainEfficiency', label='Drain Efficiency', unit='%', description=''),
            OutputField(key='dissipatedPower', label='Dissipated Power (Heat)', unit='mW', description=''),
        ),
        keywords=('power amplifier efficiency', 'PAE', 'drain efficiency', 'RF amplifier', 'power added efficiency', 'amplifier gain', 'DC power',),
    ),
    'intermodulation-distortion': CalculatorInfo(
        slug='intermodulation-distortion',
        title='Intermodulation Distortion & IP3 Calculator',
        category='rf',
        description='Calculate third-order intercept point (IP3), intermodulation distortion products, and spurious-free dynamic range for RF amplifiers and mixers',
        inputs=(
            InputField(key='outputPower', label='Output Power', unit='dBm', default=10.0, min=None, max=None, description='Fundamental output power per tone in dBm'),
            InputField(key='inputPower', label='Input Power', unit='dBm', default=0.0, min=None, max=None, description='Input drive power per tone in dBm'),
            InputField(key='oip3', label='Output IP3 (OIP3)', unit='dBm', default=30.0, min=None, max=None, description='Output third-order intercept point from datasheet'),
            InputField(key='oip2', label='Output IP2 (OIP2)', unit='dBm', default=50.0, min=None, max=None, description='Output second-order intercept point. Higher = less IM2 distortion.'),
            InputField(key='freq1', label='Tone 1 Frequency', unit='MHz', default=100.0, min=0.1, max=None, description='First test tone frequency for two-tone analysis'),
            InputField(key='freq2', label='Tone 2 Frequency', unit='MHz', default=101.0, min=0.1, max=None, description='Second test tone frequency'),
        ),
        outputs=(
            OutputField(key='iip3', label='Input IP3 (IIP3)', unit='dBm', description=''),
            OutputField(key='im3Power', label='IM3 Product Power', unit='dBm', description=''),
            OutputField(key='im3Ratio', label='IM3 to Carrier Ratio', unit='dBc', description=''),
            OutputField(key='dynamicRange', label='Spurious-Free Dynamic Range', unit='dB', description=''),
            OutputField(key='iip2', label='Input IP2 (IIP2)', unit='dBm', description=''),
            OutputField(key='im2Power', label='IM2 Product Power', unit='dBm', description=''),
            OutputField(key='im2Ratio', label='IM2 to Carrier Ratio', unit='dBc', description=''),
            OutputField(key='im3Low', label='IM3 Low (2f₁−f₂)', unit='MHz', description=''),
            OutputField(key='im3High', label='IM3 High (2f₂−f₁)', unit='MHz', description=''),
            OutputField(key='im2Sum', label='IM2 Sum (f₁+f₂)', unit='MHz', description=''),
            OutputField(key='im2Diff', label='IM2 Diff (|f₁−f₂|)', unit='MHz', description=''),
            OutputField(key='toneSpacing', label='Tone Spacing', unit='MHz', description=''),
        ),
        keywords=('intermodulation distortion', 'IP3', 'IIP3', 'OIP3', 'third order intercept', 'IMD', 'IM3', 'dynamic range',),
    ),
    'phase-noise-to-jitter': CalculatorInfo(
        slug='phase-noise-to-jitter',
        title='Phase Noise to Jitter Converter',
        category='rf',
        description='Convert oscillator phase noise (dBc/Hz) to RMS jitter and cycle-to-cycle jitter by integrating over a specified offset frequency range',
        inputs=(
            InputField(key='carrierFreq', label='Carrier Frequency', unit='MHz', default=100.0, min=0.001, max=None, description='Oscillator carrier frequency in MHz'),
            InputField(key='phaseNoise', label='Phase Noise', unit='dBc/Hz', default=-120.0, min=None, max=0.0, description='Single-sideband phase noise spectral density at a representative offset'),
            InputField(key='offsetFreqLow', label='Integration Start (Offset Low)', unit='kHz', default=1.0, min=0.001, max=None, description='Lower integration limit for phase noise bandwidth'),
            InputField(key='offsetFreqHigh', label='Integration End (Offset High)', unit='kHz', default=10000.0, min=1.0, max=None, description='Upper integration limit for phase noise bandwidth'),
            InputField(key='profileMode', label='Profile Mode', unit='', default=0.0, min=0.0, max=1.0, description='0 = Single flat phase noise, 1 = Multi-point profile for accurate integration'),
            InputField(key='offset2', label='Offset Point 2', unit='kHz', default=10.0, min=0.001, max=None, description=''),
            InputField(key='pn2', label='Phase Noise Point 2', unit='dBc/Hz', default=-140.0, min=None, max=0.0, description=''),
            InputField(key='offset3', label='Offset Point 3', unit='kHz', default=100.0, min=0.001, max=None, description=''),
            InputField(key='pn3', label='Phase Noise Point 3', unit='dBc/Hz', default=-155.0, min=None, max=0.0, description=''),
            InputField(key='offset4', label='Offset Point 4', unit='kHz', default=1000.0, min=0.001, max=None, description=''),
            InputField(key='pn4', label='Phase Noise Point 4', unit='dBc/Hz', default=-165.0, min=None, max=0.0, description=''),
        ),
        outputs=(
            OutputField(key='rmsJitter', label='RMS Jitter', unit='ps', description=''),
            OutputField(key='cycleToCycleJitter', label='Cycle-to-Cycle Jitter', unit='ps', description=''),
            OutputField(key='phaseNoisePower', label='Integrated Phase Noise Power', unit='dBc', description=''),
            OutputField(key='rmsPhaseError', label='RMS Phase Error', unit='deg', description=''),
            OutputField(key='adcSnrLimit', label='ADC SNR Limit (Jitter)', unit='dB', description='Maximum achievable ADC SNR limited by clock jitter at this carrier frequency'),
        ),
        keywords=('phase noise', 'jitter', 'oscillator noise', 'clock jitter', 'phase noise to jitter', 'RMS jitter', 'dBc/Hz', 'integrated phase noise',),
    ),
    'vibration-phase-noise': CalculatorInfo(
        slug='vibration-phase-noise',
        title='Phase Noise Under Vibrations Calculator',
        category='rf',
        description='Calculate vibration-induced phase noise degradation for oscillators on defense, aerospace, and mobile platforms using acceleration sensitivity (Gamma) and vibration profiles',
        inputs=(
            InputField(key='carrierFreq', label='Carrier Frequency', unit='GHz', default=10.0, min=0.001, max=None, description='Oscillator carrier frequency in GHz'),
            InputField(key='vibSensitivity', label='Acceleration Sensitivity', unit='ppb/g', default=1.0, min=0.001, max=100.0, description='Oscillator acceleration sensitivity (Gamma) in parts per billion per g'),
            InputField(key='vibAccel', label='Vibration Acceleration', unit='g rms', default=1.0, min=0.001, max=50.0, description='RMS vibration acceleration level in g'),
            InputField(key='vibFreq', label='Vibration Frequency', unit='Hz', default=100.0, min=1.0, max=10000.0, description='Vibration frequency or offset frequency at which to evaluate phase noise'),
        ),
        outputs=(
            OutputField(key='lvib', label='Sinusoidal Vibration Phase Noise', unit='dBc/Hz', description=''),
            OutputField(key='lRandom', label='Random Vibration Phase Noise', unit='dBc/Hz', description=''),
            OutputField(key='freqDev', label='Peak Frequency Deviation', unit='Hz', description=''),
            OutputField(key='degradation', label='Degradation vs Quiescent', unit='dB', description=''),
        ),
        keywords=('vibration phase noise', 'acceleration sensitivity', 'gamma', 'OCXO vibration', 'MIL-STD-810', 'oscillator vibration', 'microphonics', 'phase noise degradation', 'defense oscillator', 'aerospace phase noise',),
    ),
    'return-loss-error': CalculatorInfo(
        slug='return-loss-error',
        title='Return Loss Measurement Error Calculator',
        category='rf',
        description='Calculate measurement uncertainty for return loss measurements using directional couplers or bridges. Accounts for coupler directivity and source match errors critical for VNA and test engineering.',
        inputs=(
            InputField(key='dutReturnLoss', label='DUT Return Loss', unit='dB', default=20.0, min=0.0, max=60.0, description='Return loss of the device under test'),
            InputField(key='directivity', label='Coupler Directivity', unit='dB', default=35.0, min=10.0, max=60.0, description='Directivity of the directional coupler or bridge used for the measurement'),
            InputField(key='sourceMatch', label='Source Match', unit='dB', default=30.0, min=10.0, max=60.0, description='Return loss of the measurement source port (how well the source is matched)'),
        ),
        outputs=(
            OutputField(key='rlMax', label='Best-Case RL', unit='dB', description='Highest return loss you might measure (errors cancel)'),
            OutputField(key='rlMin', label='Worst-Case RL', unit='dB', description='Lowest return loss you might measure (errors add)'),
            OutputField(key='uncertaintyDb', label='Measurement Uncertainty', unit='dB', description=''),
            OutputField(key='dirError', label='Directivity Error', unit='dB', description='Error from coupler directivity only'),
        ),
        keywords=('return loss error', 'measurement uncertainty', 'directional coupler directivity', 'vna measurement error', 'source match error', 'reflection coefficient uncertainty', 'rf measurement accuracy',),
    ),
    'adc-snr': CalculatorInfo(
        slug='adc-snr',
        title='ADC SNR and ENOB Calculator',
        category='signal',
        description='Calculate analog-to-digital converter signal-to-noise ratio, effective number of bits (ENOB), and SFDR including aperture jitter effects',
        inputs=(
            InputField(key='bits', label='ADC Resolution', unit='bits', default=12.0, min=1.0, max=24.0, description=''),
            InputField(key='inputFreq', label='Input Signal Frequency', unit='MHz', default=1.0, min=0.001, max=None, description='Frequency of the input analog signal being sampled'),
            InputField(key='samplingFreq', label='Sampling Frequency', unit='MHz', default=10.0, min=0.001, max=None, description='ADC sample rate (must be > 2× input frequency)'),
            InputField(key='jitter', label='Aperture Jitter', unit='ps', default=1.0, min=0.001, max=None, description='RMS aperture jitter of the ADC sampling clock in picoseconds'),
        ),
        outputs=(
            OutputField(key='theoreticalSnr', label='Theoretical SNR (Quantization)', unit='dB', description=''),
            OutputField(key='snrWithJitter', label='Effective SNR (with Jitter)', unit='dB', description=''),
            OutputField(key='enob', label='Effective Number of Bits', unit='bits', description=''),
            OutputField(key='sfdr', label='SFDR (estimate)', unit='dBc', description=''),
            OutputField(key='noisePower', label='Noise Floor', unit='dBFS', description=''),
        ),
        keywords=('ADC SNR', 'ENOB', 'effective number of bits', 'ADC noise', 'quantization noise', 'aperture jitter', 'SFDR', 'ADC dynamic range',),
    ),
    'fft-bin-resolution': CalculatorInfo(
        slug='fft-bin-resolution',
        title='FFT Bin Resolution & Spectral Analysis Calculator',
        category='signal',
        description='Calculate FFT frequency bin resolution, Nyquist range, time record length, noise floor processing gain, and window scalloping loss',
        inputs=(
            InputField(key='sampleRate', label='Sample Rate', unit='kHz', default=44.1, min=0.001, max=None, description=''),
            InputField(key='fftSize', label='FFT Size', unit='points', default=1024.0, min=8.0, max=None, description='Number of FFT points (power of 2 recommended)'),
            InputField(key='windowType', label='Window Function', unit='', default=1.0, min=0.0, max=2.0, description=''),
        ),
        outputs=(
            OutputField(key='binResolution', label='Frequency Bin Resolution', unit='Hz', description=''),
            OutputField(key='frequencyRange', label='Frequency Range (Nyquist)', unit='kHz', description=''),
            OutputField(key='timeRecord', label='Time Record Length', unit='ms', description=''),
            OutputField(key='noiseFloor', label='FFT Processing Gain', unit='dB', description='Noise floor improvement from coherent FFT integration'),
            OutputField(key='scalloping', label='Scalloping Loss', unit='dB', description=''),
        ),
        keywords=('FFT resolution', 'bin width', 'frequency resolution', 'spectral analysis', 'DFT', 'windowing', 'scalloping loss', 'noise floor',),
    ),
    'johnson-noise': CalculatorInfo(
        slug='johnson-noise',
        title='Johnson-Nyquist Thermal Noise Calculator',
        category='signal',
        description='Calculate thermal noise voltage, noise power, and noise spectral density for resistors using the Johnson-Nyquist noise formula',
        inputs=(
            InputField(key='resistance', label='Resistance', unit='Ω', default=50.0, min=0.001, max=None, description=''),
            InputField(key='temperature', label='Temperature', unit='°C', default=25.0, min=-273.0, max=None, description='Physical temperature of the resistor'),
            InputField(key='bandwidth', label='Noise Bandwidth', unit='MHz', default=1.0, min=1e-06, max=None, description='Measurement or system bandwidth'),
        ),
        outputs=(
            OutputField(key='noiseVoltage', label='RMS Noise Voltage', unit='nV', description=''),
            OutputField(key='noisePower', label='Available Noise Power', unit='dBm', description=''),
            OutputField(key='noisePowerDensity', label='Noise Power Density', unit='dBm/Hz', description='kT in dBm/Hz (−174 dBm/Hz at 290 K)'),
            OutputField(key='noiseCurrentDensity', label='Noise Current Density', unit='pA/√Hz', description=''),
        ),
        keywords=('Johnson noise', 'thermal noise', 'Nyquist noise', 'resistor noise', 'noise figure', 'kTB noise', 'noise floor', 'noise voltage density',),
    ),
    'am-modulation-index': CalculatorInfo(
        slug='am-modulation-index',
        title='AM Modulation Index Calculator',
        category='signal',
        description='Calculate amplitude modulation index, sidebands, bandwidth, and power efficiency for AM radio signals',
        inputs=(
            InputField(key='carrierAmplitude', label='Carrier Amplitude', unit='V', default=1.0, min=0.001, max=None, description='Peak amplitude of the carrier signal'),
            InputField(key='messageAmplitude', label='Message Amplitude', unit='V', default=0.5, min=0.0, max=None, description='Peak amplitude of the modulating signal'),
            InputField(key='carrierFreq', label='Carrier Frequency', unit='kHz', default=1000.0, min=0.001, max=None, description='Carrier signal frequency (e.g. 1000 kHz = 1 MHz AM band)'),
            InputField(key='messageFreq', label='Message Frequency', unit='kHz', default=1.0, min=0.001, max=None, description='Modulating signal (audio) frequency'),
        ),
        outputs=(
            OutputField(key='modulationIndex', label='Modulation Index', unit='%', description='100% = full modulation; >100% causes overmodulation distortion'),
            OutputField(key='upperSideband', label='Upper Sideband (USB)', unit='kHz', description=''),
            OutputField(key='lowerSideband', label='Lower Sideband (LSB)', unit='kHz', description=''),
            OutputField(key='bandwidth', label='Bandwidth', unit='kHz', description=''),
            OutputField(key='powerEfficiency', label='Power Efficiency', unit='%', description=''),
            OutputField(key='sidebandsToCarrier', label='Sideband / Carrier Ratio', unit='dB', description=''),
        ),
        keywords=('AM modulation', 'amplitude modulation index', 'AM bandwidth', 'sidebands', 'modulation depth', 'carrier power', 'DSB', 'AM radio',),
    ),
    'fm-modulation-index': CalculatorInfo(
        slug='fm-modulation-index',
        title='FM Modulation Index & Bandwidth Calculator',
        category='signal',
        description="Calculate FM modulation index, bandwidth using Carson's rule, Bessel bandwidth, and SNR improvement over AM",
        inputs=(
            InputField(key='frequencyDeviation', label='Frequency Deviation', unit='kHz', default=75.0, min=0.001, max=None, description='Peak frequency deviation of the FM signal'),
            InputField(key='messageFreq', label='Message Frequency', unit='kHz', default=15.0, min=0.001, max=None, description='Highest modulating signal frequency'),
            InputField(key='carrierFreq', label='Carrier Frequency', unit='MHz', default=100.0, min=0.001, max=None, description='Carrier frequency (informational)'),
        ),
        outputs=(
            OutputField(key='modulationIndex', label='Modulation Index (β)', unit='', description=''),
            OutputField(key='carsonBandwidth', label="Carson's Rule Bandwidth", unit='kHz', description=''),
            OutputField(key='besselBandwidth', label='Bessel Bandwidth', unit='kHz', description=''),
            OutputField(key='snrImprovement', label='SNR Improvement', unit='dB', description='FM SNR improvement over AM: 10·log₁₀(3β²(β+1))'),
        ),
        keywords=('FM modulation index', 'frequency deviation', "Carson's rule", 'FM bandwidth', 'FM SNR', 'frequency modulation', 'beta factor', 'WBFM',),
    ),
    'oversampling-snr': CalculatorInfo(
        slug='oversampling-snr',
        title='Oversampling & Noise Shaping SNR Calculator',
        category='signal',
        description='Calculate SNR improvement from oversampling and noise shaping for sigma-delta ADCs, including effective bits gained from higher OSR',
        inputs=(
            InputField(key='bits', label='Base ADC Resolution', unit='bits', default=12.0, min=1.0, max=24.0, description='Underlying quantizer resolution'),
            InputField(key='oversamplingRatio', label='Oversampling Ratio', unit='', default=64.0, min=1.0, max=None, description='Ratio of sampling rate to Nyquist rate'),
            InputField(key='noiseShapingOrder', label='Noise Shaping Order', unit='', default=1.0, min=0.0, max=5.0, description='0 = no shaping (simple oversampling), 1 = 1st order, 2 = 2nd order, etc.'),
        ),
        outputs=(
            OutputField(key='baseSnr', label='Base SNR (Nyquist)', unit='dB', description=''),
            OutputField(key='oversampledSnr', label='Oversampled SNR', unit='dB', description=''),
            OutputField(key='effectiveBits', label='Effective Bits', unit='bits', description=''),
            OutputField(key='snrImprovement', label='SNR Improvement', unit='dB', description=''),
        ),
        keywords=('oversampling', 'noise shaping', 'sigma-delta', 'OSR', 'ADC resolution improvement', 'delta-sigma', 'effective bits', 'quantization noise',),
    ),
    'digital-filter-order': CalculatorInfo(
        slug='digital-filter-order',
        title='Digital Filter Order Calculator',
        category='signal',
        description='Calculate minimum filter order for Butterworth, Chebyshev, and elliptic (Cauer) low-pass filters given passband ripple and stopband attenuation requirements',
        inputs=(
            InputField(key='passbandFreq', label='Passband Edge Frequency', unit='Hz', default=1000.0, min=1.0, max=None, description='Frequency where passband ripple specification is met'),
            InputField(key='stopbandFreq', label='Stopband Edge Frequency', unit='Hz', default=2000.0, min=1.0, max=None, description='Frequency where stopband attenuation must be achieved'),
            InputField(key='passbandRipple', label='Passband Ripple', unit='dB', default=3.0, min=0.01, max=None, description='Maximum allowed ripple in the passband (typically 0.1–3 dB)'),
            InputField(key='stopbandAttenuation', label='Stopband Attenuation', unit='dB', default=40.0, min=1.0, max=None, description='Minimum attenuation required in the stopband'),
        ),
        outputs=(
            OutputField(key='butterworthOrder', label='Butterworth Order', unit='', description=''),
            OutputField(key='chebyshevOrder', label='Chebyshev Order', unit='', description=''),
            OutputField(key='ellipticOrder', label='Elliptic Order (approx)', unit='', description=''),
            OutputField(key='transitionRatio', label='Transition Ratio', unit='', description=''),
        ),
        keywords=('filter order', 'Butterworth filter', 'Chebyshev filter', 'elliptic filter', 'filter design', 'low pass filter', 'stopband attenuation', 'passband ripple',),
    ),
    'yagi-antenna': CalculatorInfo(
        slug='yagi-antenna',
        title='Yagi-Uda Antenna Design Calculator',
        category='antenna',
        description='Calculate Yagi-Uda antenna element dimensions, gain, and impedance for a given frequency and number of elements',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=144.0, min=1.0, max=None, description='Operating frequency in MHz'),
            InputField(key='numElements', label='Number of Elements', unit='', default=5.0, min=2.0, max=20.0, description='Total number of elements including reflector, driver, and directors'),
            InputField(key='boomLength', label='Boom Length', unit='m', default=1.0, min=0.01, max=None, description='Physical boom length (informational for layout)'),
        ),
        outputs=(
            OutputField(key='gain', label='Estimated Gain', unit='dBi', description=''),
            OutputField(key='driverLength', label='Driver (Dipole) Length', unit='mm', description=''),
            OutputField(key='reflectorLength', label='Reflector Length', unit='mm', description=''),
            OutputField(key='directorLength', label='Director Length', unit='mm', description=''),
            OutputField(key='spacing', label='Element Spacing (0.2λ)', unit='mm', description=''),
            OutputField(key='impedance', label='Feed Impedance (approx)', unit='Ω', description=''),
        ),
        keywords=('Yagi antenna', 'Yagi-Uda', 'directional antenna', 'antenna elements', 'antenna gain', 'VHF UHF antenna', 'beam antenna',),
    ),
    'horn-antenna': CalculatorInfo(
        slug='horn-antenna',
        title='Horn Antenna Gain & Beamwidth Calculator',
        category='antenna',
        description='Calculate pyramidal horn antenna gain, E-plane and H-plane half-power beamwidths, and effective aperture area for microwave applications',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='GHz', default=10.0, min=0.1, max=None, description='Operating frequency in GHz'),
            InputField(key='apertureWidth', label='Aperture Width (H-plane)', unit='mm', default=50.0, min=1.0, max=None, description='Aperture dimension in the H-plane (horizontal)'),
            InputField(key='apertureHeight', label='Aperture Height (E-plane)', unit='mm', default=40.0, min=1.0, max=None, description='Aperture dimension in the E-plane (vertical)'),
        ),
        outputs=(
            OutputField(key='gain', label='Gain', unit='dBi', description=''),
            OutputField(key='hpbwE', label='HPBW (E-plane)', unit='degrees', description=''),
            OutputField(key='hpbwH', label='HPBW (H-plane)', unit='degrees', description=''),
            OutputField(key='effectiveArea', label='Effective Aperture Area', unit='cm²', description=''),
            OutputField(key='wavelength', label='Wavelength', unit='mm', description=''),
        ),
        keywords=('horn antenna', 'aperture antenna', 'gain', 'beamwidth', 'microwave antenna', 'pyramidal horn', 'HPBW', 'aperture efficiency',),
    ),
    'parabolic-dish-antenna': CalculatorInfo(
        slug='parabolic-dish-antenna',
        title='Parabolic Dish Antenna Calculator',
        category='antenna',
        description='Calculate parabolic dish antenna gain, half-power beamwidth (HPBW), effective aperture area, and noise temperature for satellite and microwave links',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='GHz', default=12.0, min=0.1, max=None, description='Operating frequency in GHz'),
            InputField(key='diameter', label='Dish Diameter', unit='m', default=1.2, min=0.01, max=None, description='Reflector diameter in meters'),
            InputField(key='efficiency', label='Aperture Efficiency', unit='%', default=55.0, min=1.0, max=100.0, description='Typical values: 50–65% for commercial dishes'),
        ),
        outputs=(
            OutputField(key='gain', label='Antenna Gain', unit='dBi', description=''),
            OutputField(key='hpbw', label='Half-Power Beamwidth', unit='degrees', description=''),
            OutputField(key='effectiveArea', label='Effective Aperture Area', unit='m²', description=''),
            OutputField(key='noiseTemperature', label='Antenna Noise Temperature', unit='K', description=''),
        ),
        keywords=('parabolic dish', 'satellite antenna', 'dish gain', 'aperture efficiency', 'HPBW', 'dish antenna', 'G/T ratio', 'satellite dish',),
    ),
    'loop-antenna': CalculatorInfo(
        slug='loop-antenna',
        title='Loop Antenna Calculator',
        category='antenna',
        description='Calculate small loop antenna radiation resistance, loss resistance, gain, Q factor, and operating bandwidth for HF and VHF applications',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=7.0, min=0.1, max=None, description='Operating frequency in MHz'),
            InputField(key='diameter', label='Loop Diameter', unit='m', default=1.0, min=0.01, max=None, description='Diameter of the loop structure in meters'),
            InputField(key='conductorDiam', label='Conductor Diameter', unit='mm', default=10.0, min=0.1, max=None, description='Diameter of the conductor tube or wire in mm'),
        ),
        outputs=(
            OutputField(key='circumference', label='Loop Circumference', unit='m', description=''),
            OutputField(key='radiation_resistance', label='Radiation Resistance', unit='Ω', description=''),
            OutputField(key='loss_resistance', label='Loss Resistance', unit='Ω', description=''),
            OutputField(key='gain', label='Gain (small loop)', unit='dBi', description=''),
            OutputField(key='bandwidth', label='-3 dB Bandwidth', unit='kHz', description=''),
        ),
        keywords=('loop antenna', 'magnetic loop', 'small loop antenna', 'radiation resistance', 'Q factor', 'HF antenna', 'magnetic loop antenna',),
    ),
    'spi-timing': CalculatorInfo(
        slug='spi-timing',
        title='SPI Timing & Signal Integrity Calculator',
        category='protocol',
        description='Calculate SPI bus timing parameters including bit period, frame time, maximum clock frequency limited by trace capacitance, and signal slew rate',
        inputs=(
            InputField(key='clockFreq', label='SPI Clock Frequency', unit='MHz', default=10.0, min=0.001, max=None, description='SPI SCLK frequency in MHz'),
            InputField(key='dataWidth', label='Data Word Width', unit='bits', default=8.0, min=1.0, max=32.0, description='Number of data bits per SPI frame'),
            InputField(key='traceCapacitance', label='Trace Capacitance', unit='pF', default=20.0, min=0.1, max=None, description='Estimated total capacitive load on the signal line (PCB trace + receiver)'),
            InputField(key='driveStrength', label='Drive Strength', unit='mA', default=4.0, min=0.1, max=None, description='GPIO output drive current capability in mA'),
        ),
        outputs=(
            OutputField(key='bitPeriod', label='Bit Period', unit='ns', description=''),
            OutputField(key='framePeriod', label='Frame Period', unit='μs', description=''),
            OutputField(key='maxFreqCapacitive', label='Max Freq (RC-limited)', unit='MHz', description=''),
            OutputField(key='slewRate', label='Signal Slew Rate', unit='V/ns', description=''),
            OutputField(key='dataRate', label='Data Rate', unit='Mbps', description=''),
        ),
        keywords=('SPI timing', 'SPI clock', 'serial peripheral interface', 'SPI frequency', 'signal integrity', 'slew rate', 'RC time constant', 'digital timing',),
    ),
    'can-bus-timing': CalculatorInfo(
        slug='can-bus-timing',
        title='CAN Bus Bit Timing Calculator',
        category='protocol',
        description='Calculate CAN bus bit timing parameters including prescaler, time quanta, sync segment, propagation segment, and phase buffer segments for a given baud rate and sample point',
        inputs=(
            InputField(key='clockFreq', label='System Clock Frequency', unit='MHz', default=48.0, min=1.0, max=None, description='Microcontroller peripheral clock frequency feeding the CAN controller'),
            InputField(key='baudRate', label='CAN Baud Rate', unit='kbps', default=500.0, min=1.0, max=None, description='Target CAN bus baud rate'),
            InputField(key='samplePoint', label='Sample Point', unit='%', default=87.5, min=50.0, max=95.0, description='Sample point position as percentage of bit time (CiA 601 recommends 75–87.5%)'),
        ),
        outputs=(
            OutputField(key='tq', label='Time Quantum (TQ)', unit='ns', description=''),
            OutputField(key='nominalBitTime', label='Nominal Bit Time', unit='tq', description=''),
            OutputField(key='syncSeg', label='Sync Segment', unit='tq', description=''),
            OutputField(key='propSeg', label='Propagation Segment', unit='tq', description=''),
            OutputField(key='phase1', label='Phase Buffer 1 (BS1)', unit='tq', description=''),
            OutputField(key='phase2', label='Phase Buffer 2 (BS2)', unit='tq', description=''),
            OutputField(key='prescaler', label='Prescaler', unit='', description=''),
        ),
        keywords=('CAN bus timing', 'bit timing', 'CAN baud rate', 'prescaler', 'sample point', 'CAN FD', 'time quantum', 'CAN controller',),
    ),
    'usb-termination': CalculatorInfo(
        slug='usb-termination',
        title='USB Termination & Signal Integrity Calculator',
        category='protocol',
        description='Calculate USB bus termination resistor values, differential impedance, cable propagation delay, signal rise time, and eye opening for USB 2.0 and USB 3.0',
        inputs=(
            InputField(key='usbVersion', label='USB Version', unit='', default=0.0, min=0.0, max=1.0, description=''),
            InputField(key='lineImpedance', label='Line Impedance', unit='Ω', default=90.0, min=50.0, max=150.0, description='Single-ended trace/cable impedance (USB spec: 90Ω differential = ~45Ω per line)'),
            InputField(key='cableLength', label='Cable Length', unit='m', default=2.0, min=0.01, max=None, description='USB cable length in meters'),
        ),
        outputs=(
            OutputField(key='terminationResistor', label='Termination Resistor', unit='Ω', description=''),
            OutputField(key='differentialImpedance', label='Differential Impedance', unit='Ω', description=''),
            OutputField(key='propagationDelay', label='Cable Propagation Delay', unit='ns', description=''),
            OutputField(key='signalRiseTime', label='Signal Rise Time (spec)', unit='ps', description=''),
            OutputField(key='eyeOpening', label='Estimated Eye Opening', unit='%', description=''),
        ),
        keywords=('USB termination', 'USB impedance', 'USB signal integrity', 'USB 2.0', 'USB 3.0', 'differential impedance', 'eye diagram', 'propagation delay',),
    ),
    'rs485-termination': CalculatorInfo(
        slug='rs485-termination',
        title='RS-485 Termination & Bias Resistor Calculator',
        category='protocol',
        description='Calculate RS-485 bus termination resistors, bias resistors, maximum baud rate for cable length, propagation delay, and bias current consumption',
        inputs=(
            InputField(key='baudRate', label='Baud Rate', unit='kbps', default=115.2, min=0.1, max=None, description='RS-485 communication baud rate in kbps'),
            InputField(key='cableLength', label='Total Cable Length', unit='m', default=100.0, min=0.1, max=None, description='Total bus cable length in meters'),
            InputField(key='numNodes', label='Number of Nodes', unit='', default=10.0, min=2.0, max=256.0, description='Total number of RS-485 devices on the bus (max 32 unit loads per driver)'),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=5.0, min=3.0, max=5.5, description='Logic supply voltage for the RS-485 transceivers'),
        ),
        outputs=(
            OutputField(key='terminationResistor', label='Termination Resistor', unit='Ω', description='Match to cable characteristic impedance (~120Ω for twisted pair)'),
            OutputField(key='biasResistor', label='Bias Resistor', unit='Ω', description='Failsafe bias resistors to maintain idle state differential voltage > 200 mV'),
            OutputField(key='maxBaudRate', label='Max Baud Rate for Cable Length', unit='kbps', description=''),
            OutputField(key='propagationDelay', label='Cable Propagation Delay', unit='ns', description=''),
            OutputField(key='loadCurrent', label='Bias Load Current', unit='mA', description=''),
        ),
        keywords=('RS-485 termination', 'RS-485 impedance', 'RS-485 bias resistors', 'serial communications', 'RS-485 cable', 'Modbus', 'half duplex', 'differential bus',),
    ),
    'pwm-duty-cycle': CalculatorInfo(
        slug='pwm-duty-cycle',
        title='PWM Duty Cycle Calculator',
        category='power',
        description='Calculate PWM duty cycle, frequency, average voltage, off-time, and RMS voltage from on-time and period parameters',
        inputs=(
            InputField(key='onTime', label='On Time', unit='μs', default=5.0, min=0.001, max=None, description='Duration the signal is high in each period'),
            InputField(key='period', label='Period', unit='μs', default=10.0, min=0.001, max=None, description='Total period of the PWM signal'),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=3.3, min=0.1, max=None, description='High-level voltage of the PWM signal'),
        ),
        outputs=(
            OutputField(key='dutyCycle', label='Duty Cycle', unit='%', description=''),
            OutputField(key='frequency', label='Frequency', unit='kHz', description=''),
            OutputField(key='avgVoltage', label='Average Voltage', unit='V', description=''),
            OutputField(key='offTime', label='Off Time', unit='μs', description=''),
            OutputField(key='rmsVoltage', label='RMS Voltage', unit='V', description=''),
        ),
        keywords=('PWM duty cycle', 'pulse width modulation', 'PWM frequency', 'average voltage', 'RMS voltage', 'PWM signal', 'digital control',),
    ),
    'mosfet-power-dissipation': CalculatorInfo(
        slug='mosfet-power-dissipation',
        title='MOSFET Power Dissipation Calculator',
        category='power',
        description='Calculate MOSFET conduction loss, switching loss, total power dissipation, junction temperature, and efficiency for power electronics design',
        inputs=(
            InputField(key='drainCurrent', label='Drain Current', unit='A', default=5.0, min=0.001, max=None, description='RMS drain current through the MOSFET'),
            InputField(key='rdson', label='On-Resistance', unit='mΩ', default=10.0, min=0.1, max=None, description='Drain-source on-resistance from datasheet'),
            InputField(key='vds', label='Drain-Source Voltage', unit='V', default=12.0, min=0.1, max=None, description='Voltage across MOSFET during off state (bus voltage)'),
            InputField(key='frequency', label='Switching Frequency', unit='kHz', default=100.0, min=0.1, max=None, description='Switching frequency of the converter'),
            InputField(key='riseTime', label='Rise Time', unit='ns', default=20.0, min=0.1, max=None, description='Current rise time during turn-on transition'),
            InputField(key='fallTime', label='Fall Time', unit='ns', default=20.0, min=0.1, max=None, description='Current fall time during turn-off transition'),
            InputField(key='rthJA', label='Thermal Resistance (Rth J-A)', unit='°C/W', default=40.0, min=1.0, max=300.0, description='Junction-to-ambient thermal resistance. TO-220 no heatsink: ~60, with heatsink: ~10-20, SOT-23: ~150'),
            InputField(key='tAmbient', label='Ambient Temperature', unit='°C', default=25.0, min=-40.0, max=85.0, description='Operating ambient temperature'),
        ),
        outputs=(
            OutputField(key='conductionLoss', label='Conduction Loss', unit='mW', description=''),
            OutputField(key='switchingLoss', label='Switching Loss', unit='mW', description=''),
            OutputField(key='totalLoss', label='Total Power Loss', unit='mW', description=''),
            OutputField(key='junctionTemp', label='Junction Temperature', unit='°C', description=''),
            OutputField(key='efficiency', label='MOSFET Efficiency (1 − P_loss/P_in)', unit='%', description=''),
        ),
        keywords=('MOSFET power loss', 'conduction loss', 'switching loss', 'MOSFET efficiency', 'Rdson', 'MOSFET thermal', 'power MOSFET', 'synchronous rectifier',),
    ),
    'solar-panel-sizing': CalculatorInfo(
        slug='solar-panel-sizing',
        title='Solar Panel Sizing Calculator',
        category='power',
        description='Calculate solar panel wattage, battery capacity, and charge controller current for off-grid photovoltaic systems based on load and sun hours',
        inputs=(
            InputField(key='loadPower', label='Load Power', unit='W', default=100.0, min=0.1, max=None, description='Continuous power consumption of the load'),
            InputField(key='peakSunHours', label='Peak Sun Hours', unit='hr', default=5.0, min=0.1, max=None, description='Average peak sun hours per day for your location'),
            InputField(key='systemVoltage', label='System Voltage', unit='V', default=12.0, min=1.0, max=None, description=''),
            InputField(key='batteryCapacity', label='Battery Capacity (reference)', unit='Ah', default=100.0, min=1.0, max=None, description='Reference battery capacity (used for comparison)'),
            InputField(key='daysAutonomy', label='Days of Autonomy', unit='', default=3.0, min=1.0, max=30.0, description='Number of cloudy days the system must operate without sun'),
        ),
        outputs=(
            OutputField(key='energyPerDay', label='Energy Per Day', unit='Wh', description=''),
            OutputField(key='panelWattage', label='Required Panel Wattage', unit='W', description=''),
            OutputField(key='panelCurrent', label='Panel Current', unit='A', description=''),
            OutputField(key='batteryAh', label='Required Battery Capacity', unit='Ah', description=''),
            OutputField(key='chargeControllerAmps', label='Charge Controller Current', unit='A', description=''),
        ),
        keywords=('solar panel sizing', 'photovoltaic', 'off-grid solar', 'battery sizing', 'charge controller', 'peak sun hours', 'PV system design', 'off-grid power',),
    ),
    'battery-charge-time': CalculatorInfo(
        slug='battery-charge-time',
        title='Battery Charge Time Calculator',
        category='power',
        description='Calculate Li-ion battery charge time using CC/CV method, including CC phase duration, total charge time, energy input, and charging efficiency',
        inputs=(
            InputField(key='capacity', label='Battery Capacity', unit='mAh', default=3000.0, min=1.0, max=None, description='Rated battery capacity in mAh'),
            InputField(key='chargeCurrentC', label='Charge Rate (C-rate)', unit='C', default=1.0, min=0.1, max=4.0, description='Charge current as a multiple of battery capacity (1C = full capacity in 1 hour)'),
            InputField(key='initialSoc', label='Initial State of Charge', unit='%', default=20.0, min=0.0, max=99.0, description=''),
            InputField(key='targetSoc', label='Target State of Charge', unit='%', default=80.0, min=1.0, max=100.0, description=''),
            InputField(key='chargingVoltage', label='Charging Voltage', unit='V', default=4.2, min=0.1, max=None, description='Terminal voltage during charging'),
            InputField(key='battVoltage', label='Nominal Battery Voltage', unit='V', default=3.7, min=0.1, max=None, description='Nominal battery voltage for energy calculation'),
        ),
        outputs=(
            OutputField(key='chargeCurrent', label='Charge Current', unit='mA', description=''),
            OutputField(key='ccTime', label='CC Phase Time', unit='hr', description=''),
            OutputField(key='chargeTime', label='Total Charge Time', unit='hr', description=''),
            OutputField(key='energyIn', label='Energy Input', unit='mWh', description=''),
            OutputField(key='chargingEfficiency', label='Charging Efficiency', unit='%', description=''),
        ),
        keywords=('battery charge time', 'Li-ion charging', 'CC CV charging', 'battery capacity', 'C-rate charging', 'lithium battery', 'charge time calculator',),
    ),
    'inrush-current-limiter': CalculatorInfo(
        slug='inrush-current-limiter',
        title='Inrush Current Limiter (NTC) Calculator',
        category='power',
        description='Calculate NTC thermistor requirements for inrush current limiting, including cold resistance, peak inrush current, time constant, and energy absorbed',
        inputs=(
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=12.0, min=0.1, max=None, description='Supply voltage applied at power-on'),
            InputField(key='filterCapacitance', label='Filter Capacitance', unit='μF', default=1000.0, min=0.1, max=None, description='Total input filter capacitance that must be charged'),
            InputField(key='targetInrush', label='Target Inrush Current', unit='A', default=5.0, min=0.001, max=None, description='Maximum allowable inrush current at power-on'),
            InputField(key='ntcResistanceHot', label='NTC Resistance (Hot)', unit='Ω', default=0.5, min=0.001, max=None, description='NTC thermistor resistance when fully heated (steady-state)'),
        ),
        outputs=(
            OutputField(key='ntcResistanceCold', label='Required NTC Cold Resistance', unit='Ω', description=''),
            OutputField(key='peakInrush', label='Peak Inrush Current', unit='A', description=''),
            OutputField(key='timeConstant', label='Time Constant', unit='ms', description=''),
            OutputField(key='energyAbsorbed', label='Energy Absorbed', unit='mJ', description=''),
            OutputField(key='limitingResistor', label='Limiting Resistance (cold)', unit='Ω', description=''),
        ),
        keywords=('inrush current', 'NTC thermistor', 'soft start', 'power supply inrush', 'current limiting', 'capacitor inrush', 'power on surge',),
    ),
    'charge-pump-voltage': CalculatorInfo(
        slug='charge-pump-voltage',
        title='Charge Pump Voltage Multiplier Calculator',
        category='power',
        description='Calculate Dickson charge pump output voltage, loaded voltage, output ripple, and efficiency for switched-capacitor voltage multiplier circuits',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage', unit='V', default=3.3, min=0.1, max=None, description=''),
            InputField(key='stages', label='Number of Stages', unit='', default=2.0, min=1.0, max=8.0, description=''),
            InputField(key='pumpCurrent', label='Output Current', unit='mA', default=10.0, min=0.001, max=None, description='Load current drawn from charge pump output'),
            InputField(key='frequency', label='Switching Frequency', unit='kHz', default=100.0, min=0.1, max=None, description=''),
            InputField(key='capacitance', label='Pump Capacitance', unit='μF', default=1.0, min=0.001, max=None, description='Capacitance of each pump capacitor stage'),
        ),
        outputs=(
            OutputField(key='openCircuitVoltage', label='Open Circuit Voltage', unit='V', description=''),
            OutputField(key='loadedVoltage', label='Loaded Output Voltage', unit='V', description=''),
            OutputField(key='outputRipple', label='Output Ripple', unit='mV', description=''),
            OutputField(key='efficiency', label='Efficiency', unit='%', description=''),
        ),
        keywords=('charge pump', 'voltage multiplier', 'Dickson charge pump', 'switched capacitor', 'voltage doubler', 'voltage tripler', 'capacitive boost',),
    ),
    'switching-regulator-ripple': CalculatorInfo(
        slug='switching-regulator-ripple',
        title='Switching Regulator Output Ripple Calculator',
        category='power',
        description='Calculate buck converter output voltage ripple, inductor current ripple, and ESR contribution for switching regulator design',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='outputVoltage', label='Output Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='frequency', label='Switching Frequency', unit='kHz', default=500.0, min=1.0, max=None, description=''),
            InputField(key='inductance', label='Inductance', unit='μH', default=10.0, min=0.01, max=None, description=''),
            InputField(key='capacitance', label='Output Capacitance', unit='μF', default=100.0, min=0.1, max=None, description=''),
            InputField(key='esr', label='Capacitor ESR', unit='mΩ', default=20.0, min=0.1, max=None, description='Equivalent series resistance of the output capacitor'),
        ),
        outputs=(
            OutputField(key='dutyCycle', label='Duty Cycle', unit='%', description=''),
            OutputField(key='inductorRippleCurrent', label='Inductor Ripple Current', unit='A', description=''),
            OutputField(key='capacitorRipple', label='Capacitor Ripple Voltage', unit='mV', description=''),
            OutputField(key='inductorRipple', label='ESR Ripple Voltage', unit='mV', description=''),
            OutputField(key='peakToPeakRipple', label='Total Peak-to-Peak Ripple', unit='mV', description=''),
        ),
        keywords=('buck converter ripple', 'switching regulator', 'output ripple', 'ESR', 'inductor current ripple', 'capacitor ripple', 'buck converter design', 'SMPS ripple',),
    ),
    'linear-regulator-dropout': CalculatorInfo(
        slug='linear-regulator-dropout',
        title='LDO Linear Regulator Dropout Calculator',
        category='power',
        description='Calculate LDO regulator power dissipation, junction temperature rise, minimum input voltage, efficiency, and headroom for linear regulator design',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='outputVoltage', label='Output Voltage', unit='V', default=3.3, min=0.1, max=None, description=''),
            InputField(key='loadCurrent', label='Load Current', unit='mA', default=500.0, min=0.001, max=None, description=''),
            InputField(key='dropoutVoltage', label='Dropout Voltage', unit='mV', default=300.0, min=10.0, max=None, description='Minimum input-to-output differential for regulation (from datasheet)'),
            InputField(key='thetaJA', label='Thermal Resistance θJA', unit='°C/W', default=50.0, min=1.0, max=None, description='Junction-to-ambient thermal resistance (from datasheet)'),
        ),
        outputs=(
            OutputField(key='powerDissipation', label='Power Dissipation', unit='mW', description=''),
            OutputField(key='junctionTempRise', label='Junction Temp Rise', unit='°C', description=''),
            OutputField(key='minInputVoltage', label='Minimum Input Voltage', unit='V', description=''),
            OutputField(key='efficiency', label='Efficiency', unit='%', description=''),
            OutputField(key='headroom', label='Input Headroom', unit='mV', description=''),
        ),
        keywords=('LDO dropout voltage', 'linear regulator', 'dropout', 'efficiency', 'thermal dissipation', 'LDO design', 'low dropout regulator', 'regulator thermal',),
    ),
    'pcb-crosstalk': CalculatorInfo(
        slug='pcb-crosstalk',
        title='PCB Crosstalk Calculator',
        category='pcb',
        description='Estimate PCB trace crosstalk coupling coefficient, NEXT, FEXT, and critical coupling length for signal integrity analysis on PCB layouts',
        inputs=(
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=0.2, min=0.01, max=None, description=''),
            InputField(key='traceSpacing', label='Trace Spacing (edge-to-edge)', unit='mm', default=0.2, min=0.01, max=None, description='Edge-to-edge spacing between traces'),
            InputField(key='dielectricHeight', label='Dielectric Height', unit='mm', default=0.1, min=0.01, max=None, description='Height of dielectric layer between trace and reference plane'),
            InputField(key='frequency', label='Signal Frequency', unit='MHz', default=100.0, min=0.1, max=None, description='Highest significant frequency component of the signal'),
            InputField(key='traceLength', label='Parallel Trace Length', unit='mm', default=50.0, min=0.1, max=None, description='Length over which the traces run parallel'),
        ),
        outputs=(
            OutputField(key='couplingCoeff', label='Coupling Coefficient', unit='%', description=''),
            OutputField(key='next_dB', label='NEXT', unit='dB', description=''),
            OutputField(key='fext_dB', label='FEXT', unit='dB', description=''),
            OutputField(key='criticalLength', label='Critical Length (λ/4)', unit='mm', description='Quarter-wavelength at the signal frequency in PCB medium'),
        ),
        keywords=('PCB crosstalk', 'NEXT', 'FEXT', 'signal integrity', 'coupled traces', 'PCB trace coupling', 'near-end crosstalk', 'far-end crosstalk',),
    ),
    'decoupling-capacitor': CalculatorInfo(
        slug='decoupling-capacitor',
        title='Decoupling Capacitor Selection Calculator',
        category='pcb',
        description='Calculate decoupling capacitor self-resonant frequency, impedance at target frequency, effective bypass range, and number of capacitors needed for power integrity',
        inputs=(
            InputField(key='capacitance', label='Capacitance', unit='nF', default=100.0, min=0.001, max=None, description=''),
            InputField(key='esr', label='ESR', unit='mΩ', default=50.0, min=0.1, max=None, description='Equivalent series resistance of the capacitor'),
            InputField(key='esl', label='ESL', unit='nH', default=1.0, min=0.01, max=None, description='Equivalent series inductance (package parasitic)'),
            InputField(key='targetFreq', label='Target Frequency', unit='MHz', default=100.0, min=0.001, max=None, description='Frequency at which decoupling impedance is evaluated'),
            InputField(key='supplyImpedance', label='Target Supply Impedance', unit='mΩ', default=10.0, min=0.001, max=None, description='Maximum allowable PDN impedance at the target frequency'),
        ),
        outputs=(
            OutputField(key='selfResonantFreq', label='Self-Resonant Frequency', unit='MHz', description=''),
            OutputField(key='impedanceAtSrf', label='Impedance at SRF', unit='mΩ', description=''),
            OutputField(key='impedanceAtTarget', label='Impedance at Target Freq', unit='mΩ', description=''),
            OutputField(key='effectiveRange', label='Effective Bypass Range (upper)', unit='MHz', description=''),
            OutputField(key='numCapacitors', label='Capacitors Needed', unit='', description=''),
        ),
        keywords=('decoupling capacitor', 'bypass capacitor', 'self-resonant frequency', 'ESR', 'ESL', 'power integrity', 'PDN design', 'power delivery network',),
    ),
    'pcb-trace-inductance': CalculatorInfo(
        slug='pcb-trace-inductance',
        title='PCB Trace Inductance Calculator',
        category='pcb',
        description='Calculate PCB trace parasitic inductance using the Ruehli formula, including inductance per unit length and inductive impedance at key frequencies',
        inputs=(
            InputField(key='traceLength', label='Trace Length', unit='mm', default=10.0, min=0.1, max=None, description=''),
            InputField(key='traceWidth', label='Trace Width', unit='mm', default=0.2, min=0.01, max=None, description=''),
            InputField(key='thickness', label='Copper Thickness', unit='μm', default=35.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='inductance', label='Total Inductance', unit='nH', description=''),
            OutputField(key='inductancePerLength', label='Inductance per Length', unit='nH/mm', description=''),
            OutputField(key='impedanceAt100MHz', label='Impedance at 100 MHz', unit='Ω', description=''),
            OutputField(key='impedanceAt1GHz', label='Impedance at 1 GHz', unit='Ω', description=''),
        ),
        keywords=('PCB trace inductance', 'trace parasitic', 'signal integrity', 'trace impedance', 'parasitic inductance', 'PCB parasitics', 'Ruehli formula',),
    ),
    'via-thermal-resistance': CalculatorInfo(
        slug='via-thermal-resistance',
        title='Via Thermal Resistance Calculator',
        category='pcb',
        description='Calculate PCB via thermal resistance, array thermal resistance, thermal conductance, and current-carrying capacity for thermal via design',
        inputs=(
            InputField(key='viaDiameter', label='Via Diameter', unit='mm', default=0.3, min=0.05, max=None, description=''),
            InputField(key='platingThickness', label='Plating Thickness', unit='μm', default=25.0, min=1.0, max=None, description='Copper plating thickness on via barrel walls'),
            InputField(key='boardThickness', label='Board Thickness', unit='mm', default=1.6, min=0.1, max=None, description=''),
            InputField(key='numVias', label='Number of Vias', unit='', default=4.0, min=1.0, max=100.0, description=''),
            InputField(key='viaFill', label='Via Fill', unit='', default=0.0, min=0.0, max=1.0, description=''),
        ),
        outputs=(
            OutputField(key='viaResistance', label='Single Via Thermal Resistance', unit='°C/W', description=''),
            OutputField(key='arrayResistance', label='Array Thermal Resistance', unit='°C/W', description=''),
            OutputField(key='thermalConductance', label='Thermal Conductance', unit='W/°C', description=''),
            OutputField(key='currentCapacity', label='Current Capacity (per via)', unit='mA', description=''),
        ),
        keywords=('via thermal resistance', 'thermal via', 'PCB thermal management', 'via current capacity', 'thermal management', 'PCB heat dissipation', 'copper via',),
    ),
    'bjt-bias-point': CalculatorInfo(
        slug='bjt-bias-point',
        title='BJT Transistor Bias Point Calculator',
        category='general',
        description='Calculate BJT voltage divider bias Q-point including collector current, base voltage, VCE, power dissipation, and operating region',
        inputs=(
            InputField(key='vcc', label='Supply Voltage (VCC)', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='r1', label='R1 (upper bias resistor)', unit='kΩ', default=10.0, min=0.001, max=None, description=''),
            InputField(key='r2', label='R2 (lower bias resistor)', unit='kΩ', default=4.7, min=0.001, max=None, description=''),
            InputField(key='rc', label='Collector Resistor', unit='kΩ', default=2.2, min=0.001, max=None, description=''),
            InputField(key='re', label='Emitter Resistor', unit='Ω', default=470.0, min=0.0, max=None, description=''),
            InputField(key='beta', label='Current Gain (β / hFE)', unit='', default=100.0, min=1.0, max=None, description=''),
            InputField(key='vbe', label='Base-Emitter Voltage', unit='V', default=0.7, min=0.1, max=0.9, description=''),
        ),
        outputs=(
            OutputField(key='vb', label='Base Voltage', unit='V', description=''),
            OutputField(key='ve', label='Emitter Voltage', unit='V', description=''),
            OutputField(key='vc', label='Collector Voltage', unit='V', description=''),
            OutputField(key='ic', label='Collector Current', unit='mA', description=''),
            OutputField(key='ib', label='Base Current', unit='μA', description=''),
            OutputField(key='vce', label='Collector-Emitter Voltage', unit='V', description=''),
            OutputField(key='powerDissipation', label='Power Dissipation', unit='mW', description=''),
            OutputField(key='operatingRegion', label='Operating Region (1=Active, 0=Sat)', unit='', description=''),
        ),
        keywords=('BJT bias point', 'transistor bias', 'Q-point', 'voltage divider bias', 'BJT operating point', 'NPN bias', 'transistor Q-point', 'Thevenin bias',),
    ),
    'mosfet-operating-point': CalculatorInfo(
        slug='mosfet-operating-point',
        title='MOSFET Operating Point Calculator',
        category='general',
        description='Calculate MOSFET drain current, saturation voltage, transconductance, and operating region (cutoff, triode, saturation) for NMOS transistors',
        inputs=(
            InputField(key='vgs', label='Gate-Source Voltage', unit='V', default=5.0, min=0.0, max=None, description=''),
            InputField(key='vth', label='Threshold Voltage', unit='V', default=2.0, min=0.1, max=None, description=''),
            InputField(key='kn', label='Process Transconductance (kn)', unit='mA/V²', default=100.0, min=0.001, max=None, description='Process parameter kn = μ_n × Cox × W/L'),
            InputField(key='vds', label='Drain-Source Voltage', unit='V', default=10.0, min=0.0, max=None, description=''),
            InputField(key='vdd', label='Supply Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='rdLoad', label='Drain Load Resistance', unit='kΩ', default=1.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='id', label='Drain Current', unit='mA', description=''),
            OutputField(key='vdsSat', label='Saturation Voltage', unit='V', description=''),
            OutputField(key='powerDissipation', label='Power Dissipation', unit='mW', description=''),
            OutputField(key='gm', label='Transconductance', unit='mA/V', description=''),
            OutputField(key='region', label='Operating Region (0=Off, 1=Triode, 2=Sat)', unit='', description=''),
        ),
        keywords=('MOSFET operating point', 'MOSFET drain current', 'threshold voltage', 'gm', 'transconductance', 'NMOS saturation', 'MOSFET triode', 'FET bias',),
    ),
    'comparator-hysteresis': CalculatorInfo(
        slug='comparator-hysteresis',
        title='Comparator Hysteresis (Schmitt Trigger) Calculator',
        category='general',
        description='Calculate comparator hysteresis trip points for Schmitt trigger circuits, upper and lower threshold voltages, and design resistor values for a desired hysteresis percentage',
        inputs=(
            InputField(key='vref', label='Reference Voltage', unit='V', default=2.5, min=0.0, max=None, description='Reference voltage applied to the inverting input'),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='r1', label='R1 (feedback resistor)', unit='kΩ', default=10.0, min=0.001, max=None, description='Resistor from comparator output to non-inverting input'),
            InputField(key='r2', label='R2 (input resistor)', unit='kΩ', default=100.0, min=0.001, max=None, description='Resistor from non-inverting input to ground (sets reference divider)'),
            InputField(key='hystPercent', label='Desired Hysteresis', unit='%', default=5.0, min=0.1, max=50.0, description='Desired hysteresis as percentage of supply voltage (for design calculation)'),
        ),
        outputs=(
            OutputField(key='vTrip_high', label='Upper Trip Point', unit='V', description=''),
            OutputField(key='vTrip_low', label='Lower Trip Point', unit='V', description=''),
            OutputField(key='hysteresis', label='Hysteresis Band', unit='mV', description=''),
            OutputField(key='r1Calc', label='Calculated R1 (for desired hyst%)', unit='kΩ', description=''),
            OutputField(key='r2Calc', label='R2 (used)', unit='kΩ', description=''),
        ),
        keywords=('comparator hysteresis', 'Schmitt trigger', 'threshold voltage', 'noise immunity', 'positive feedback', 'hysteresis band', 'comparator design',),
    ),
    '555-timer': CalculatorInfo(
        slug='555-timer',
        title='555 Timer Calculator (Astable & Monostable)',
        category='general',
        description='Calculate 555 timer frequency, period, duty cycle, and pulse width for both astable oscillator and monostable one-shot configurations',
        inputs=(
            InputField(key='mode', label='Timer Mode', unit='', default=0.0, min=0.0, max=1.0, description=''),
            InputField(key='ra', label='Resistor RA', unit='kΩ', default=10.0, min=0.001, max=None, description='Timing resistor RA (connected between VCC and discharge pin)'),
            InputField(key='rb', label='Resistor RB', unit='kΩ', default=10.0, min=0.001, max=None, description='Timing resistor RB (astable: between discharge and threshold; monostable: not used)'),
            InputField(key='c', label='Timing Capacitor', unit='μF', default=0.1, min=0.0001, max=None, description=''),
            InputField(key='vcc', label='Supply Voltage', unit='V', default=5.0, min=1.0, max=16.0, description=''),
        ),
        outputs=(
            OutputField(key='frequency', label='Frequency', unit='Hz', description=''),
            OutputField(key='period', label='Period', unit='ms', description=''),
            OutputField(key='pulseWidth', label='Pulse Width (high time)', unit='ms', description=''),
            OutputField(key='dutyCycle', label='Duty Cycle', unit='%', description=''),
            OutputField(key='highTime', label='High Time', unit='ms', description=''),
            OutputField(key='lowTime', label='Low Time', unit='ms', description=''),
        ),
        keywords=('555 timer', 'astable', 'monostable', 'timer circuit', 'oscillator', 'pulse generator', 'NE555', '555 oscillator', 'one-shot timer',),
    ),
    'transistor-switch': CalculatorInfo(
        slug='transistor-switch',
        title='BJT Transistor Switch Calculator',
        category='general',
        description='Calculate BJT transistor switch parameters including load current, required base current, base resistor value, saturation check, and power dissipation',
        inputs=(
            InputField(key='vcc', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='loadResistor', label='Load Resistance', unit='Ω', default=100.0, min=0.1, max=None, description=''),
            InputField(key='inputVoltage', label='Input Drive Voltage', unit='V', default=3.3, min=0.0, max=None, description='Logic-high voltage driving the transistor base through R_B'),
            InputField(key='beta', label='Current Gain (β)', unit='', default=100.0, min=1.0, max=None, description='Minimum DC current gain (hFE) from datasheet'),
            InputField(key='vbe', label='Base-Emitter Voltage', unit='V', default=0.7, min=0.1, max=0.9, description=''),
            InputField(key='vce_sat', label='Saturation Voltage VCE(sat)', unit='V', default=0.2, min=0.01, max=None, description='Collector-emitter saturation voltage from datasheet'),
            InputField(key='overdriveFactor', label='Overdrive Factor', unit='×', default=5.0, min=1.0, max=20.0, description='Factor by which base current exceeds minimum required (typically 5-10×)'),
        ),
        outputs=(
            OutputField(key='loadCurrent', label='Load Current', unit='mA', description=''),
            OutputField(key='ib_required', label='Required Base Current', unit='μA', description=''),
            OutputField(key='rb', label='Base Resistor', unit='kΩ', description=''),
            OutputField(key='ib_actual', label='Actual Base Current', unit='μA', description=''),
            OutputField(key='powerDissipation', label='Transistor Power Dissipation', unit='mW', description=''),
            OutputField(key='switchingState', label='Saturated? (1=Yes, 0=No)', unit='', description=''),
        ),
        keywords=('transistor switch', 'BJT switch', 'saturation', 'switching circuit', 'base resistor', 'NPN switch', 'digital switch', 'transistor saturation',),
    ),
    'current-mirror': CalculatorInfo(
        slug='current-mirror',
        title='Current Mirror Calculator',
        category='general',
        description='Calculate current mirror output current, beta error, reference resistor, power consumption, and Widlar mirror resistor for analog IC and bias circuit design',
        inputs=(
            InputField(key='refCurrent', label='Reference Current', unit='mA', default=1.0, min=0.001, max=None, description=''),
            InputField(key='ratio', label='Mirror Ratio (Iout/Iref)', unit='×', default=2.0, min=0.001, max=None, description=''),
            InputField(key='vcc', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='beta', label='Transistor β (hFE)', unit='', default=100.0, min=1.0, max=None, description=''),
            InputField(key='vt', label='Thermal Voltage', unit='mV', default=26.0, min=10.0, max=50.0, description='Thermal voltage kT/q ≈ 26 mV at room temperature'),
        ),
        outputs=(
            OutputField(key='outputCurrent', label='Output Current (with β error)', unit='mA', description=''),
            OutputField(key='refResistor', label='Reference Resistor', unit='kΩ', description=''),
            OutputField(key='powerRef', label='Reference Branch Power', unit='mW', description=''),
            OutputField(key='error', label='β Error', unit='%', description=''),
            OutputField(key='widlarResistor', label='Widlar Resistor (ratio<1)', unit='kΩ', description='Widlar emitter resistor value — only applicable when mirror ratio < 1'),
        ),
        keywords=('current mirror', 'Widlar mirror', 'Wilson mirror', 'bias circuit', 'IC design', 'analog design', 'current source', 'BJT current mirror',),
    ),
    'thermal-resistance-network': CalculatorInfo(
        slug='thermal-resistance-network',
        title='Thermal Resistance Network Calculator',
        category='thermal',
        description='Calculate junction, case, and heatsink temperatures through a series thermal resistance network (θJC + θCS + θSA) for component thermal management',
        inputs=(
            InputField(key='powerDissipation', label='Power Dissipation', unit='W', default=5.0, min=0.001, max=None, description='Total power dissipated by the device'),
            InputField(key='thetaJC', label='Junction-to-Case (θJC)', unit='°C/W', default=2.0, min=0.01, max=None, description='Junction-to-case thermal resistance from device datasheet'),
            InputField(key='thetaCS', label='Case-to-Heatsink (θCS)', unit='°C/W', default=0.5, min=0.0, max=None, description='Case-to-heatsink thermal resistance (thermal interface material)'),
            InputField(key='thetaSA', label='Heatsink-to-Ambient (θSA)', unit='°C/W', default=10.0, min=0.1, max=None, description='Heatsink-to-ambient thermal resistance (heatsink specification)'),
            InputField(key='ambientTemp', label='Ambient Temperature', unit='°C', default=25.0, min=-55.0, max=85.0, description=''),
        ),
        outputs=(
            OutputField(key='junctionTemp', label='Junction Temperature', unit='°C', description=''),
            OutputField(key='caseTemp', label='Case Temperature', unit='°C', description=''),
            OutputField(key='heatsinkTemp', label='Heatsink Temperature', unit='°C', description=''),
            OutputField(key='totalThetaJA', label='Total θJA', unit='°C/W', description=''),
            OutputField(key='thermalMargin', label='Thermal Margin (to 150°C)', unit='°C', description=''),
        ),
        keywords=('thermal resistance', 'junction temperature', 'heatsink', 'thermal network', 'θJC', 'θCS', 'θSA', 'thermal management', 'semiconductor cooling',),
    ),
    'bldc-motor': CalculatorInfo(
        slug='bldc-motor',
        title='BLDC Motor Performance Calculator',
        category='motor',
        description='Calculate brushless DC motor no-load RPM, stall torque, maximum efficiency, input power, and propeller thrust from Kv rating and electrical parameters',
        inputs=(
            InputField(key='kvRating', label='Motor Kv Rating', unit='RPM/V', default=1000.0, min=1.0, max=None, description='Motor velocity constant — RPM per volt at no load'),
            InputField(key='voltage', label='Operating Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='motorResistance', label='Motor Winding Resistance', unit='mΩ', default=50.0, min=0.1, max=None, description='Phase-to-phase winding resistance from datasheet'),
            InputField(key='noLoadCurrent', label='No-Load Current', unit='A', default=0.5, min=0.001, max=None, description='No-load current (iron losses, friction) from datasheet'),
            InputField(key='propDiameter', label='Propeller Diameter', unit='inch', default=5.0, min=0.5, max=None, description='Propeller diameter for thrust estimate (multirotor)'),
        ),
        outputs=(
            OutputField(key='noLoadRpm', label='No-Load RPM', unit='RPM', description=''),
            OutputField(key='stallTorque', label='Stall Torque', unit='Nm', description=''),
            OutputField(key='maxEfficiency', label='Maximum Efficiency', unit='%', description=''),
            OutputField(key='inputPower', label='Input Power (at midpoint)', unit='W', description=''),
            OutputField(key='thrust', label='Estimated Thrust', unit='g', description='Very rough thrust estimate for multirotor propellers'),
        ),
        keywords=('BLDC motor', 'brushless motor', 'Kv rating', 'motor torque', 'motor efficiency', 'ESC', 'drone motor', 'brushless DC', 'motor Kt',),
    ),
    'servo-motor': CalculatorInfo(
        slug='servo-motor',
        title='Servo Motor Torque & Speed',
        category='motor',
        description='Calculate servo motor torque, speed, efficiency, and back-EMF from electrical and load parameters.',
        inputs=(
            InputField(key='voltage', label='Supply Voltage', unit='V', default=5.0, min=0.0, max=None, description=''),
            InputField(key='current', label='Operating Current', unit='A', default=0.5, min=0.0, max=None, description=''),
            InputField(key='speed', label='No-Load Speed', unit='RPM', default=500.0, min=1.0, max=None, description=''),
            InputField(key='loadTorque', label='Load Torque', unit='N·m', default=0.05, min=0.0, max=None, description=''),
            InputField(key='armRes', label='Winding Resistance', unit='Ω', default=2.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='inputPower', label='Input Power', unit='W', description=''),
            OutputField(key='outputPower', label='Output Power', unit='W', description=''),
            OutputField(key='efficiency', label='Efficiency', unit='%', description=''),
            OutputField(key='backEmf', label='Back-EMF', unit='V', description=''),
            OutputField(key='stallTorque', label='Stall Torque (est.)', unit='N·m', description=''),
        ),
        keywords=('servo motor', 'torque speed', 'back EMF', 'servo efficiency', 'RC servo', 'servo power',),
    ),
    'gear-ratio': CalculatorInfo(
        slug='gear-ratio',
        title='Gear Ratio Calculator',
        category='motor',
        description='Calculate gear ratio, output speed, torque multiplication, and power transmission efficiency for gear trains.',
        inputs=(
            InputField(key='driverTeeth', label='Driver (Input) Teeth', unit='teeth', default=10.0, min=1.0, max=None, description=''),
            InputField(key='drivenTeeth', label='Driven (Output) Teeth', unit='teeth', default=40.0, min=1.0, max=None, description=''),
            InputField(key='inputSpeed', label='Input Speed', unit='RPM', default=1000.0, min=0.0, max=None, description=''),
            InputField(key='inputTorque', label='Input Torque', unit='N·m', default=0.5, min=0.0, max=None, description=''),
            InputField(key='efficiency', label='Gear Efficiency', unit='%', default=95.0, min=10.0, max=100.0, description=''),
        ),
        outputs=(
            OutputField(key='gearRatio', label='Gear Ratio', unit=':1', description=''),
            OutputField(key='outputSpeed', label='Output Speed', unit='RPM', description=''),
            OutputField(key='outputTorque', label='Output Torque', unit='N·m', description=''),
            OutputField(key='inputPower', label='Input Power', unit='W', description=''),
            OutputField(key='outputPower', label='Output Power', unit='W', description=''),
        ),
        keywords=('gear ratio', 'gear train', 'torque multiplication', 'speed reduction', 'gear efficiency', 'planetary gear',),
    ),
    'pwm-duty-cycle-motor': CalculatorInfo(
        slug='pwm-duty-cycle-motor',
        title='PWM Duty Cycle to Motor Voltage',
        category='motor',
        description='Convert PWM duty cycle to effective motor voltage, calculate no-load speed and stall current for DC motor PWM control.',
        inputs=(
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='dutyCycle', label='Duty Cycle', unit='%', default=75.0, min=0.0, max=100.0, description=''),
            InputField(key='motorKv', label='Motor Kv Constant', unit='RPM/V', default=100.0, min=1.0, max=None, description='Speed per volt at no load'),
            InputField(key='motorResistance', label='Winding Resistance', unit='Ω', default=1.5, min=0.01, max=None, description=''),
        ),
        outputs=(
            OutputField(key='effectiveVoltage', label='Effective Voltage', unit='V', description=''),
            OutputField(key='noLoadSpeed', label='No-Load Speed', unit='RPM', description=''),
            OutputField(key='stallCurrent', label='Stall Current', unit='A', description=''),
            OutputField(key='peakPower', label='Peak Power (stall)', unit='W', description=''),
            OutputField(key='rippleVoltageFactor', label='PWM Voltage Factor', unit='V', description='Voltage ripple factor — V_s × D × (1−D); indicates PWM voltage variation, not current'),
        ),
        keywords=('PWM duty cycle', 'motor voltage', 'PWM motor control', 'effective voltage', 'motor speed control', 'H-bridge PWM',),
    ),
    'torque-unit-converter': CalculatorInfo(
        slug='torque-unit-converter',
        title='Torque Unit Converter',
        category='motor',
        description='Convert torque between Newton-metres, pound-feet, pound-inches, oz·in, kg·cm and dyne·cm — covers all motor datasheet units.',
        inputs=(
            InputField(key='nm', label='Torque', unit='N·m', default=1.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='lbFt', label='Pound-feet', unit='lb·ft', description=''),
            OutputField(key='lbIn', label='Pound-inches', unit='lb·in', description=''),
            OutputField(key='ozIn', label='Oz-inches', unit='oz·in', description=''),
            OutputField(key='kgCm', label='Kilogram-cm', unit='kg·cm', description=''),
            OutputField(key='kgM', label='Kilogram-metres', unit='kg·m', description=''),
            OutputField(key='dyneCm', label='Dyne-centimetres', unit='dyn·cm', description=''),
        ),
        keywords=('torque converter', 'N·m to lb·ft', 'oz-in to N-m', 'kg-cm torque', 'torque unit conversion', 'motor torque units',),
    ),
    'motor-efficiency': CalculatorInfo(
        slug='motor-efficiency',
        title='Motor Input/Output Efficiency',
        category='motor',
        description='Calculate motor efficiency, power losses, and heat dissipation from electrical input and mechanical output measurements.',
        inputs=(
            InputField(key='inputVoltage', label='Supply Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='inputCurrent', label='Supply Current', unit='A', default=2.0, min=0.0, max=None, description=''),
            InputField(key='outputPowerW', label='Mechanical Output Power', unit='W', default=18.0, min=0.0, max=None, description='Measure with a torque + speed sensor, or use P = T × ω'),
        ),
        outputs=(
            OutputField(key='inputPower', label='Input Power', unit='W', description=''),
            OutputField(key='efficiency', label='Efficiency', unit='%', description=''),
            OutputField(key='losses', label='Total Losses', unit='W', description=''),
            OutputField(key='heatDissipation', label='Heat Dissipated', unit='W', description=''),
        ),
        keywords=('motor efficiency', 'motor losses', 'motor heat', 'efficiency percentage', 'motor power', 'motor thermal',),
    ),
    'induction-motor-slip': CalculatorInfo(
        slug='induction-motor-slip',
        title='Induction Motor Slip',
        category='motor',
        description='Calculate induction motor slip, synchronous speed, slip frequency, and rotor speed for AC induction motors.',
        inputs=(
            InputField(key='frequency', label='Supply Frequency', unit='Hz', default=60.0, min=1.0, max=None, description=''),
            InputField(key='poles', label='Number of Poles', unit='', default=4.0, min=2.0, max=None, description='Must be even (2, 4, 6, 8...)'),
            InputField(key='rotorSpeed', label='Rotor Speed (actual)', unit='RPM', default=1750.0, min=0.0, max=None, description=''),
            InputField(key='syncSpeed', label='Synchronous Speed (override)', unit='RPM', default=0.0, min=0.0, max=None, description='Leave 0 to calculate from frequency and poles'),
        ),
        outputs=(
            OutputField(key='effectiveSyncSpeed', label='Synchronous Speed', unit='RPM', description=''),
            OutputField(key='slipPercent', label='Slip', unit='%', description=''),
            OutputField(key='slipRPM', label='Speed Difference', unit='RPM', description=''),
            OutputField(key='slipFrequency', label='Rotor Frequency', unit='Hz', description=''),
        ),
        keywords=('induction motor', 'motor slip', 'synchronous speed', 'slip frequency', 'AC motor', 'slip RPM',),
    ),
    'motor-inrush-current': CalculatorInfo(
        slug='motor-inrush-current',
        title='Motor Inrush Current',
        category='motor',
        description='Calculate motor inrush current, voltage drop during startup, and I²t value for fuse/breaker selection.',
        inputs=(
            InputField(key='ratedCurrent', label='Rated Full-Load Current', unit='A', default=5.0, min=0.01, max=None, description=''),
            InputField(key='inrushMultiplier', label='Inrush Multiplier', unit='×', default=6.0, min=1.0, max=15.0, description='Typically 5–8× for induction motors'),
            InputField(key='startupDuration', label='Startup Duration', unit='s', default=0.1, min=0.001, max=None, description=''),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=120.0, min=1.0, max=None, description=''),
            InputField(key='lineResistance', label='Line Resistance', unit='Ω', default=0.5, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='inrushCurrent', label='Inrush Current', unit='A', description=''),
            OutputField(key='voltageDropAtInrush', label='Voltage Drop', unit='V', description=''),
            OutputField(key='voltageDropPercent', label='Voltage Drop', unit='%', description=''),
            OutputField(key='fuseISquaredT', label='I²t (fuse energy)', unit='A²s', description=''),
            OutputField(key='peakPower', label='Peak Power Draw', unit='W', description=''),
        ),
        keywords=('motor inrush current', 'startup current', 'locked rotor current', 'I2t fuse', 'motor protection', 'motor soft start',),
    ),
    'motor-heat-dissipation': CalculatorInfo(
        slug='motor-heat-dissipation',
        title='Motor Heat Dissipation',
        category='motor',
        description='Calculate motor heat dissipation, temperature rise, and operating temperature from input power and efficiency.',
        inputs=(
            InputField(key='inputPower', label='Input Power', unit='W', default=50.0, min=0.0, max=None, description=''),
            InputField(key='efficiency', label='Motor Efficiency', unit='%', default=80.0, min=1.0, max=100.0, description=''),
            InputField(key='ambientTemp', label='Ambient Temperature', unit='°C', default=25.0, min=-40.0, max=85.0, description=''),
            InputField(key='thermalResistance', label='Thermal Resistance (motor)', unit='°C/W', default=2.5, min=0.01, max=None, description='Motor winding to ambient thermal resistance from datasheet'),
        ),
        outputs=(
            OutputField(key='losses', label='Power Losses', unit='W', description=''),
            OutputField(key='tempRise', label='Temperature Rise', unit='°C', description=''),
            OutputField(key='motorTemp', label='Motor Operating Temp', unit='°C', description=''),
            OutputField(key='outputPower', label='Output Power', unit='W', description=''),
        ),
        keywords=('motor heat', 'motor temperature', 'motor cooling', 'motor losses', 'thermal resistance motor', 'motor temperature rise',),
    ),
    'encoder-resolution': CalculatorInfo(
        slug='encoder-resolution',
        title='Encoder Resolution Calculator',
        category='motor',
        description='Calculate encoder counts per revolution, angular resolution, and maximum frequency for quadrature and single-channel encoders.',
        inputs=(
            InputField(key='ppr', label='Pulses Per Revolution (PPR)', unit='pulses', default=1000.0, min=1.0, max=None, description=''),
            InputField(key='quadrature', label='Quadrature (×4)', unit='', default=1.0, min=0.0, max=1.0, description='Set 1 for quadrature (4× edge count), 0 for single channel'),
            InputField(key='gearRatio', label='Gear Ratio', unit=':1', default=1.0, min=0.01, max=None, description=''),
            InputField(key='motorMaxRpm', label='Max Motor Speed', unit='RPM', default=3000.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='countsMechanicalRev', label='Counts/Motor Rev', unit='counts', description=''),
            OutputField(key='countsPerOutputRev', label='Counts/Output Rev', unit='counts', description=''),
            OutputField(key='degreePerCount', label='Angular Resolution', unit='°/count', description=''),
            OutputField(key='maxFrequency', label='Max Pulse Frequency', unit='Hz', description=''),
        ),
        keywords=('encoder resolution', 'quadrature encoder', 'PPR encoder', 'CPR encoder', 'encoder counts', 'optical encoder',),
    ),
    'motor-starting-torque': CalculatorInfo(
        slug='motor-starting-torque',
        title='Motor Starting Torque',
        category='motor',
        description='Calculate DC motor starting (stall) torque, stall current, no-load speed, and peak power at startup.',
        inputs=(
            InputField(key='voltage', label='Supply Voltage', unit='V', default=12.0, min=0.1, max=None, description=''),
            InputField(key='resistance', label='Winding Resistance', unit='Ω', default=0.5, min=0.001, max=None, description=''),
            InputField(key='torqueConst', label='Torque Constant', unit='N·m/A', default=0.05, min=0.001, max=None, description=''),
            InputField(key='backEmfConst', label='Back-EMF Constant', unit='V/RPM', default=0.01, min=0.0001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='startingTorque', label='Starting (Stall) Torque', unit='N·m', description=''),
            OutputField(key='stallCurrent', label='Stall Current', unit='A', description=''),
            OutputField(key='noLoadSpeed', label='No-Load Speed', unit='RPM', description=''),
            OutputField(key='powerAtStall', label='Power at Stall', unit='W', description=''),
        ),
        keywords=('motor starting torque', 'stall torque', 'locked rotor torque', 'motor startup', 'stall current', 'DC motor stall',),
    ),
    'battery-runtime-motor': CalculatorInfo(
        slug='battery-runtime-motor',
        title='Battery Runtime (Motor Load)',
        category='motor',
        description='Calculate battery runtime for motor-driven systems accounting for motor current draw, efficiency, and depth of discharge.',
        inputs=(
            InputField(key='batteryCapacityMah', label='Battery Capacity', unit='mAh', default=2000.0, min=1.0, max=None, description=''),
            InputField(key='batteryVoltage', label='Battery Voltage', unit='V', default=3.7, min=0.5, max=None, description=''),
            InputField(key='motorCurrentA', label='Motor Current (avg)', unit='A', default=0.5, min=0.001, max=None, description=''),
            InputField(key='efficiency', label='Drive Efficiency', unit='%', default=85.0, min=10.0, max=100.0, description='Motor driver + motor combined efficiency'),
            InputField(key='depthOfDischarge', label='Depth of Discharge', unit='%', default=80.0, min=1.0, max=100.0, description=''),
        ),
        outputs=(
            OutputField(key='runtimeHours', label='Runtime', unit='h', description=''),
            OutputField(key='runtimeMinutes', label='Runtime', unit='min', description=''),
            OutputField(key='usableCapacityMah', label='Usable Capacity', unit='mAh', description=''),
            OutputField(key='energyWh', label='Battery Energy (est.)', unit='Wh', description=''),
        ),
        keywords=('battery runtime motor', 'motor battery life', 'robot battery', 'motor run time', 'mAh motor', 'battery capacity motor',),
    ),
    'motor-winding-resistance': CalculatorInfo(
        slug='motor-winding-resistance',
        title='Winding Resistance vs Temperature',
        category='motor',
        description='Calculate motor winding resistance at operating temperature using the copper temperature coefficient of resistance.',
        inputs=(
            InputField(key='resistance25', label='Resistance at 25°C', unit='Ω', default=1.0, min=0.001, max=None, description=''),
            InputField(key='temperature', label='Operating Temperature', unit='°C', default=80.0, min=-40.0, max=200.0, description=''),
            InputField(key='tempCoeff', label='Temperature Coefficient', unit='/°C', default=0.00393, min=0.0, max=None, description='Copper: 0.00393/°C, Aluminium: 0.00429/°C'),
        ),
        outputs=(
            OutputField(key='resistanceAtTemp', label='Resistance at Temp', unit='Ω', description=''),
            OutputField(key='resistanceChange', label='Resistance Change', unit='Ω', description=''),
            OutputField(key='resistanceChangePercent', label='Change', unit='%', description=''),
        ),
        keywords=('winding resistance', 'motor resistance temperature', 'copper TCR', 'motor temperature coefficient', 'winding temperature', 'motor derating',),
    ),
    'h-bridge-selection': CalculatorInfo(
        slug='h-bridge-selection',
        title='H-Bridge MOSFET Selection',
        category='motor',
        description='Calculate H-bridge MOSFET requirements including peak current, conduction losses, and minimum current rating for DC motor drivers.',
        inputs=(
            InputField(key='motorCurrent', label='Motor Rated Current', unit='A', default=2.0, min=0.1, max=None, description=''),
            InputField(key='motorVoltage', label='Motor Supply Voltage', unit='V', default=12.0, min=1.0, max=None, description=''),
            InputField(key='inrushMultiplier', label='Inrush Multiplier', unit='×', default=6.0, min=1.0, max=15.0, description=''),
            InputField(key='pwmFrequency', label='PWM Frequency', unit='Hz', default=20000.0, min=100.0, max=None, description=''),
            InputField(key='mosfetRdson', label='MOSFET RDS(on)', unit='Ω', default=0.01, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='peakCurrent', label='Peak Current', unit='A', description=''),
            OutputField(key='mosfetCurrentRating', label='Min. MOSFET Current Rating', unit='A', description=''),
            OutputField(key='conductionLoss', label='Conduction Loss (per FET)', unit='W', description=''),
            OutputField(key='switchingLoss', label='Switching Loss (per FET)', unit='W', description=''),
            OutputField(key='totalLoss', label='Total Bridge Loss (est.)', unit='W', description=''),
        ),
        keywords=('H-bridge', 'motor driver', 'MOSFET selection', 'H-bridge design', 'motor driver IC', 'RDS(on) motor',),
    ),
    'motor-driver-power': CalculatorInfo(
        slug='motor-driver-power',
        title='Motor Driver Power Dissipation',
        category='motor',
        description='Calculate motor driver IC or discrete MOSFET power dissipation including conduction loss and switching loss at a given PWM frequency.',
        inputs=(
            InputField(key='motorCurrent', label='Motor Current (RMS)', unit='A', default=2.0, min=0.0, max=None, description=''),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=12.0, min=1.0, max=None, description=''),
            InputField(key='rdson', label='RDS(on)', unit='Ω', default=0.015, min=0.001, max=None, description=''),
            InputField(key='dutyCycle', label='PWM Duty Cycle', unit='%', default=75.0, min=0.0, max=100.0, description=''),
            InputField(key='switchingFreq', label='Switching Frequency', unit='Hz', default=20000.0, min=100.0, max=None, description=''),
            InputField(key='gateCharge', label='Gate Charge Qg', unit='nC', default=30.0, min=0.1, max=None, description='From MOSFET datasheet'),
        ),
        outputs=(
            OutputField(key='conductionLoss', label='Conduction Loss / FET', unit='W', description=''),
            OutputField(key='switchingLoss', label='Switching Loss / FET', unit='W', description=''),
            OutputField(key='totalLossPerFet', label='Total Loss / FET', unit='W', description=''),
            OutputField(key='totalLossBridge', label='Total Bridge Loss', unit='W', description=''),
            OutputField(key='efficiency', label='Driver Efficiency (est.)', unit='%', description=''),
        ),
        keywords=('motor driver power', 'motor driver loss', 'MOSFET switching loss', 'motor driver efficiency', 'PWM loss', 'motor driver heat',),
    ),
    'pid-tuning': CalculatorInfo(
        slug='pid-tuning',
        title='PID Controller Tuning (Ziegler-Nichols)',
        category='motor',
        description='Calculate PID controller gains using the Ziegler-Nichols open-loop (reaction curve) method from process gain, dead time, and time constant.',
        inputs=(
            InputField(key='processGain', label='Process Gain (K)', unit='', default=1.5, min=0.001, max=None, description='Output change / Input step size from step test'),
            InputField(key='deadTime', label='Dead Time (L)', unit='s', default=0.1, min=0.001, max=None, description='Time before response begins'),
            InputField(key='timeConstant', label='Time Constant (τ)', unit='s', default=1.0, min=0.001, max=None, description='Time for 63.2% of final step response'),
        ),
        outputs=(
            OutputField(key='kpPID', label='Kp (PID)', unit='', description=''),
            OutputField(key='kiPID', label='Ki (PID)', unit='1/s', description=''),
            OutputField(key='kdPID', label='Kd (PID)', unit='s', description=''),
            OutputField(key='kpPI', label='Kp (PI only)', unit='', description=''),
            OutputField(key='tiPI', label='Ti (PI only)', unit='s', description=''),
        ),
        keywords=('PID tuning', 'Ziegler-Nichols', 'PID gains', 'PID controller', 'motor PID', 'Kp Ki Kd',),
    ),
    'ntc-thermistor': CalculatorInfo(
        slug='ntc-thermistor',
        title='NTC Thermistor Temperature Calculator',
        category='sensor',
        description='Calculate temperature from NTC thermistor resistance using the Steinhart-Hart beta equation. Useful for PT100/PT1000 and generic NTC thermistors.',
        inputs=(
            InputField(key='resistance', label='Measured Resistance', unit='Ω', default=10000.0, min=0.1, max=None, description='Measured thermistor resistance at unknown temperature'),
            InputField(key='beta', label='Beta Coefficient', unit='K', default=3950.0, min=100.0, max=10000.0, description='Beta (B) coefficient of the thermistor, from datasheet. Typically 3000–4500 K.'),
            InputField(key='T0', label='Reference Temperature', unit='°C', default=25.0, min=-55.0, max=200.0, description='Reference temperature at which R0 is specified (usually 25°C)'),
            InputField(key='R0', label='Reference Resistance', unit='Ω', default=10000.0, min=0.1, max=None, description='Thermistor resistance at reference temperature T0 (e.g. 10kΩ at 25°C)'),
        ),
        outputs=(
            OutputField(key='temperature', label='Temperature', unit='°C', description='Calculated temperature in degrees Celsius'),
            OutputField(key='temperatureK', label='Temperature (Kelvin)', unit='K', description='Calculated temperature in Kelvin'),
        ),
        keywords=('NTC thermistor', 'thermistor temperature', 'Steinhart-Hart', 'beta equation', 'temperature sensor', 'NTC resistance', 'temperature from resistance',),
    ),
    'rtd-temperature': CalculatorInfo(
        slug='rtd-temperature',
        title='RTD Temperature Calculator (PT100/PT1000)',
        category='sensor',
        description='Calculate temperature from PT100 or PT1000 RTD (Resistance Temperature Detector) measured resistance using the linear Callendar-Van Dusen approximation.',
        inputs=(
            InputField(key='resistance', label='Measured Resistance', unit='Ω', default=119.4, min=1.0, max=None, description='Measured RTD resistance. At 0°C: PT100=100Ω, PT1000=1000Ω.'),
            InputField(key='r0', label='Nominal Resistance (R₀)', unit='Ω', default=100.0, min=1.0, max=None, description='Nominal resistance at 0°C, e.g. 100 for PT100, 1000 for PT1000'),
            InputField(key='alpha', label='Temperature Coefficient', unit='°C⁻¹', default=0.003851, min=0.001, max=0.01, description='Temperature coefficient of resistance. IEC 60751 standard: 0.003851 °C⁻¹'),
        ),
        outputs=(
            OutputField(key='temperature', label='Temperature', unit='°C', description='Calculated temperature using linear RTD approximation'),
            OutputField(key='resistanceAt100C', label='Resistance at 100°C', unit='Ω', description='Calculated resistance at 100°C for this RTD type'),
        ),
        keywords=('RTD temperature', 'PT100 calculator', 'PT1000 calculator', 'resistance temperature detector', 'Callendar-Van Dusen', 'temperature from resistance', 'RTD sensor',),
    ),
    'wheatstone-bridge': CalculatorInfo(
        slug='wheatstone-bridge',
        title='Wheatstone Bridge Calculator',
        category='sensor',
        description='Calculate Wheatstone bridge output voltage, balance condition, and sensitivity. Used for strain gauges, RTDs, and precision resistance measurements.',
        inputs=(
            InputField(key='vin', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=30.0, description='Bridge excitation supply voltage'),
            InputField(key='r1', label='R1 (top-left)', unit='Ω', default=1000.0, min=1.0, max=None, description='Bridge resistor R1 (top-left arm)'),
            InputField(key='r2', label='R2 (top-right)', unit='Ω', default=1000.0, min=1.0, max=None, description='Bridge resistor R2 (top-right arm)'),
            InputField(key='r3', label='R3 (bottom-left)', unit='Ω', default=1000.0, min=1.0, max=None, description='Bridge resistor R3 (bottom-left arm, often the sensor)'),
            InputField(key='r4', label='R4 (bottom-right)', unit='Ω', default=1000.0, min=1.0, max=None, description='Bridge resistor R4 (bottom-right arm)'),
        ),
        outputs=(
            OutputField(key='vout', label='Output Voltage', unit='V', description='Differential output voltage of the bridge'),
            OutputField(key='voutMv', label='Output Voltage', unit='mV', description='Differential output voltage in millivolts'),
            OutputField(key='balance', label='Balance Factor', unit='', description='Balance indicator: 0 = perfectly balanced (R1/R3 = R2/R4)'),
            OutputField(key='sensitivity', label='Sensitivity', unit='mV/V', description='Bridge sensitivity: output mV per V of excitation'),
        ),
        keywords=('Wheatstone bridge', 'bridge circuit', 'differential voltage', 'bridge balance', 'strain gauge', 'sensor bridge', 'bridge sensitivity',),
    ),
    'hall-effect-sensor': CalculatorInfo(
        slug='hall-effect-sensor',
        title='Hall Effect Sensor Calculator',
        category='sensor',
        description='Calculate Hall voltage, Hall coefficient, and sensitivity for Hall effect sensors. Useful for magnetic field measurement, current sensing, and position detection.',
        inputs=(
            InputField(key='current', label='Control Current', unit='mA', default=100.0, min=0.001, max=1000.0, description='Control current flowing through the Hall element'),
            InputField(key='Bfield', label='Magnetic Field', unit='mT', default=100.0, min=0.0, max=None, description='Applied magnetic field perpendicular to current flow'),
            InputField(key='thickness', label='Element Thickness', unit='mm', default=0.5, min=0.001, max=None, description='Thickness of the Hall element in the direction of magnetic field'),
            InputField(key='carrierDensity', label='Carrier Density (×10²³)', unit='×10²³/m³', default=8.5, min=0.001, max=None, description='Charge carrier density (8.5×10²³ for copper, ~10²⁴ for silicon)'),
        ),
        outputs=(
            OutputField(key='hallVoltage', label='Hall Voltage', unit='mV', description='Developed Hall voltage across the element'),
            OutputField(key='hallCoefficient', label='Hall Coefficient', unit='m³/C', description='Hall coefficient R_H = 1/(n·e)'),
            OutputField(key='sensitivity', label='Sensitivity', unit='mV/mT', description='Hall sensor sensitivity: output mV per mT of applied field'),
        ),
        keywords=('Hall effect', 'Hall voltage', 'Hall coefficient', 'magnetic sensor', 'current sensor', 'Hall sensor sensitivity', 'magnetic field measurement',),
    ),
    'strain-gauge-bridge': CalculatorInfo(
        slug='strain-gauge-bridge',
        title='Strain Gauge Bridge Calculator',
        category='sensor',
        description='Calculate Wheatstone bridge output voltage for strain gauges. Supports quarter, half, and full bridge configurations for structural monitoring and load cell design.',
        inputs=(
            InputField(key='vin', label='Excitation Voltage', unit='V', default=5.0, min=0.1, max=30.0, description='Bridge excitation (supply) voltage'),
            InputField(key='gaugeFactor', label='Gauge Factor', unit='', default=2.1, min=0.1, max=200.0, description='Gauge factor (sensitivity) of the strain gauge. Metal foil: ~2, semiconductor: 50–200.'),
            InputField(key='strain', label='Applied Strain', unit='με', default=1000.0, min=0.0, max=50000.0, description='Strain in microstrain (με). 1000 με = 0.1% elongation.'),
            InputField(key='bridgeConfig', label='Bridge Configuration', unit='active arms', default=1.0, min=1.0, max=4.0, description='Number of active gauge arms: 1=quarter bridge, 2=half bridge, 4=full bridge'),
        ),
        outputs=(
            OutputField(key='vout', label='Bridge Output', unit='mV', description='Bridge differential output voltage in millivolts'),
            OutputField(key='resistance_change', label='Resistance Change', unit='%', description='Fractional change in gauge resistance as percentage (ΔR/R = GF × ε)'),
            OutputField(key='strain_SI', label='Strain (SI)', unit='m/m', description='Strain in SI units (dimensionless, m/m)'),
        ),
        keywords=('strain gauge', 'Wheatstone bridge', 'gauge factor', 'microstrain', 'load cell', 'bridge output', 'structural monitoring',),
    ),
    'pt100-resistance': CalculatorInfo(
        slug='pt100-resistance',
        title='PT100/PT1000 Resistance vs Temperature',
        category='sensor',
        description='Calculate PT100 or PT1000 RTD resistance at any temperature using the ITS-90 Callendar-Van Dusen equation.',
        inputs=(
            InputField(key='r0', label='R₀ (at 0°C)', unit='Ω', default=100.0, min=1.0, max=None, description=''),
            InputField(key='temperature', label='Temperature', unit='°C', default=25.0, min=-200.0, max=850.0, description=''),
        ),
        outputs=(
            OutputField(key='resistance', label='Resistance', unit='Ω', description=''),
            OutputField(key='sensitivityOhmPerDeg', label='Sensitivity', unit='Ω/°C', description=''),
        ),
        keywords=('PT100', 'PT1000', 'RTD resistance', 'Callendar Van Dusen', 'temperature sensor resistance', 'RTD temperature',),
    ),
    'thermocouple-voltage': CalculatorInfo(
        slug='thermocouple-voltage',
        title='Thermocouple Voltage & Temperature',
        category='sensor',
        description='Calculate thermocouple EMF voltage from hot junction temperature and cold junction compensation for Type K, J, T, and E thermocouples.',
        inputs=(
            InputField(key='type', label='Thermocouple Type', unit='', default=0.0, min=0.0, max=3.0, description='0=K (41 μV/°C), 1=J (51 μV/°C), 2=T (43 μV/°C), 3=E (68 μV/°C)'),
            InputField(key='temperature', label='Hot Junction Temperature', unit='°C', default=200.0, min=-270.0, max=1372.0, description=''),
            InputField(key='coldJunctionTemp', label='Cold Junction Temperature', unit='°C', default=25.0, min=-50.0, max=70.0, description=''),
        ),
        outputs=(
            OutputField(key='voltage', label='Output Voltage', unit='μV', description=''),
            OutputField(key='coldJunctionCorrection', label='Cold Junction Correction', unit='μV', description=''),
            OutputField(key='seebeck', label='Seebeck Coefficient', unit='μV/°C', description=''),
            OutputField(key='deltaT', label='Temperature Difference', unit='°C', description=''),
        ),
        keywords=('thermocouple voltage', 'Type K thermocouple', 'cold junction compensation', 'thermocouple EMF', 'Seebeck coefficient', 'thermocouple mV',),
    ),
    'load-cell-amplifier': CalculatorInfo(
        slug='load-cell-amplifier',
        title='Load Cell Amplifier Gain',
        category='sensor',
        description='Calculate load cell output voltage, required amplifier gain, and sensitivity for Wheatstone bridge load cells.',
        inputs=(
            InputField(key='excitationVoltage', label='Excitation Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='sensitivity', label='Load Cell Sensitivity', unit='mV/V', default=2.0, min=0.01, max=None, description='From load cell datasheet, typically 1–3 mV/V'),
            InputField(key='fullScaleLoad', label='Full-Scale Load', unit='kg', default=10.0, min=0.001, max=None, description=''),
            InputField(key='gain', label='Amplifier Gain', unit='V/V', default=500.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='fullScaleOutputMv', label='Full-Scale Output', unit='mV', description=''),
            OutputField(key='amplifiedOutput', label='Amplified Full-Scale', unit='V', description=''),
            OutputField(key='sensitivityPerUnit', label='Sensitivity', unit='mV/kg', description=''),
            OutputField(key='requiredGain', label='Gain for 5V ADC', unit='V/V', description=''),
        ),
        keywords=('load cell amplifier', 'load cell gain', 'load cell mV/V', 'INA125 gain', 'strain gauge amplifier', 'weigh scale amplifier',),
    ),
    'photodiode-transimpedance': CalculatorInfo(
        slug='photodiode-transimpedance',
        title='Photodiode Transimpedance Amplifier',
        category='sensor',
        description='Calculate transimpedance amplifier (TIA) output voltage, bandwidth, and noise for photodiode signal conditioning.',
        inputs=(
            InputField(key='photocurrent', label='Photocurrent', unit='μA', default=10.0, min=0.001, max=None, description='At operating light level'),
            InputField(key='feedbackResistance', label='Feedback Resistor (Rf)', unit='kΩ', default=100.0, min=0.001, max=None, description=''),
            InputField(key='feedbackCapacitance', label='Feedback Capacitor (Cf)', unit='pF', default=10.0, min=0.001, max=None, description='Stabilizing capacitor in parallel with Rf'),
        ),
        outputs=(
            OutputField(key='outputVoltageV', label='Output Voltage', unit='mV', description=''),
            OutputField(key='bandwidth', label='Bandwidth (−3 dB)', unit='kHz', description=''),
            OutputField(key='noiseVoltage', label='Johnson Noise', unit='nV/√Hz', description=''),
        ),
        keywords=('transimpedance amplifier', 'TIA photodiode', 'photodiode amplifier', 'op-amp TIA', 'current to voltage converter', 'TIA bandwidth',),
    ),
    'capacitive-proximity': CalculatorInfo(
        slug='capacitive-proximity',
        title='Capacitive Proximity Sensor',
        category='sensor',
        description='Calculate capacitance between sensor plate and target, and sensitivity (pF/mm) for capacitive proximity sensor design.',
        inputs=(
            InputField(key='plateArea', label='Sensor Plate Area', unit='cm²', default=1.0, min=0.001, max=None, description=''),
            InputField(key='gapDistance', label='Gap to Target', unit='mm', default=5.0, min=0.1, max=None, description=''),
            InputField(key='permittivity', label='Relative Permittivity (εᵣ)', unit='', default=1.0, min=1.0, max=None, description='Air: 1, Glass: 4–10, Water: 80'),
        ),
        outputs=(
            OutputField(key='capacitancePf', label='Capacitance', unit='pF', description=''),
            OutputField(key='sensitivity', label='Sensitivity', unit='pF/mm', description=''),
        ),
        keywords=('capacitive proximity sensor', 'capacitive sensor', 'proximity sensor design', 'capacitance gap', 'touch sensor', 'capacitive transducer',),
    ),
    'current-shunt': CalculatorInfo(
        slug='current-shunt',
        title='Current Shunt Resistor',
        category='sensor',
        description='Calculate shunt resistor voltage drop, amplifier output, power dissipation, and ADC resolution for current sensing.',
        inputs=(
            InputField(key='current', label='Measured Current', unit='A', default=10.0, min=0.0, max=None, description=''),
            InputField(key='shuntResistance', label='Shunt Resistance', unit='mΩ', default=10.0, min=0.001, max=None, description=''),
            InputField(key='amplifierGain', label='Amplifier Gain', unit='V/V', default=50.0, min=1.0, max=None, description='INA219: 1–128×, INA240: 20–200×'),
            InputField(key='adcVoltage', label='ADC Reference Voltage', unit='V', default=3.3, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='shuntVoltage', label='Shunt Voltage Drop', unit='mV', description=''),
            OutputField(key='amplifiedVoltage', label='Amplified Voltage', unit='V', description=''),
            OutputField(key='powerDissipation', label='Shunt Power Dissipation', unit='mW', description=''),
            OutputField(key='adcResolutionCurrent', label='ADC Resolution (12-bit)', unit='mA/LSB', description=''),
        ),
        keywords=('current shunt', 'shunt resistor', 'current sensing', 'INA219', 'current monitor', 'shunt amplifier',),
    ),
    'accelerometer-sensitivity': CalculatorInfo(
        slug='accelerometer-sensitivity',
        title='Accelerometer Range & Sensitivity',
        category='sensor',
        description='Calculate accelerometer output voltage, ADC resolution, and mg per LSB from sensitivity and full-scale range specifications.',
        inputs=(
            InputField(key='sensitivity', label='Sensitivity', unit='mV/g', default=300.0, min=0.001, max=None, description='From accelerometer datasheet (e.g., ADXL335: 300 mV/g)'),
            InputField(key='fullScaleRange', label='Full-Scale Range', unit='g', default=3.0, min=0.1, max=None, description=''),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=3.3, min=0.1, max=None, description=''),
            InputField(key='adcBits', label='ADC Resolution', unit='bits', default=12.0, min=8.0, max=24.0, description=''),
        ),
        outputs=(
            OutputField(key='fullScaleVoltage', label='Full-Scale Output Swing', unit='mV', description=''),
            OutputField(key='voltagePerCount', label='Voltage per LSB', unit='mV', description=''),
            OutputField(key='accelerationMgPerCount', label='Acceleration per LSB', unit='mg', description=''),
        ),
        keywords=('accelerometer sensitivity', 'accelerometer range', 'MEMS accelerometer', 'mg/LSB', 'accelerometer ADC', 'vibration sensor',),
    ),
    'pressure-bridge-output': CalculatorInfo(
        slug='pressure-bridge-output',
        title='Pressure Sensor Bridge Output',
        category='sensor',
        description='Calculate Wheatstone bridge output voltage for piezoresistive pressure sensors from excitation, sensitivity, and applied pressure.',
        inputs=(
            InputField(key='excitationVoltage', label='Bridge Excitation Voltage', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='bridgeSensitivity', label='Bridge Sensitivity', unit='mV/V', default=10.0, min=0.001, max=None, description='Full-scale output in mV per V of excitation'),
            InputField(key='appliedPressure', label='Applied Pressure', unit='kPa', default=50.0, min=0.0, max=None, description=''),
            InputField(key='fullScalePressure', label='Full-Scale Pressure', unit='kPa', default=100.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='bridgeOutputMv', label='Bridge Output', unit='mV', description=''),
            OutputField(key='fullScaleOutput', label='Full-Scale Output', unit='mV', description=''),
            OutputField(key='fractionalDeflection', label='Fractional Deflection', unit='%', description=''),
        ),
        keywords=('pressure sensor bridge', 'piezoresistive sensor', 'bridge output voltage', 'pressure transducer mV/V', 'pressure sensor output', 'bridge pressure',),
    ),
    'sensor-accuracy-budget': CalculatorInfo(
        slug='sensor-accuracy-budget',
        title='Sensor Accuracy Budget',
        category='sensor',
        description='Calculate total sensor system accuracy using RSS and worst-case methods from offset, gain, nonlinearity, resolution, and temperature drift errors.',
        inputs=(
            InputField(key='offsetError', label='Offset Error', unit='% FS', default=0.1, min=0.0, max=None, description=''),
            InputField(key='gainError', label='Gain/Sensitivity Error', unit='% FS', default=0.2, min=0.0, max=None, description=''),
            InputField(key='nonlinearity', label='Nonlinearity', unit='% FS', default=0.1, min=0.0, max=None, description=''),
            InputField(key='resolution', label='Resolution Error', unit='% FS', default=0.05, min=0.0, max=None, description=''),
            InputField(key='tempDrift', label='Temp Drift', unit='% FS/°C', default=0.005, min=0.0, max=None, description=''),
            InputField(key='tempRange', label='Temperature Range', unit='°C', default=40.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='tempError', label='Temperature Error', unit='% FS', description=''),
            OutputField(key='totalRss', label='Total Accuracy (RSS)', unit='% FS', description=''),
            OutputField(key='totalWorstCase', label='Total Accuracy (Worst Case)', unit='% FS', description=''),
        ),
        keywords=('sensor accuracy budget', 'error budget', 'sensor accuracy', 'RSS error', 'sensor system accuracy', 'measurement accuracy',),
    ),
    'optical-sensor-range': CalculatorInfo(
        slug='optical-sensor-range',
        title='Optical Proximity Sensor Range',
        category='sensor',
        description='Compare optical proximity sensor configurations using a relative detection factor derived from emitter power, detector responsivity, and target reflectivity. The output is dimensionless — use it to ra',
        inputs=(
            InputField(key='emitterPower', label='Emitter Power', unit='mW', default=10.0, min=0.001, max=None, description=''),
            InputField(key='detectorSensitivity', label='Detector Responsivity', unit='A/W', default=0.6, min=0.001, max=None, description='Typical silicon photodiode: 0.5–0.8 A/W at 850 nm'),
            InputField(key='targetReflectivity', label='Target Reflectivity', unit='%', default=90.0, min=0.1, max=100.0, description=''),
            InputField(key='safetyFactor', label='Safety Factor', unit='', default=1.5, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='maxRange', label='Relative Detection Factor', unit='', description=''),
            OutputField(key='normalizedRange', label='Nominal Detection Factor', unit='', description=''),
        ),
        keywords=('optical proximity sensor', 'IR sensor range', 'photointerrupter', 'reflective optical sensor', 'sensor range', 'optical encoder range',),
    ),
    'lvdt-sensitivity': CalculatorInfo(
        slug='lvdt-sensitivity',
        title='LVDT Sensitivity & Range',
        category='sensor',
        description='Calculate LVDT (Linear Variable Differential Transformer) output voltage, sensitivity in mV/mm, and linear range from excitation and stroke.',
        inputs=(
            InputField(key='excitationVoltage', label='Excitation Voltage (RMS)', unit='V', default=5.0, min=0.1, max=None, description=''),
            InputField(key='sensitivity', label='Sensitivity', unit='mV/V/%FS', default=4.0, min=0.001, max=None, description='mV output per V excitation per % of full stroke (from datasheet)'),
            InputField(key='coreDisplacement', label='Core Displacement', unit='mm', default=5.0, min=0.0, max=None, description=''),
            InputField(key='fullScaleRange', label='Full-Scale Range (±)', unit='mm', default=25.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='outputVoltage', label='Output Voltage (RMS)', unit='mV', description=''),
            OutputField(key='fullScaleOutput', label='Full-Scale Output', unit='mV', description=''),
            OutputField(key='sensitivityMvMm', label='Sensitivity', unit='mV/mm', description=''),
            OutputField(key='linearRange', label='Linear Range (est.)', unit='mm', description=''),
        ),
        keywords=('LVDT', 'linear variable differential transformer', 'LVDT sensitivity', 'LVDT range', 'displacement sensor', 'position sensor LVDT',),
    ),
    '4-20ma-transmitter': CalculatorInfo(
        slug='4-20ma-transmitter',
        title='4–20 mA Loop Transmitter',
        category='sensor',
        description='Calculate 4–20 mA current loop voltage budget, sensor value from current, and maximum loop resistance for industrial sensor transmitters.',
        inputs=(
            InputField(key='supplyVoltage', label='Loop Supply Voltage', unit='V', default=24.0, min=12.0, max=None, description=''),
            InputField(key='loopCurrent', label='Loop Current', unit='mA', default=12.0, min=4.0, max=20.0, description=''),
            InputField(key='loopResistance', label='Loop Resistance', unit='Ω', default=250.0, min=0.0, max=None, description='Total cable + load resistance (250 Ω = standard 1–5 V input)'),
            InputField(key='sensorRangeMin', label='Sensor Range Min', unit='', default=0.0, min=-99999.0, max=None, description=''),
            InputField(key='sensorRangeMax', label='Sensor Range Max', unit='', default=100.0, min=-99999.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='sensorValue', label='Sensor Value', unit='eng units', description=''),
            OutputField(key='voltageAtLoad', label='Voltage at Load', unit='V', description=''),
            OutputField(key='availableVoltage', label='Transmitter Voltage', unit='V', description=''),
            OutputField(key='maxLoopResistance', label='Max Loop Resistance', unit='Ω', description=''),
        ),
        keywords=('4-20mA loop', 'current loop', '4-20mA transmitter', 'industrial sensor', 'loop resistance', 'HART current loop',),
    ),
    'frequency-wavelength': CalculatorInfo(
        slug='frequency-wavelength',
        title='Frequency to Wavelength Converter',
        category='unit-conversion',
        description='Convert frequency to wavelength in any medium. Calculates full, half, and quarter wavelengths for antenna design, transmission line, and RF system planning.',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='MHz', default=2400.0, min=0.001, max=None, description='Signal frequency in MHz'),
            InputField(key='velocityFactor', label='Velocity Factor', unit='', default=1.0, min=0.01, max=1.0, description='Velocity factor of medium: 1.0=free space, 0.66=coax, 0.97=FR4 PCB, 0.85=open-wire'),
        ),
        outputs=(
            OutputField(key='wavelength', label='Wavelength', unit='m', description='Full wavelength in meters'),
            OutputField(key='wavelengthCm', label='Wavelength', unit='cm', description='Full wavelength in centimeters'),
            OutputField(key='wavelengthMm', label='Wavelength', unit='mm', description='Full wavelength in millimeters'),
            OutputField(key='halfWave', label='Half Wavelength (λ/2)', unit='m', description='Half wavelength — typical dipole antenna length'),
            OutputField(key='quarterWave', label='Quarter Wavelength (λ/4)', unit='m', description='Quarter wavelength — typical monopole antenna length'),
        ),
        keywords=('frequency wavelength', 'wavelength calculator', 'velocity factor', 'half wavelength', 'quarter wavelength', 'antenna length', 'transmission line wavelength',),
    ),
    'dbm-watts': CalculatorInfo(
        slug='dbm-watts',
        title='dBm to Watts Power Converter',
        category='unit-conversion',
        description='Convert RF power between dBm, Watts, milliwatts, dBW, dBμV, and RMS volts into 50Ω. Essential for link budgets, amplifier analysis, and RF system design.',
        inputs=(
            InputField(key='dbm', label='Power', unit='dBm', default=0.0, min=-200.0, max=100.0, description='Power level in dBm (dB relative to 1 milliwatt)'),
        ),
        outputs=(
            OutputField(key='watts', label='Power', unit='W', description='Power in Watts'),
            OutputField(key='milliwatts', label='Power', unit='mW', description='Power in milliwatts'),
            OutputField(key='dBW', label='Power', unit='dBW', description='Power in dBW (dB relative to 1 Watt). dBW = dBm − 30'),
            OutputField(key='dBuV', label='Voltage Level (50Ω)', unit='dBμV', description='Voltage level in dBμV referenced to 1μV, in 50Ω system'),
            OutputField(key='volts', label='RMS Voltage (50Ω)', unit='V', description='RMS voltage into 50Ω load: V = √(P × 50)'),
        ),
        keywords=('dBm to watts', 'power converter', 'dBm calculator', 'RF power', 'dBW converter', 'milliwatts', 'dBuV', 'RF unit conversion',),
    ),
    'temperature-converter': CalculatorInfo(
        slug='temperature-converter',
        title='Temperature Unit Converter',
        category='unit-conversion',
        description='Convert temperature between Celsius, Fahrenheit, Kelvin, Rankine, and Réaumur scales. Useful for thermal analysis, datasheet comparison, and engineering calculations.',
        inputs=(
            InputField(key='celsius', label='Temperature', unit='°C', default=25.0, min=-273.15, max=None, description='Temperature in degrees Celsius'),
        ),
        outputs=(
            OutputField(key='fahrenheit', label='Fahrenheit', unit='°F', description='Temperature in degrees Fahrenheit: F = C × 9/5 + 32'),
            OutputField(key='kelvin', label='Kelvin', unit='K', description='Temperature in Kelvin (absolute scale): K = C + 273.15'),
            OutputField(key='rankine', label='Rankine', unit='°R', description='Temperature in degrees Rankine (absolute Fahrenheit scale): R = K × 9/5'),
            OutputField(key='reaumur', label='Réaumur', unit='°Ré', description='Temperature in degrees Réaumur: Ré = C × 4/5'),
        ),
        keywords=('temperature converter', 'Celsius to Fahrenheit', 'Kelvin converter', 'Rankine temperature', 'temperature unit conversion', 'C to F', 'K to C',),
    ),
    'awg-wire': CalculatorInfo(
        slug='awg-wire',
        title='AWG Wire Gauge Calculator',
        category='unit-conversion',
        description='Convert AWG wire gauge to diameter (mm/inches), cross-sectional area (mm²), resistance per meter, and approximate current carrying capacity.',
        inputs=(
            InputField(key='awg', label='AWG Gauge', unit='AWG', default=24.0, min=0.0, max=40.0, description='American Wire Gauge number. Lower number = thicker wire.'),
        ),
        outputs=(
            OutputField(key='diameterMm', label='Diameter', unit='mm', description='Wire conductor diameter in millimeters'),
            OutputField(key='diameterIn', label='Diameter', unit='in', description='Wire conductor diameter in inches'),
            OutputField(key='areaMm2', label='Cross-Section Area', unit='mm²', description='Conductor cross-sectional area in mm²'),
            OutputField(key='resistance20C', label='Resistance (20°C)', unit='mΩ/m', description='DC resistance per meter at 20°C for copper conductor'),
            OutputField(key='currentCapacity', label='Current Capacity', unit='A', description='Approximate current capacity for chassis wiring (free air). Derate 40–50% in conduit.'),
        ),
        keywords=('AWG wire gauge', 'wire diameter', 'wire resistance', 'copper wire', 'wire cross section', 'current capacity', 'wire calculator', 'AWG to mm',),
    ),
    'capacitor-code': CalculatorInfo(
        slug='capacitor-code',
        title='Capacitor Code Decoder',
        category='unit-conversion',
        description='Decode 3-digit capacitor code (e.g., 104 = 100nF) to capacitance in pF, nF, and μF. Works with ceramic, film, and tantalum capacitor markings.',
        inputs=(
            InputField(key='code', label='Capacitor Code', unit='', default=104.0, min=100.0, max=999.0, description='3-digit code: first 2 digits = significant figures, 3rd digit = multiplier power of 10 in pF. E.g., 104 = 10 × 10⁴ pF = 100nF'),
        ),
        outputs=(
            OutputField(key='picofarads', label='Capacitance', unit='pF', description='Capacitance in picofarads (pF)'),
            OutputField(key='nanofarads', label='Capacitance', unit='nF', description='Capacitance in nanofarads (nF)'),
            OutputField(key='microfarads', label='Capacitance', unit='μF', description='Capacitance in microfarads (μF)'),
            OutputField(key='voltageCode', label='Voltage Code', unit='V', description='Voltage rating from separate letter code (if present; 0 = not encoded in 3-digit code)'),
        ),
        keywords=('capacitor code', 'capacitor decoder', '3-digit code', 'capacitor value', 'ceramic capacitor', '104 capacitor', 'capacitor marking',),
    ),
    'inductance-units': CalculatorInfo(
        slug='inductance-units',
        title='Inductance Unit Converter',
        category='unit-conversion',
        description='Convert inductance between henries, millihenries, microhenries, nanohenries, and picohenries.',
        inputs=(
            InputField(key='henry', label='Inductance', unit='H', default=1e-06, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='millihenry', label='Millihenries', unit='mH', description=''),
            OutputField(key='microhenry', label='Microhenries', unit='μH', description=''),
            OutputField(key='nanohenry', label='Nanohenries', unit='nH', description=''),
            OutputField(key='picohenry', label='Picohenries', unit='pH', description=''),
        ),
        keywords=('inductance converter', 'henry to microhenry', 'mH to μH', 'nH to μH', 'inductance unit conversion', 'inductor value converter',),
    ),
    'capacitance-units': CalculatorInfo(
        slug='capacitance-units',
        title='Capacitance Unit Converter',
        category='unit-conversion',
        description='Convert capacitance between farads, millifarads, microfarads, nanofarads, and picofarads.',
        inputs=(
            InputField(key='farad', label='Capacitance', unit='F', default=1e-07, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='millifarad', label='Millifarads', unit='mF', description=''),
            OutputField(key='microfarad', label='Microfarads', unit='μF', description=''),
            OutputField(key='nanofarad', label='Nanofarads', unit='nF', description=''),
            OutputField(key='picofarad', label='Picofarads', unit='pF', description=''),
        ),
        keywords=('capacitance converter', 'μF to nF', 'pF to nF', 'capacitor value converter', 'capacitance unit conversion', 'farad converter',),
    ),
    'resistance-units': CalculatorInfo(
        slug='resistance-units',
        title='Resistance Unit Converter',
        category='unit-conversion',
        description='Convert resistance between milliohms, ohms, kilohms, megaohms, and gigaohms.',
        inputs=(
            InputField(key='ohm', label='Resistance', unit='Ω', default=1000.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='milliohm', label='Milliohms', unit='mΩ', description=''),
            OutputField(key='kilohm', label='Kilohms', unit='kΩ', description=''),
            OutputField(key='megaohm', label='Megaohms', unit='MΩ', description=''),
            OutputField(key='gigaohm', label='Gigaohms', unit='GΩ', description=''),
        ),
        keywords=('resistance converter', 'ohm to kilohm', 'MΩ to kΩ', 'resistance unit conversion', 'resistor value converter', 'mΩ to Ω',),
    ),
    'current-units': CalculatorInfo(
        slug='current-units',
        title='Current Unit Converter',
        category='unit-conversion',
        description='Convert electric current between amperes, milliamperes, microamperes, nanoamperes, and picoamperes.',
        inputs=(
            InputField(key='ampere', label='Current', unit='A', default=0.01, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='milliampere', label='Milliamperes', unit='mA', description=''),
            OutputField(key='microampere', label='Microamperes', unit='μA', description=''),
            OutputField(key='nanoampere', label='Nanoamperes', unit='nA', description=''),
            OutputField(key='picoampere', label='Picoamperes', unit='pA', description=''),
        ),
        keywords=('current converter', 'mA to μA', 'nA to mA', 'current unit conversion', 'ampere converter', 'μA to A',),
    ),
    'voltage-units': CalculatorInfo(
        slug='voltage-units',
        title='Voltage Unit Converter',
        category='unit-conversion',
        description='Convert voltage between microvolts, millivolts, volts, kilovolts, and megavolts.',
        inputs=(
            InputField(key='volt', label='Voltage', unit='V', default=1.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='microvolt', label='Microvolts', unit='μV', description=''),
            OutputField(key='millivolt', label='Millivolts', unit='mV', description=''),
            OutputField(key='kilovolt', label='Kilovolts', unit='kV', description=''),
            OutputField(key='megavolt', label='Megavolts', unit='MV', description=''),
        ),
        keywords=('voltage converter', 'mV to V', 'kV to V', 'voltage unit conversion', 'volt converter', 'μV to mV',),
    ),
    'time-units': CalculatorInfo(
        slug='time-units',
        title='Time Unit Converter',
        category='unit-conversion',
        description='Convert time between seconds, milliseconds, microseconds, nanoseconds, picoseconds, and femtoseconds for digital and RF applications.',
        inputs=(
            InputField(key='second', label='Time', unit='s', default=1e-06, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='millisecond', label='Milliseconds', unit='ms', description=''),
            OutputField(key='microsecond', label='Microseconds', unit='μs', description=''),
            OutputField(key='nanosecond', label='Nanoseconds', unit='ns', description=''),
            OutputField(key='picosecond', label='Picoseconds', unit='ps', description=''),
            OutputField(key='femtosecond', label='Femtoseconds', unit='fs', description=''),
        ),
        keywords=('time unit converter', 'ns to μs', 'ms to μs', 'picosecond converter', 'nanosecond converter', 'time conversion electronics',),
    ),
    'magnetic-flux-units': CalculatorInfo(
        slug='magnetic-flux-units',
        title='Magnetic Flux Density Converter',
        category='unit-conversion',
        description='Convert magnetic flux density between Tesla, milliTesla, microTesla, Gauss, and nanoTesla for sensor and motor applications.',
        inputs=(
            InputField(key='tesla', label='Magnetic Flux Density', unit='T', default=0.001, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='millitesla', label='Millitesla', unit='mT', description=''),
            OutputField(key='microtesla', label='Microtesla', unit='μT', description=''),
            OutputField(key='nanotesla', label='Nanotesla', unit='nT', description=''),
            OutputField(key='gauss', label='Gauss', unit='G', description=''),
        ),
        keywords=('tesla converter', 'gauss to tesla', 'magnetic flux density', 'magnetic field units', 'nT to μT', 'magnetics unit conversion',),
    ),
    'data-rate-units': CalculatorInfo(
        slug='data-rate-units',
        title='Data Rate Unit Converter',
        category='unit-conversion',
        description='Convert data rates between bits per second (bps), kbps, Mbps, Gbps, and bytes per second.',
        inputs=(
            InputField(key='bps', label='Data Rate', unit='bps', default=1000000.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='kbps', label='Kilobits/sec', unit='kbps', description=''),
            OutputField(key='mbps', label='Megabits/sec', unit='Mbps', description=''),
            OutputField(key='gbps', label='Gigabits/sec', unit='Gbps', description=''),
            OutputField(key='bytesPerSecond', label='Bytes/sec', unit='B/s', description=''),
            OutputField(key='kBps', label='Kilobytes/sec', unit='kB/s', description=''),
            OutputField(key='mBps', label='Megabytes/sec', unit='MB/s', description=''),
        ),
        keywords=('data rate converter', 'bps to Mbps', 'Mbps to MBps', 'bandwidth converter', 'bits per second', 'data throughput',),
    ),
    'angle-units': CalculatorInfo(
        slug='angle-units',
        title='Angle Unit Converter',
        category='unit-conversion',
        description='Convert angles between degrees, radians, gradians, arcminutes, arcseconds, and turns for motor, antenna, and RF applications.',
        inputs=(
            InputField(key='degree', label='Angle', unit='°', default=90.0, min=-360.0, max=360.0, description=''),
        ),
        outputs=(
            OutputField(key='radian', label='Radians', unit='rad', description=''),
            OutputField(key='gradian', label='Gradians', unit='grad', description=''),
            OutputField(key='arcminute', label='Arcminutes', unit="'", description=''),
            OutputField(key='arcsecond', label='Arcseconds', unit='"', description=''),
            OutputField(key='turn', label='Turns', unit='rev', description=''),
        ),
        keywords=('angle converter', 'degrees to radians', 'radians to degrees', 'gradian', 'arcminute arcsecond', 'angle unit conversion',),
    ),
    'energy-units': CalculatorInfo(
        slug='energy-units',
        title='Energy Unit Converter',
        category='unit-conversion',
        description='Convert energy between joules, millijoules, electron-volts, kilowatt-hours, calories, and BTU.',
        inputs=(
            InputField(key='joule', label='Energy', unit='J', default=1.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='millijoule', label='Millijoules', unit='mJ', description=''),
            OutputField(key='microjoule', label='Microjoules', unit='μJ', description=''),
            OutputField(key='electronvolt', label='Electron-Volts', unit='eV', description=''),
            OutputField(key='kwh', label='Kilowatt-Hours', unit='kWh', description=''),
            OutputField(key='calorie', label='Calories', unit='cal', description=''),
            OutputField(key='btu', label='BTU', unit='BTU', description=''),
        ),
        keywords=('energy converter', 'joule to kWh', 'eV to joule', 'energy unit conversion', 'BTU to joule', 'calorie converter',),
    ),
    'torque-units': CalculatorInfo(
        slug='torque-units',
        title='Torque Unit Converter (N·m/lb·ft/oz·in)',
        category='unit-conversion',
        description='Convert torque between Newton-metres, pound-feet, pound-inches, oz·in, kg·cm, kg·m, and dyne·cm.',
        inputs=(
            InputField(key='nm', label='Torque', unit='N·m', default=1.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='lbFt', label='Pound-feet', unit='lb·ft', description=''),
            OutputField(key='lbIn', label='Pound-inches', unit='lb·in', description=''),
            OutputField(key='ozIn', label='Oz-inches', unit='oz·in', description=''),
            OutputField(key='kgCm', label='Kg-centimetres', unit='kg·cm', description=''),
            OutputField(key='kgM', label='Kg-metres', unit='kg·m', description=''),
            OutputField(key='dyneCm', label='Dyne·cm', unit='dyn·cm', description=''),
        ),
        keywords=('torque unit converter', 'N-m to lb-ft', 'oz-in to N-m', 'torque conversion', 'kg-cm to N-m', 'torque units',),
    ),
    'illuminance-units': CalculatorInfo(
        slug='illuminance-units',
        title='Illuminance Unit Converter',
        category='unit-conversion',
        description='Convert illuminance between lux, foot-candles, millilux, kilolux, and phot for ambient light sensor and LED design.',
        inputs=(
            InputField(key='lux', label='Illuminance', unit='lux', default=500.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='footcandle', label='Foot-candles', unit='fc', description=''),
            OutputField(key='millilux', label='Millilux', unit='mlux', description=''),
            OutputField(key='kilolux', label='Kilolux', unit='klux', description=''),
            OutputField(key='phot', label='Phot', unit='ph', description=''),
        ),
        keywords=('lux converter', 'lux to foot-candle', 'illuminance converter', 'foot-candle to lux', 'light level converter', 'ambient light units',),
    ),
    'junction-temperature': CalculatorInfo(
        slug='junction-temperature',
        title='Junction Temperature Calculator',
        category='thermal',
        description='Calculate semiconductor junction temperature from power dissipation and thermal resistance chain (θJC + θCS + θSA). Essential for transistor, MOSFET, and IC thermal design.',
        inputs=(
            InputField(key='pd', label='Power Dissipation', unit='W', default=1.0, min=0.0, max=None, description='Power dissipated in the device (Watts)'),
            InputField(key='ta', label='Ambient Temperature', unit='°C', default=25.0, min=-55.0, max=125.0, description='Ambient (surrounding air) temperature'),
            InputField(key='thetaJC', label='θ_JC (Junction-to-Case)', unit='°C/W', default=5.0, min=0.0, max=None, description='Junction-to-case thermal resistance from device datasheet'),
            InputField(key='thetaCS', label='θ_CS (Case-to-Heatsink)', unit='°C/W', default=0.5, min=0.0, max=None, description='Case-to-heatsink thermal resistance (thermal pad/paste). ~0.1–1.0 °C/W typical.'),
            InputField(key='thetaSA', label='θ_SA (Heatsink-to-Ambient)', unit='°C/W', default=10.0, min=0.0, max=None, description='Heatsink-to-ambient thermal resistance. Lower = better heatsink. ~1–50 °C/W typical.'),
        ),
        outputs=(
            OutputField(key='thetaJA', label='θ_JA (Total)', unit='°C/W', description='Total junction-to-ambient thermal resistance: θJA = θJC + θCS + θSA'),
            OutputField(key='tj', label='Junction Temperature', unit='°C', description='Device junction temperature: TJ = TA + PD × θJA'),
            OutputField(key='tc', label='Case Temperature', unit='°C', description='Device case/package temperature'),
            OutputField(key='ts', label='Heatsink Temperature', unit='°C', description='Heatsink temperature'),
            OutputField(key='margin', label='Thermal Margin', unit='°C', description='Temperature margin below 125°C maximum junction temperature. Positive = safe.'),
        ),
        keywords=('junction temperature', 'thermal resistance', 'theta JA', 'heatsink design', 'power dissipation', 'thermal management', 'MOSFET junction temperature',),
    ),
    'heatsink-selection': CalculatorInfo(
        slug='heatsink-selection',
        title='Heatsink Selection Calculator',
        category='thermal',
        description='Calculate the required heatsink thermal resistance (θSA) to keep a device junction below its maximum temperature. Use this to select an appropriate heatsink.',
        inputs=(
            InputField(key='pd', label='Power Dissipation', unit='W', default=5.0, min=0.001, max=None, description='Power dissipated in the device that must be removed'),
            InputField(key='ta', label='Ambient Temperature', unit='°C', default=40.0, min=-55.0, max=125.0, description='Maximum ambient (surrounding air) temperature'),
            InputField(key='tjMax', label='Max Junction Temperature', unit='°C', default=125.0, min=50.0, max=200.0, description='Maximum allowable junction temperature from device datasheet'),
            InputField(key='thetaJC', label='θ_JC (Junction-to-Case)', unit='°C/W', default=3.0, min=0.0, max=None, description='Junction-to-case thermal resistance from device datasheet'),
            InputField(key='thetaCS', label='θ_CS (Case-to-Heatsink)', unit='°C/W', default=0.5, min=0.0, max=None, description='Case-to-heatsink thermal resistance (thermal interface material)'),
        ),
        outputs=(
            OutputField(key='thetaSARequired', label='Required θ_SA', unit='°C/W', description='Maximum heatsink-to-ambient thermal resistance required. Select a heatsink with θSA ≤ this value.'),
            OutputField(key='tjActual', label='Actual Junction Temp', unit='°C', description='Junction temperature achieved with the exactly required heatsink'),
            OutputField(key='deltaTJ', label='Thermal Margin', unit='°C', description='Temperature margin below maximum junction temperature'),
        ),
        keywords=('heatsink selection', 'required thermal resistance', 'theta SA', 'heatsink design', 'thermal resistance', 'junction temperature', 'thermal management',),
    ),
    'thermal-via-array': CalculatorInfo(
        slug='thermal-via-array',
        title='Thermal Via Array Calculator',
        category='thermal',
        description='Calculate thermal resistance of a PCB thermal via array for heat spreading from SMD packages to inner copper planes or heatsinks.',
        inputs=(
            InputField(key='numVias', label='Number of Vias', unit='vias', default=9.0, min=1.0, max=10000.0, description='Total number of thermal vias in the array'),
            InputField(key='viaDiameter', label='Via Drill Diameter', unit='mm', default=0.3, min=0.05, max=5.0, description='Via drill hole diameter. IPC-7093 recommends 0.2–0.4mm for thermal vias.'),
            InputField(key='platingThickness', label='Copper Plating', unit='μm', default=25.0, min=1.0, max=200.0, description='Via barrel copper plating thickness. Typical PCB: 18–35μm. Ignored if filled.'),
            InputField(key='pcbThickness', label='PCB Thickness', unit='mm', default=1.6, min=0.1, max=10.0, description='PCB thickness (length of the via thermal path)'),
            InputField(key='copperThermal', label='Thermal Conductivity', unit='W/m·K', default=385.0, min=1.0, max=None, description='Thermal conductivity of via fill material. Copper: 385, silver: 430, thermal epoxy: 1–5.'),
            InputField(key='drillFill', label='Fill Fraction', unit='', default=0.0, min=0.0, max=1.0, description='0 = hollow plated via, 1 = fully filled with copper. Filled vias offer best thermal performance.'),
        ),
        outputs=(
            OutputField(key='thetaPerVia', label='Resistance Per Via', unit='°C/W', description='Thermal resistance of a single via'),
            OutputField(key='thetaArray', label='Array Thermal Resistance', unit='°C/W', description='Total thermal resistance of all vias in parallel: θ_array = θ_via / N'),
            OutputField(key='effectiveConductance', label='Effective Conductance', unit='W/°C', description='Thermal conductance of the array (reciprocal of θ_array)'),
        ),
        keywords=('thermal via', 'via array', 'PCB thermal', 'thermal resistance', 'via thermal resistance', 'heat spreading', 'SMD thermal', 'PCB heatsink',),
    ),
    'pll-loop-filter': CalculatorInfo(
        slug='pll-loop-filter',
        title='PLL Loop Filter Designer',
        category='signal',
        description='Design a type-2 second-order PLL passive loop filter. Calculates time constants, capacitor and resistor values for target loop bandwidth and phase margin.',
        inputs=(
            InputField(key='fRef', label='Reference Frequency', unit='kHz', default=100.0, min=0.001, max=None, description='Reference (comparison) frequency at phase detector input'),
            InputField(key='loopBW', label='Loop Bandwidth', unit='kHz', default=5.0, min=0.001, max=None, description='Desired closed-loop bandwidth (crossover frequency). Typically 1/10 to 1/100 of reference frequency.'),
            InputField(key='phaseMargin', label='Phase Margin', unit='deg', default=45.0, min=10.0, max=89.0, description='Desired phase margin for loop stability. 45° provides good transient response.'),
            InputField(key='kvco', label='VCO Gain', unit='MHz/V', default=20.0, min=0.001, max=None, description='VCO frequency tuning gain (sensitivity). From VCO datasheet.'),
            InputField(key='n', label='Divider Ratio', unit='', default=100.0, min=1.0, max=None, description='Feedback divider ratio N. f_out = N × f_ref.'),
            InputField(key='icp', label='Charge Pump Current', unit='μA', default=500.0, min=1.0, max=10000.0, description='Charge pump output current. From PLL IC datasheet.'),
        ),
        outputs=(
            OutputField(key='c1', label='C1 (primary capacitor)', unit='nF', description='Primary integrating capacitor. Determines loop gain.'),
            OutputField(key='r1', label='R1 (zero resistor)', unit='kΩ', description='Resistor in series with C1. Sets the stabilizing zero.'),
            OutputField(key='c2', label='C2 (pole capacitor)', unit='pF', description='Secondary capacitor (C2 = C1/10). Provides high-frequency spur filtering.'),
            OutputField(key='pmActual', label='Actual Phase Margin', unit='°', description='Computed phase margin at the crossover frequency.'),
            OutputField(key='bwRatio', label='BW / f_ref Ratio', unit='', description='Loop bandwidth to reference frequency ratio. Should be < 0.1 for low spurs.'),
        ),
        keywords=('PLL loop filter', 'phase locked loop', 'loop filter design', 'PLL bandwidth', 'phase margin', 'VCO filter', 'PLL component values',),
    ),
    'ber-snr': CalculatorInfo(
        slug='ber-snr',
        title='Bit Error Rate (BER) Calculator',
        category='signal',
        description='Calculate bit error rate (BER) from Eb/N0 for BPSK, QPSK, 8PSK, and 16QAM digital modulations. Essential for digital communications system design.',
        inputs=(
            InputField(key='ebN0dB', label='Eb/N0', unit='dB', default=10.0, min=-5.0, max=30.0, description='Energy per bit to noise density ratio. The fundamental SNR metric for digital communications.'),
            InputField(key='modulation', label='Modulation', unit='', default=1.0, min=1.0, max=4.0, description='Modulation type: 1=BPSK, 2=QPSK, 3=8PSK, 4=16QAM'),
        ),
        outputs=(
            OutputField(key='ber', label='Bit Error Rate', unit='', description='Bit error rate (probability of bit error)'),
            OutputField(key='berLog10', label='BER (log₁₀)', unit='', description='Log base-10 of BER. e.g. −6 means BER = 10⁻⁶'),
            OutputField(key='bitsPerSymbol', label='Bits per Symbol', unit='bits/symbol', description='Number of bits per modulation symbol'),
        ),
        keywords=('bit error rate', 'BER calculator', 'Eb/N0', 'BPSK BER', 'QPSK BER', '16QAM BER', 'digital modulation', 'SNR BER', 'communications performance',),
    ),
    'quantization-noise': CalculatorInfo(
        slug='quantization-noise',
        title='ADC Quantization Noise Calculator',
        category='signal',
        description='Calculate ADC quantization noise, theoretical SQNR, ENOB, dynamic range, and noise spectral density for analog-to-digital converter design.',
        inputs=(
            InputField(key='bits', label='ADC Resolution', unit='bits', default=12.0, min=1.0, max=24.0, description='ADC resolution in bits'),
            InputField(key='vref', label='Reference Voltage', unit='V', default=3.3, min=0.001, max=None, description='ADC full-scale reference voltage'),
            InputField(key='frequency', label='Input Frequency', unit='kHz', default=1.0, min=0.001, max=None, description='Input signal frequency (used for reference only)'),
            InputField(key='sampleRate', label='Sample Rate', unit='kHz', default=100.0, min=0.001, max=None, description='ADC sample rate. Nyquist bandwidth = sample rate / 2.'),
        ),
        outputs=(
            OutputField(key='lsb', label='LSB Size', unit='mV', description='Least significant bit voltage: Vref / 2^N'),
            OutputField(key='sqnr', label='Theoretical SQNR', unit='dB', description='Signal-to-quantization-noise ratio: 6.02N + 1.76 dB'),
            OutputField(key='enob', label='ENOB (theoretical)', unit='bits', description='Effective number of bits (equals N for ideal ADC)'),
            OutputField(key='dynamicRange', label='Dynamic Range', unit='dB', description='Ideal dynamic range: 20·log₁₀(2^N)'),
            OutputField(key='noiseDensity', label='Noise Density', unit='nV/√Hz', description='Quantization noise spectral density referred to ADC input'),
        ),
        keywords=('quantization noise', 'ADC SNR', 'SQNR', 'ENOB', 'dynamic range', 'ADC resolution', 'LSB size', 'noise density',),
    ),
    'fresnel-zone': CalculatorInfo(
        slug='fresnel-zone',
        title='Fresnel Zone Calculator',
        category='rf',
        description='Calculate Fresnel zone radius at the midpoint of an RF line-of-sight link. Determine required clearance above obstructions for reliable microwave and WiFi links.',
        inputs=(
            InputField(key='frequency', label='Frequency', unit='GHz', default=5.8, min=0.001, max=None, description='Link operating frequency in GHz'),
            InputField(key='distance', label='Link Distance', unit='km', default=1.0, min=0.001, max=None, description='Total distance between the two endpoints of the link'),
            InputField(key='n', label='Fresnel Zone Number', unit='', default=1.0, min=1.0, max=5.0, description='Fresnel zone number (1 = first Fresnel zone, most important for link design)'),
        ),
        outputs=(
            OutputField(key='radiusM', label='Zone Radius at Midpoint', unit='m', description='Radius of the nth Fresnel zone at the link midpoint'),
            OutputField(key='clearanceM', label='Recommended Clearance', unit='m', description='Minimum clearance above obstructions (60% of first Fresnel zone) for reliable link'),
            OutputField(key='wavelengthM', label='Wavelength', unit='m', description='Free-space wavelength at the operating frequency'),
        ),
        keywords=('Fresnel zone', 'line of sight', 'RF link clearance', 'microwave link', 'path clearance', 'Fresnel radius', 'LOS link', 'point to point link',),
    ),
    'power-density': CalculatorInfo(
        slug='power-density',
        title='RF Power Density Calculator',
        category='rf',
        description='Calculate RF power density (W/m²), electric field strength (V/m), and magnetic field strength (A/m) from EIRP and distance. Useful for EMF exposure and safety analysis.',
        inputs=(
            InputField(key='eirp', label='EIRP', unit='dBm', default=30.0, min=-30.0, max=80.0, description='Equivalent Isotropically Radiated Power (transmitter power + antenna gain)'),
            InputField(key='distance', label='Distance', unit='m', default=10.0, min=0.01, max=None, description='Distance from the antenna to observation point (far field assumed)'),
            InputField(key='frequency', label='Frequency', unit='GHz', default=2.4, min=0.001, max=None, description='Operating frequency (used for reference, does not affect far-field power density)'),
        ),
        outputs=(
            OutputField(key='powerDensity', label='Power Density', unit='mW/m²', description='RF power density at given distance: S = EIRP / (4π·d²)'),
            OutputField(key='efield', label='Electric Field Strength', unit='V/m', description='Far-field electric field strength: E = √(S × 120π)'),
            OutputField(key='hfield', label='Magnetic Field Strength', unit='mA/m', description='Far-field magnetic field strength: H = E / (120π)'),
            OutputField(key='planeWaveImpedance', label='Plane Wave Impedance', unit='Ω', description='Free-space plane wave impedance η = 120π ≈ 377Ω'),
        ),
        keywords=('power density', 'electric field strength', 'RF exposure', 'EIRP', 'EMF safety', 'SAR', 'far field', 'RF field strength',),
    ),
    'balun-transformer': CalculatorInfo(
        slug='balun-transformer',
        title='Balun & RF Transformer Calculator',
        category='rf',
        description='Calculate balun and RF transformer turns ratio, impedance transformation ratio, and insertion loss for balanced/unbalanced feed line matching.',
        inputs=(
            InputField(key='zSource', label='Source Impedance', unit='Ω', default=50.0, min=0.1, max=None, description='Source (transmitter/feedline) impedance'),
            InputField(key='zLoad', label='Load Impedance', unit='Ω', default=200.0, min=0.1, max=None, description='Load (antenna/device) impedance to transform to'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=100.0, min=0.001, max=None, description='Operating frequency (for reference)'),
            InputField(key='bandwidth', label='Bandwidth', unit='MHz', default=10.0, min=0.001, max=None, description='Operating bandwidth (for reference)'),
        ),
        outputs=(
            OutputField(key='turnsRatio', label='Turns Ratio (N)', unit=':1', description='Transformer turns ratio N = √(ZL/ZS). Wind N turns on secondary for 1 turn on primary (or vice versa).'),
            OutputField(key='impedanceRatio', label='Impedance Ratio', unit=':1', description='Impedance transformation ratio ZL/ZS = N²'),
            OutputField(key='insertionLoss', label='Typical Insertion Loss', unit='dB', description='Typical insertion loss for ferrite core transformer (~0.3 dB). Ideal = 0 dB.'),
            OutputField(key='vswr', label='VSWR (ideal)', unit=':1', description='VSWR = 1:1 for ideal impedance-matched transformer'),
        ),
        keywords=('balun', 'RF transformer', 'impedance transformation', 'turns ratio', 'balanced unbalanced', 'impedance matching', 'transmission line transformer',),
    ),
    'link-margin': CalculatorInfo(
        slug='link-margin',
        title='RF Link Margin Calculator',
        category='rf',
        description='Calculate RF link margin from TX power, antenna gains, free-space path loss, and receiver sensitivity. Determines maximum range and fade margin for wireless links.',
        inputs=(
            InputField(key='txPower', label='TX Power', unit='dBm', default=20.0, min=-30.0, max=60.0, description='Transmitter output power'),
            InputField(key='txGain', label='TX Antenna Gain', unit='dBi', default=3.0, min=-10.0, max=50.0, description='Transmit antenna gain in dBi'),
            InputField(key='rxGain', label='RX Antenna Gain', unit='dBi', default=3.0, min=-10.0, max=50.0, description='Receive antenna gain in dBi'),
            InputField(key='distance', label='Link Distance', unit='km', default=1.0, min=0.001, max=None, description='Distance between transmitter and receiver'),
            InputField(key='frequency', label='Frequency', unit='GHz', default=2.4, min=0.001, max=None, description='Operating frequency in GHz'),
            InputField(key='sensitivity', label='RX Sensitivity', unit='dBm', default=-90.0, min=-150.0, max=0.0, description='Receiver minimum sensitivity from datasheet'),
            InputField(key='cableLoss', label='Cable/Connector Loss', unit='dB', default=1.0, min=0.0, max=None, description='Total cable and connector losses on TX and RX sides combined'),
        ),
        outputs=(
            OutputField(key='fspl', label='Free-Space Path Loss', unit='dB', description='Free-space path loss at specified frequency and distance'),
            OutputField(key='receivedPower', label='Received Power', unit='dBm', description='Received signal power level at receiver input'),
            OutputField(key='linkMargin', label='Link Margin', unit='dB', description='Margin above receiver sensitivity. Positive = link will work. >10 dB recommended.'),
            OutputField(key='maxRange', label='Maximum Range', unit='km', description='Maximum range where link still has positive margin'),
        ),
        keywords=('link margin', 'RF link budget', 'free space path loss', 'fade margin', 'receiver sensitivity', 'wireless range', 'link budget',),
    ),
    'mixer-spur-calculator': CalculatorInfo(
        slug='mixer-spur-calculator',
        title='Mixer Spur Calculator',
        category='rf',
        description='Calculate mixer spurious products (m×fLO ± n×fRF) for superheterodyne receiver design. Identify problematic spurs near the IF passband and optimize LO/IF frequency planning.',
        inputs=(
            InputField(key='rfFreq', label='RF Frequency', unit='MHz', default=915.0, min=None, max=None, description='Input RF signal frequency in MHz'),
            InputField(key='loFreq', label='LO Frequency', unit='MHz', default=1000.0, min=None, max=None, description='Local oscillator frequency in MHz'),
            InputField(key='maxOrder', label='Maximum Spur Order', unit='', default=5.0, min=None, max=None, description='Maximum harmonic order (m+n) to analyze (2-7)'),
        ),
        outputs=(
            OutputField(key='ifLow', label='IF Low (|fLO − fRF|)', unit='MHz', description=''),
            OutputField(key='ifHigh', label='IF High (fLO + fRF)', unit='MHz', description=''),
            OutputField(key='im3Low', label='2×LO − RF', unit='MHz', description=''),
            OutputField(key='im3High', label='2×LO + RF', unit='MHz', description=''),
            OutputField(key='im3RfLow', label='LO − 2×RF', unit='MHz', description=''),
            OutputField(key='im3RfHigh', label='LO + 2×RF', unit='MHz', description=''),
            OutputField(key='totalSpurs', label='Total Spur Products', unit='', description=''),
            OutputField(key='spursNearIf', label='Spurs Near IF (±10%)', unit='', description=''),
        ),
        keywords=('mixer spur', 'spurious products', 'superheterodyne', 'image frequency', 'spur chart', 'IF planning', 'LO harmonics', 'intermodulation', 'receiver design', 'frequency planning',),
    ),
    'schmitt-trigger': CalculatorInfo(
        slug='schmitt-trigger',
        title='Schmitt Trigger Calculator',
        category='general',
        description='Calculate non-inverting Schmitt trigger threshold voltages and hysteresis band for comparator circuits with positive feedback.',
        inputs=(
            InputField(key='vcc', label='Supply Voltage', unit='V', default=5.0, min=0.1, max=36.0, description='Supply voltage for the comparator/op-amp'),
            InputField(key='r1', label='R1 (Lower)', unit='kΩ', default=10.0, min=0.001, max=10000.0, description='Lower resistor to ground in the voltage divider network'),
            InputField(key='r2', label='R2 (Upper)', unit='kΩ', default=10.0, min=0.001, max=10000.0, description='Upper resistor from output to the voltage divider node'),
            InputField(key='r3', label='R3 (Feedback)', unit='kΩ', default=100.0, min=0.001, max=10000.0, description='Feedback resistor from output to non-inverting input'),
        ),
        outputs=(
            OutputField(key='vth_high', label='Upper Threshold', unit='V', description='High threshold voltage — input must exceed this to trigger high-to-low transition'),
            OutputField(key='vth_low', label='Lower Threshold', unit='V', description='Low threshold voltage — input must fall below this to trigger low-to-high transition'),
            OutputField(key='hysteresis', label='Hysteresis', unit='V', description='Total hysteresis window (Vth_high - Vth_low)'),
            OutputField(key='centerVoltage', label='Center Voltage', unit='V', description='Center (reference) voltage of the hysteresis window'),
        ),
        keywords=('schmitt trigger calculator', 'hysteresis comparator', 'threshold voltage', 'positive feedback comparator', 'noise immunity trigger',),
    ),
    'crystal-load-capacitance': CalculatorInfo(
        slug='crystal-load-capacitance',
        title='Crystal Load Capacitance Calculator',
        category='general',
        description='Calculate actual load capacitance seen by a crystal oscillator, estimate frequency error from spec, and find recommended external capacitor values.',
        inputs=(
            InputField(key='cl', label='Crystal Load Capacitance (spec)', unit='pF', default=18.0, min=1.0, max=100.0, description='Crystal specified load capacitance from datasheet'),
            InputField(key='cstray', label='Stray / Parasitic Capacitance', unit='pF', default=3.0, min=0.0, max=50.0, description='PCB stray/parasitic capacitance including IC input capacitance'),
            InputField(key='c1', label='External Cap C1', unit='pF', default=22.0, min=0.1, max=1000.0, description='External capacitor 1 (C1 = C2 is typical for symmetric layout)'),
            InputField(key='c2', label='External Cap C2', unit='pF', default=22.0, min=0.1, max=1000.0, description='External capacitor 2'),
        ),
        outputs=(
            OutputField(key='clActual', label='Actual Load Capacitance', unit='pF', description='Actual load capacitance presented to the crystal: (C1||C2) + Cstray'),
            OutputField(key='clError', label='Load Capacitance Error', unit='pF', description='Difference between actual and specified load capacitance'),
            OutputField(key='freqError', label='Estimated Frequency Error', unit='ppm', description='Approximate frequency error due to load capacitance mismatch'),
            OutputField(key='c_recommended', label='Recommended External Cap (each)', unit='pF', description='Recommended value for each external capacitor (C1 = C2) to hit the specified load capacitance'),
        ),
        keywords=('crystal load capacitance', 'crystal oscillator design', 'frequency accuracy ppm', 'xtal capacitor', 'oscillator stray capacitance',),
    ),
    'opamp-bandwidth': CalculatorInfo(
        slug='opamp-bandwidth',
        title='Op-Amp Closed-Loop Bandwidth Calculator',
        category='general',
        description='Calculate op-amp closed-loop -3dB bandwidth from the gain-bandwidth product (GBW), determine rise time, and verify phase margin.',
        inputs=(
            InputField(key='gbw', label='Gain-Bandwidth Product', unit='MHz', default=1.0, min=0.001, max=10000.0, description='Unity gain bandwidth product from datasheet (GBW or ft)'),
            InputField(key='gain', label='Closed-Loop Gain', unit='V/V', default=10.0, min=1.0, max=100000.0, description='Closed-loop voltage gain (non-inverting: 1 + Rf/Rg)'),
            InputField(key='phase_margin', label='Phase Margin', unit='°', default=45.0, min=1.0, max=90.0, description='Phase margin for stability assessment (typically 45-60°)'),
        ),
        outputs=(
            OutputField(key='bandwidth', label='-3dB Bandwidth', unit='kHz', description='Closed-loop -3dB bandwidth: BW = GBW / A_CL'),
            OutputField(key='riseTime', label='Rise Time (10-90%)', unit='μs', description='Approximate 10-90% rise time: t_r = 0.35 / BW'),
            OutputField(key='slewLimited', label='Slew Rate Limited', unit='', description='Whether output is slew-rate limited (1=yes, 0=no). Requires slew rate input to evaluate.'),
            OutputField(key='gainDb', label='Gain', unit='dB', description='Closed-loop gain in decibels'),
        ),
        keywords=('op amp bandwidth calculator', 'gain bandwidth product', 'closed loop bandwidth', 'opamp rise time', 'unity gain bandwidth',),
    ),
    'lm317-resistors': CalculatorInfo(
        slug='lm317-resistors',
        title='LM317 Resistor Calculator',
        category='general',
        description='Calculate R2 resistor value for LM317/LM338 adjustable voltage regulator output voltage, with actual Vout and resistor power dissipation.',
        inputs=(
            InputField(key='vout', label='Desired Output Voltage', unit='V', default=5.0, min=1.25, max=37.0, description='Desired output voltage (minimum 1.25V = Vref)'),
            InputField(key='r1', label='R1', unit='Ω', default=240.0, min=1.0, max=10000.0, description='R1 from output pin to ADJ pin — typically 240Ω per LM317 datasheet'),
            InputField(key='iadj', label='ADJ Pin Current', unit='μA', default=50.0, min=0.0, max=500.0, description='ADJ pin current — typically 50μA for LM317, 65μA for LM317A'),
        ),
        outputs=(
            OutputField(key='r2', label='Required R2', unit='Ω', description='Calculated R2 value from ADJ pin to ground'),
            OutputField(key='voutActual', label='Actual Output Voltage', unit='V', description='Actual output voltage including ADJ pin current effect'),
            OutputField(key='powerR1', label='Power in R1', unit='mW', description='Power dissipated in R1'),
            OutputField(key='powerR2', label='Power in R2', unit='mW', description='Power dissipated in R2'),
        ),
        keywords=('lm317 resistor calculator', 'lm317 output voltage', 'adjustable voltage regulator', 'lm338 design', 'linear regulator resistors',),
    ),
    'voltage-regulator-dropout': CalculatorInfo(
        slug='voltage-regulator-dropout',
        title='LDO Dropout Voltage Calculator',
        category='general',
        description='Calculate LDO minimum input voltage from dropout specification, determine power dissipation, and estimate efficiency at a given supply voltage.',
        inputs=(
            InputField(key='vout', label='Output Voltage', unit='V', default=3.3, min=0.1, max=36.0, description='Regulated output voltage'),
            InputField(key='iload', label='Load Current', unit='mA', default=500.0, min=0.1, max=10000.0, description='Maximum load current drawn from the regulator'),
            InputField(key='vdropout', label='Dropout Voltage', unit='mV', default=300.0, min=1.0, max=5000.0, description='Typical LDO dropout voltage from datasheet at rated current'),
            InputField(key='rds_on', label='MOSFET Rds(on)', unit='mΩ', default=0.0, min=0.0, max=10000.0, description='MOSFET Rds(on) for LDO pass device — enter 0 if not applicable or unknown'),
            InputField(key='vin', label='Actual Supply Voltage', unit='V', default=5.0, min=0.1, max=60.0, description='Actual input supply voltage for power and efficiency calculations'),
        ),
        outputs=(
            OutputField(key='vinMin', label='Minimum Input Voltage', unit='V', description='Minimum input voltage to maintain regulation: Vout + Vdropout + Iload*Rds'),
            OutputField(key='vinRec', label='Recommended Input Voltage', unit='V', description='Recommended input voltage with 10% margin above minimum'),
            OutputField(key='powerDiss', label='Power Dissipation', unit='mW', description='Power dissipated in the regulator at the given Vin'),
            OutputField(key='efficiency', label='Efficiency', unit='%', description='Regulator efficiency: Vout/Vin × 100%'),
        ),
        keywords=('ldo dropout voltage', 'minimum input voltage ldo', 'linear regulator efficiency', 'voltage regulator power dissipation', 'ldo headroom',),
    ),
    'transformer-turns-ratio': CalculatorInfo(
        slug='transformer-turns-ratio',
        title='Transformer Turns Ratio Calculator',
        category='power',
        description='Calculate transformer turns ratio, secondary current, apparent power, and real power delivered. Accounts for transformer efficiency.',
        inputs=(
            InputField(key='vPrimary', label='Primary Voltage', unit='V', default=120.0, min=0.1, max=100000.0, description='Primary (input) winding voltage'),
            InputField(key='vSecondary', label='Secondary Voltage', unit='V', default=12.0, min=0.1, max=100000.0, description='Secondary (output) winding voltage'),
            InputField(key='iPrimary', label='Primary Current', unit='A', default=0.1, min=0.0001, max=10000.0, description='Primary winding current'),
            InputField(key='efficiency', label='Transformer Efficiency', unit='%', default=95.0, min=1.0, max=100.0, description='Transformer efficiency (typical: 90-99% for power transformers)'),
        ),
        outputs=(
            OutputField(key='turnsRatio', label='Turns Ratio (Np/Ns)', unit='', description='Transformer turns ratio Np/Ns = Vp/Vs'),
            OutputField(key='iSecondary', label='Secondary Current', unit='A', description='Secondary winding current accounting for efficiency'),
            OutputField(key='apparentPower', label='Apparent Power', unit='VA', description='Apparent power on primary side: Vp × Ip'),
            OutputField(key='realPower', label='Real Power Delivered', unit='W', description='Real power delivered to secondary: VA × efficiency'),
            OutputField(key='couplingFactor', label='Coupling Factor', unit='', description='Magnetic coupling factor (approximated from efficiency)'),
        ),
        keywords=('transformer turns ratio', 'transformer design calculator', 'step down transformer', 'secondary current transformer', 'transformer efficiency',),
    ),
    'flyback-converter': CalculatorInfo(
        slug='flyback-converter',
        title='Flyback Converter Calculator',
        category='power',
        description='Calculate flyback converter turns ratio, peak primary and secondary currents, and power levels for isolated DC-DC converter design.',
        inputs=(
            InputField(key='vin', label='Input Voltage', unit='V', default=48.0, min=1.0, max=1000.0, description='DC input voltage'),
            InputField(key='vout', label='Output Voltage', unit='V', default=12.0, min=0.5, max=500.0, description='Desired output voltage'),
            InputField(key='iout', label='Output Current', unit='A', default=1.0, min=0.01, max=100.0, description='Maximum output current'),
            InputField(key='efficiency', label='Efficiency', unit='%', default=85.0, min=10.0, max=99.0, description='Expected converter efficiency (typical: 80-90%)'),
            InputField(key='fsw', label='Switching Frequency', unit='kHz', default=100.0, min=10.0, max=5000.0, description='Switching frequency'),
            InputField(key='dutyCycle', label='Duty Cycle', unit='%', default=40.0, min=5.0, max=90.0, description='Primary switch duty cycle (typical: 30-50% for flyback)'),
        ),
        outputs=(
            OutputField(key='turnsRatio', label='Turns Ratio (Np/Ns)', unit='', description='Primary-to-secondary turns ratio'),
            OutputField(key='iinAvg', label='Average Input Current', unit='A', description='Average DC input current'),
            OutputField(key='ipPeak', label='Peak Primary Current', unit='A', description='Peak current in primary MOSFET switch'),
            OutputField(key='isecPeak', label='Peak Secondary Current', unit='A', description='Peak current in secondary diode/rectifier'),
            OutputField(key='outputPower', label='Output Power', unit='W', description='Total output power: Vout × Iout'),
        ),
        keywords=('flyback converter design', 'flyback turns ratio', 'isolated dc dc converter', 'flyback peak current', 'switching power supply',),
    ),
    'supercapacitor-backup': CalculatorInfo(
        slug='supercapacitor-backup',
        title='Supercapacitor Backup Time Calculator',
        category='power',
        description='Calculate supercapacitor backup time, stored energy, and charge time for power backup applications using ultracapacitors.',
        inputs=(
            InputField(key='capacitance', label='Capacitance', unit='F', default=10.0, min=0.001, max=10000.0, description='Supercapacitor capacitance in Farads'),
            InputField(key='vMax', label='Maximum Voltage', unit='V', default=5.5, min=0.1, max=100.0, description='Maximum (fully charged) voltage — must not exceed rated voltage'),
            InputField(key='vMin', label='Minimum Operating Voltage', unit='V', default=3.0, min=0.1, max=99.0, description='Minimum voltage at which load circuit still operates'),
            InputField(key='iLoad', label='Load Current', unit='mA', default=100.0, min=0.01, max=100000.0, description='Load current drawn during backup operation'),
        ),
        outputs=(
            OutputField(key='energy', label='Usable Energy', unit='J', description='Energy available between Vmax and Vmin: E = 0.5×C×(Vmax²−Vmin²)'),
            OutputField(key='backupTime', label='Backup Time', unit='s', description='Estimated backup time at constant load current'),
            OutputField(key='backupTimeMin', label='Backup Time', unit='min', description='Estimated backup time in minutes'),
            OutputField(key='chargeTime', label='Approximate Charge Time', unit='s', description='Approximate charge time assuming 5× load current charge rate'),
            OutputField(key='selfDischarge', label='Daily Self-Discharge', unit='%', description='Estimated self-discharge per day (assumes ~1μA/F leakage current)'),
        ),
        keywords=('supercapacitor backup time', 'ultracapacitor sizing', 'supercap energy storage', 'edlc backup calculator', 'capacitor backup power',),
    ),
    'battery-internal-resistance': CalculatorInfo(
        slug='battery-internal-resistance',
        title='Battery Internal Resistance Calculator',
        category='power',
        description='Calculate battery internal resistance from open-circuit and loaded voltage measurements, determine power loss and maximum short-circuit current.',
        inputs=(
            InputField(key='vocv', label='Open Circuit Voltage', unit='V', default=12.6, min=0.1, max=1000.0, description='Battery open circuit voltage with no load applied'),
            InputField(key='vLoad', label='Loaded Voltage', unit='V', default=11.8, min=0.1, max=1000.0, description='Battery terminal voltage under load current'),
            InputField(key='iLoad', label='Load Current', unit='A', default=4.0, min=0.001, max=10000.0, description='Load current applied during the voltage measurement'),
            InputField(key='temperature', label='Temperature', unit='°C', default=25.0, min=-40.0, max=85.0, description='Battery temperature (affects internal resistance — informational)'),
        ),
        outputs=(
            OutputField(key='rinternal', label='Internal Resistance', unit='mΩ', description='Battery internal resistance: R = (Vocv − Vload) / Iload'),
            OutputField(key='powerLoss', label='Internal Power Loss', unit='W', description='Power dissipated inside the battery: P = Rint × Iload²'),
            OutputField(key='efficiency', label='Efficiency', unit='%', description='Energy delivery efficiency: Vload/Vocv × 100%'),
            OutputField(key='maxCurrentShort', label='Theoretical Short-Circuit Current', unit='A', description='Theoretical maximum short-circuit current: Isc = Vocv / Rint'),
        ),
        keywords=('battery internal resistance', 'battery impedance', 'voltage sag under load', 'battery health calculator', 'discharge resistance',),
    ),
    'i2s-timing': CalculatorInfo(
        slug='i2s-timing',
        title='I2S Audio Interface Timing Calculator',
        category='protocol',
        description='Calculate I2S bit clock (BCLK), word clock (LRCLK/WCLK), and data rate for audio interfaces at any sample rate, bit depth, and channel count.',
        inputs=(
            InputField(key='sampleRate', label='Sample Rate', unit='kHz', default=44.1, min=0.1, max=768.0, description='Audio sample rate (e.g., 44.1, 48, 96, 192 kHz)'),
            InputField(key='bitDepth', label='Bit Depth', unit='bits', default=24.0, min=8.0, max=64.0, description='Bits per sample (common: 16, 24, 32 bits)'),
            InputField(key='channels', label='Channels', unit='', default=2.0, min=1.0, max=32.0, description='Number of audio channels (1=mono, 2=stereo)'),
        ),
        outputs=(
            OutputField(key='bclk', label='Bit Clock (BCLK)', unit='MHz', description='Bit clock frequency: BCLK = Fs × bit_depth × channels'),
            OutputField(key='wclk', label='Word Clock (LRCLK)', unit='kHz', description='Word/frame clock frequency = sample rate'),
            OutputField(key='bclkPeriod', label='BCLK Period', unit='ns', description='Period of one BCLK cycle'),
            OutputField(key='dataRate', label='Data Rate', unit='Mbps', description='Raw audio data rate on the I2S bus'),
        ),
        keywords=('i2s timing calculator', 'i2s bclk frequency', 'i2s word clock', 'audio interface bit clock', 'i2s data rate',),
    ),
    'lin-bus-timing': CalculatorInfo(
        slug='lin-bus-timing',
        title='LIN Bus Timing Calculator',
        category='protocol',
        description='Calculate LIN bus bit time, break field length, frame time, and maximum frame rate for automotive LIN network design.',
        inputs=(
            InputField(key='baudRate', label='Baud Rate', unit='kbps', default=19.2, min=0.1, max=20.0, description='LIN baud rate (typical: 2.4, 9.6, 10.4, 19.2 kbps)'),
            InputField(key='dataBytes', label='Data Bytes', unit='bytes', default=8.0, min=1.0, max=8.0, description='Number of data bytes in the response field (1-8 per LIN spec)'),
        ),
        outputs=(
            OutputField(key='bitTime', label='Bit Time', unit='μs', description='Duration of one bit: T_bit = 1 / baud_rate'),
            OutputField(key='breakLength', label='Break Field Length', unit='μs', description='Minimum break field duration (13 bit times)'),
            OutputField(key='frameTime', label='Frame Time', unit='μs', description='Total LIN frame duration including header and response'),
            OutputField(key='framesPerSec', label='Max Frame Rate', unit='frames/s', description='Maximum frames per second at this baud rate and data length'),
            OutputField(key='busLoad', label='Bus Load', unit='%', description='Approximate bus utilization percentage'),
        ),
        keywords=('lin bus timing', 'lin frame time', 'lin baud rate calculator', 'automotive lin bus', 'lin bus frame structure',),
    ),
    'modbus-frame-timing': CalculatorInfo(
        slug='modbus-frame-timing',
        title='Modbus RTU Frame Timing Calculator',
        category='protocol',
        description='Calculate Modbus RTU character time, 3.5-character inter-frame gap, total frame duration, and maximum frame rate.',
        inputs=(
            InputField(key='baudRate', label='Baud Rate', unit='bps', default=9600.0, min=300.0, max=115200.0, description='Modbus RTU baud rate'),
            InputField(key='dataBytes', label='Data Bytes', unit='bytes', default=8.0, min=1.0, max=252.0, description='Number of data bytes in PDU including function code'),
            InputField(key='parityBits', label='Parity Bits', unit='bits', default=1.0, min=0.0, max=1.0, description='Parity bits: 0=None, 1=Even or Odd'),
            InputField(key='stopBits', label='Stop Bits', unit='bits', default=1.0, min=1.0, max=2.0, description='Stop bits (1 or 2 — use 2 stop bits when parity=none)'),
        ),
        outputs=(
            OutputField(key='charTime', label='Character Time', unit='ms', description='Time to transmit one character: (1+8+parity+stop) / baud_rate'),
            OutputField(key='t35', label='Inter-Frame Gap (3.5T)', unit='ms', description='Modbus RTU inter-frame silence: 3.5 × character time'),
            OutputField(key='frameTime', label='Frame Time', unit='ms', description='Total frame transmission time (address + function + data + CRC)'),
            OutputField(key='maxFrameRate', label='Max Frame Rate', unit='frames/s', description='Maximum frames per second including inter-frame gap'),
        ),
        keywords=('modbus rtu timing', 'modbus frame time', 'modbus inter frame gap', 't35 modbus', 'modbus baud rate calculator',),
    ),
    'ethernet-cable': CalculatorInfo(
        slug='ethernet-cable',
        title='Ethernet Cable Length & Attenuation Calculator',
        category='protocol',
        description='Calculate Ethernet cable attenuation, maximum cable length, and pass/fail for Cat5e, Cat6, Cat6a, and Cat8 at 100Mbps, 1Gbps, and 10Gbps.',
        inputs=(
            InputField(key='cableType', label='Cable Category', unit='', default=2.0, min=1.0, max=4.0, description='1=Cat5e, 2=Cat6, 3=Cat6a, 4=Cat8'),
            InputField(key='length', label='Cable Length', unit='m', default=50.0, min=1.0, max=500.0, description='Total cable run length in meters'),
            InputField(key='speed', label='Network Speed', unit='', default=2.0, min=1.0, max=3.0, description='1=100Mbps (100BASE-TX), 2=1Gbps (1000BASE-T), 3=10Gbps (10GBASE-T)'),
        ),
        outputs=(
            OutputField(key='attenuation', label='Cable Attenuation', unit='dB', description='Estimated signal attenuation at given length'),
            OutputField(key='maxLength', label='Maximum Length', unit='m', description='IEEE/TIA maximum cable length for this category and speed'),
            OutputField(key='headroom', label='Length Headroom', unit='m', description='Remaining length margin before limit (negative = over limit)'),
            OutputField(key='passOrFail', label='Pass / Fail', unit='', description='1 = within spec (PASS), 0 = exceeds maximum length (FAIL)'),
        ),
        keywords=('ethernet cable length', 'cat6 maximum length', 'ethernet attenuation', 'cat5e 10 gigabit', 'cable run calculator',),
    ),
    'power-plane-impedance': CalculatorInfo(
        slug='power-plane-impedance',
        title='PCB Power Plane Impedance Calculator',
        category='pcb',
        description='Calculate PCB power plane spreading impedance, plane capacitance, inductance, and self-resonant frequency for PDN (power delivery network) design.',
        inputs=(
            InputField(key='length', label='Plane Length', unit='mm', default=100.0, min=1.0, max=1000.0, description='Length of the power plane area'),
            InputField(key='width', label='Plane Width', unit='mm', default=80.0, min=1.0, max=1000.0, description='Width of the power plane area'),
            InputField(key='dielectric', label='Dielectric Thickness', unit='mm', default=0.1, min=0.01, max=5.0, description='Distance between power and ground planes (core/prepreg thickness)'),
            InputField(key='er', label='Dielectric Constant', unit='', default=4.4, min=1.0, max=20.0, description='PCB dielectric constant (FR4 = 4.3–4.8 at 1 MHz)'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=100.0, min=0.001, max=10000.0, description='Frequency at which to evaluate plane impedance'),
        ),
        outputs=(
            OutputField(key='capacitance', label='Plane Capacitance', unit='nF', description='Distributed capacitance of the power-ground plane pair'),
            OutputField(key='impedance', label='Impedance at Frequency', unit='mΩ', description='Inductive reactance of the plane at the given frequency'),
            OutputField(key='resonantFrequency', label='Self-Resonant Frequency', unit='MHz', description='Frequency at which plane capacitance resonates with plane inductance'),
            OutputField(key='inductance', label='Plane Inductance', unit='nH', description='Approximate spreading inductance of the plane'),
        ),
        keywords=('pcb power plane impedance', 'pdn impedance', 'power plane capacitance', 'pcb plane resonance', 'power distribution network',),
    ),
    'via-stub-resonance': CalculatorInfo(
        slug='via-stub-resonance',
        title='PCB Via Stub Resonance Calculator',
        category='pcb',
        description='Calculate PCB via stub length, stub resonant frequency that causes signal notch, and frequency improvement from back-drilling.',
        inputs=(
            InputField(key='pcbThickness', label='PCB Thickness', unit='mm', default=1.6, min=0.1, max=10.0, description='Total PCB board thickness'),
            InputField(key='layer', label='Signal Exit Layer', unit='', default=4.0, min=1.0, max=32.0, description='Layer number where the signal exits the via (counting from top, layer 1)'),
            InputField(key='totalLayers', label='Total PCB Layers', unit='', default=8.0, min=2.0, max=40.0, description='Total number of PCB copper layers'),
            InputField(key='er', label='Dielectric Constant', unit='', default=4.3, min=1.0, max=20.0, description='PCB dielectric constant (FR4 = 4.3–4.8)'),
        ),
        outputs=(
            OutputField(key='stubLength', label='Via Stub Length', unit='mm', description='Length of the unused via stub below the signal exit layer'),
            OutputField(key='resonantFreq', label='Stub Resonant Frequency', unit='GHz', description='Quarter-wave resonant frequency of the via stub — causes signal notch'),
            OutputField(key='notchDepth', label='Notch Depth (approx)', unit='dB', description='Approximate signal attenuation notch depth at resonance (~−20 dB)'),
            OutputField(key='backdrillBenefit', label='Post-Backdrill Frequency', unit='GHz', description='Approximate resonance frequency improvement after back-drilling the stub'),
        ),
        keywords=('via stub resonance', 'pcb via backdrill', 'via stub notch frequency', 'high speed pcb via', 'stub resonance signal integrity',),
    ),
    'solder-paste-volume': CalculatorInfo(
        slug='solder-paste-volume',
        title='Solder Paste Volume Calculator',
        category='pcb',
        description='Calculate SMD solder paste volume, stencil aperture area, and IPC-7525A area ratio for stencil printing and reflow soldering process.',
        inputs=(
            InputField(key='padLength', label='Pad Length', unit='mm', default=1.5, min=0.05, max=50.0, description='PCB pad length (in the direction of component lead)'),
            InputField(key='padWidth', label='Pad Width', unit='mm', default=0.8, min=0.05, max=50.0, description='PCB pad width'),
            InputField(key='stencilThickness', label='Stencil Thickness', unit='mm', default=0.12, min=0.05, max=1.0, description='Stencil foil thickness (typical: 0.10, 0.12, 0.15 mm)'),
            InputField(key='apertureReduction', label='Aperture Reduction', unit='%', default=10.0, min=0.0, max=50.0, description='Aperture reduction from pad size per IPC-7525A (typically 10-20%)'),
        ),
        outputs=(
            OutputField(key='apertureArea', label='Aperture Area', unit='mm²', description='Stencil aperture area after reduction'),
            OutputField(key='pasteVolume', label='Paste Volume', unit='mm³', description='Volume of solder paste deposited per pad'),
            OutputField(key='pasteVolumeMl', label='Paste Volume', unit='μL', description='Volume in microliters (1 mm³ = 1 μL)'),
            OutputField(key='areaRatio', label='Area Ratio', unit='', description='IPC-7525A area ratio — must be > 0.66 for acceptable paste release'),
        ),
        keywords=('solder paste volume', 'stencil aperture design', 'solder paste calculator', 'ipc-7525 area ratio', 'smt stencil thickness',),
    ),
    'emi-filter-lc': CalculatorInfo(
        slug='emi-filter-lc',
        title='LC EMI Filter Design Calculator',
        category='emc',
        description='Design an LC low-pass EMI filter for conducted emissions suppression — calculate inductance, capacitance, filter order, and attenuation at the stop band.',
        inputs=(
            InputField(key='fc', label='Cutoff Frequency', unit='kHz', default=150.0, min=0.1, max=100000.0, description='Filter -3dB cutoff frequency (150 kHz = CISPR conducted emissions limit start)'),
            InputField(key='attenuationNeeded', label='Required Attenuation', unit='dB', default=40.0, min=6.0, max=120.0, description='Required attenuation at the cutoff frequency to meet EMC limits'),
            InputField(key='zSource', label='Source Impedance', unit='Ω', default=50.0, min=0.1, max=10000.0, description='Source impedance (50Ω for LISN test environments)'),
            InputField(key='zLoad', label='Load Impedance', unit='Ω', default=50.0, min=0.1, max=10000.0, description='Load impedance'),
        ),
        outputs=(
            OutputField(key='inductance', label='Inductance', unit='μH', description='Filter inductor value per stage'),
            OutputField(key='capacitance', label='Capacitance', unit='μF', description='Filter capacitor value per stage'),
            OutputField(key='filterOrder', label='Filter Order', unit='', description='Number of LC stages required to achieve the specified attenuation'),
            OutputField(key='actualAttenuation', label='Attenuation at 10× fc', unit='dB', description='Actual attenuation at 10× the cutoff frequency (one decade into stop band)'),
            OutputField(key='impedanceMatching', label='Matching Impedance', unit='Ω', description='Geometric mean impedance for filter matching'),
        ),
        keywords=('emi filter design', 'lc filter emc', 'conducted emissions filter', 'cispr 22 filter', 'emc low pass filter calculator',),
    ),
    'esd-tvs-diode': CalculatorInfo(
        slug='esd-tvs-diode',
        title='ESD TVS Diode Selection Calculator',
        category='emc',
        description='Calculate TVS diode clamping voltage, breakdown voltage, peak pulse current, and power rating for ESD protection circuit design.',
        inputs=(
            InputField(key='vwm', label='Working Voltage', unit='V', default=5.0, min=0.1, max=400.0, description='Maximum continuous working voltage on the protected line'),
            InputField(key='esd_level', label='ESD Level', unit='', default=2.0, min=1.0, max=4.0, description='1=2kV HBM, 2=4kV HBM, 3=8kV HBM, 4=15kV IEC 61000-4-2'),
            InputField(key='clampMultiplier', label='Clamp Voltage Multiplier', unit='', default=1.3, min=1.0, max=3.0, description='Ratio of clamp voltage to breakdown voltage — typical datasheet ratio 1.2-1.5'),
        ),
        outputs=(
            OutputField(key='vclamp', label='Clamp Voltage', unit='V', description='Maximum TVS clamp voltage — must be below protected IC maximum rating'),
            OutputField(key='vBR', label='Breakdown Voltage', unit='V', description='TVS breakdown voltage — select nearest standard value above this'),
            OutputField(key='ipp', label='Peak Pulse Current', unit='A', description='Peak pulse current from ESD event (HBM: Vpeak / 1500Ω)'),
            OutputField(key='ppwr', label='Peak Pulse Power', unit='W', description='Peak pulse power the TVS must handle: Vc × Ipp'),
            OutputField(key='energy', label='ESD Energy', unit='mJ', description='ESD event energy: E = 0.5 × C × V² (HBM: 100pF, IEC: 150pF)'),
        ),
        keywords=('tvs diode selection', 'esd protection calculator', 'transient voltage suppressor', 'esd tvs diode rating', 'iec 61000-4-2 esd',),
    ),
    'common-mode-choke': CalculatorInfo(
        slug='common-mode-choke',
        title='Common Mode Choke Impedance',
        category='emc',
        description='Calculate common mode choke impedance, insertion loss, and Q factor at a given frequency for EMC filter design.',
        inputs=(
            InputField(key='inductance', label='Inductance', unit='μH', default=1000.0, min=0.1, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='Hz', default=150000.0, min=1.0, max=None, description='CISPR 25 conducted emissions start at 150 kHz'),
            InputField(key='dcr', label='DC Resistance (DCR)', unit='Ω', default=0.5, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='impedance', label='Impedance |Z|', unit='Ω', description=''),
            OutputField(key='attenuation', label='Insertion Loss', unit='dB', description=''),
            OutputField(key='qualityFactor', label='Q Factor', unit='', description=''),
        ),
        keywords=('common mode choke', 'CMC impedance', 'common mode filter', 'EMC choke', 'differential mode', 'choke impedance',),
    ),
    'decoupling-capacitor-emc': CalculatorInfo(
        slug='decoupling-capacitor-emc',
        title='Decoupling Capacitor EMC Selection',
        category='emc',
        description='Calculate decoupling capacitor impedance at frequency and self-resonant frequency for EMC power supply decoupling.',
        inputs=(
            InputField(key='capacitance', label='Capacitance', unit='nF', default=100.0, min=0.001, max=None, description=''),
            InputField(key='esr', label='ESR', unit='Ω', default=0.05, min=0.001, max=None, description='Equivalent series resistance from datasheet'),
            InputField(key='frequency', label='Target Frequency', unit='kHz', default=100.0, min=0.001, max=None, description=''),
            InputField(key='packageInductance', label='Package Inductance', unit='nH', default=1.0, min=0.1, max=20.0, description=''),
        ),
        outputs=(
            OutputField(key='xc', label='Capacitive Reactance', unit='Ω', description=''),
            OutputField(key='impedance', label='Total Impedance |Z|', unit='Ω', description=''),
            OutputField(key='srf', label='Self-Resonant Freq.', unit='MHz', description=''),
        ),
        keywords=('decoupling capacitor EMC', 'bypass capacitor', 'capacitor self resonant frequency', 'ESR capacitor', 'power supply decoupling EMC', 'SRF capacitor',),
    ),
    'esd-clamp-selection': CalculatorInfo(
        slug='esd-clamp-selection',
        title='ESD Clamp Diode Selection',
        category='emc',
        description='Calculate ESD clamp diode peak current, power dissipation, and clamping ratio to verify protection for IEC 61000-4-2 compliance.',
        inputs=(
            InputField(key='esdVoltage', label='ESD Strike Voltage', unit='V', default=4000.0, min=100.0, max=None, description='IEC 61000-4-2 Level 4: ±8 kV contact'),
            InputField(key='clampVoltage', label='Clamp Voltage (V_cl)', unit='V', default=15.0, min=1.0, max=None, description='TVS clamping voltage at peak current from datasheet'),
            InputField(key='lineImpedance', label='Line Impedance', unit='Ω', default=330.0, min=0.1, max=None, description='Series resistance in ESD discharge path'),
        ),
        outputs=(
            OutputField(key='peakCurrent', label='Peak Clamp Current', unit='A', description=''),
            OutputField(key='clampPower', label='Peak Power Dissipation', unit='W', description=''),
            OutputField(key='voltageMargin', label='Voltage Margin', unit='V', description=''),
            OutputField(key='clampingRatio', label='Clamping Ratio', unit='', description=''),
        ),
        keywords=('ESD clamp', 'TVS diode ESD', 'ESD protection', 'IEC 61000-4-2', 'ESD clamp selection', 'surge protection',),
    ),
    'radiated-emission-estimate': CalculatorInfo(
        slug='radiated-emission-estimate',
        title='Radiated Emission Estimate',
        category='emc',
        description='Estimate far-field radiated emissions from a PCB current loop using the small-loop antenna model. Compare against CISPR 22/FCC Class B limits.',
        inputs=(
            InputField(key='current', label='Loop Current (peak)', unit='mA', default=10.0, min=0.001, max=None, description=''),
            InputField(key='loopArea', label='Loop Area', unit='cm²', default=1.0, min=0.001, max=None, description='Area enclosed by the current loop on PCB'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=100.0, min=0.01, max=None, description=''),
            InputField(key='distance', label='Measurement Distance', unit='m', default=3.0, min=0.1, max=None, description='CISPR 22 standard: 3 m or 10 m'),
        ),
        outputs=(
            OutputField(key='eFieldDbuvM', label='E-Field', unit='dBμV/m', description=''),
            OutputField(key='margin', label='Margin vs CISPR 22 Class B', unit='dB', description=''),
        ),
        keywords=('radiated emissions', 'EMC radiated', 'CISPR 22', 'FCC radiated emissions', 'PCB emissions estimate', 'loop antenna emissions',),
    ),
    'ground-plane-impedance': CalculatorInfo(
        slug='ground-plane-impedance',
        title='Ground Plane Impedance vs Frequency',
        category='emc',
        description='Calculate PCB ground plane AC impedance, skin depth, and inductive reactance at high frequencies for EMC analysis.',
        inputs=(
            InputField(key='length', label='Plane Length', unit='mm', default=100.0, min=1.0, max=None, description=''),
            InputField(key='width', label='Plane Width', unit='mm', default=50.0, min=0.1, max=None, description=''),
            InputField(key='thickness', label='Copper Thickness', unit='μm', default=35.0, min=1.0, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='MHz', default=10.0, min=0.001, max=None, description=''),
            InputField(key='conductivity', label='Conductivity', unit='MS/m', default=58.0, min=0.1, max=None, description='Copper: 58 MS/m, Aluminium: 37 MS/m'),
        ),
        outputs=(
            OutputField(key='dcResistance', label='DC Resistance', unit='mΩ', description=''),
            OutputField(key='skinDepth', label='Skin Depth', unit='μm', description=''),
            OutputField(key='acResistance', label='AC Resistance', unit='mΩ', description=''),
            OutputField(key='inductance', label='Plane Inductance', unit='nH', description=''),
            OutputField(key='totalImpedance', label='Total Impedance |Z|', unit='mΩ', description=''),
        ),
        keywords=('ground plane impedance', 'ground plane EMC', 'skin depth PCB', 'ground inductance', 'AC ground resistance', 'PCB ground return',),
    ),
    'pcb-crosstalk-emc': CalculatorInfo(
        slug='pcb-crosstalk-emc',
        title='PCB Trace Crosstalk (EMC)',
        category='emc',
        description='Estimate PCB trace crosstalk (capacitive and inductive coupling) for EMC pre-compliance analysis.',
        inputs=(
            InputField(key='aggressorVoltage', label='Aggressor Voltage', unit='V', default=3.3, min=0.001, max=None, description=''),
            InputField(key='mutualCapacitance', label='Mutual Capacitance', unit='pF', default=20.0, min=0.001, max=None, description='Total mutual capacitance between traces (pF)'),
            InputField(key='mutualInductance', label='Mutual Inductance', unit='nH', default=10.0, min=0.001, max=None, description='Total mutual inductance between traces (nH)'),
            InputField(key='frequency', label='Frequency', unit='MHz', default=100.0, min=0.001, max=None, description=''),
            InputField(key='lineImpedance', label='Victim Line Impedance', unit='Ω', default=50.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='capacitiveCoupling', label='Capacitive Coupling', unit='mV', description=''),
            OutputField(key='inductiveCoupling', label='Inductive Coupling', unit='mV', description=''),
            OutputField(key='totalCrosstalk', label='Total Crosstalk', unit='mV', description=''),
            OutputField(key='crosstalkDb', label='Crosstalk Coupling', unit='dB', description=''),
        ),
        keywords=('PCB crosstalk EMC', 'trace coupling', 'capacitive coupling PCB', 'inductive coupling PCB', 'EMC crosstalk', 'PCB EMC',),
    ),
    'power-supply-ripple-filter': CalculatorInfo(
        slug='power-supply-ripple-filter',
        title='Power Supply Ripple Filter',
        category='emc',
        description='Calculate LC filter attenuation and output ripple voltage for power supply EMC filtering. Find the resonant frequency and ripple rejection.',
        inputs=(
            InputField(key='inputRipple', label='Input Ripple Voltage', unit='mV', default=100.0, min=0.001, max=None, description=''),
            InputField(key='frequency', label='Ripple Frequency', unit='kHz', default=100.0, min=0.001, max=None, description=''),
            InputField(key='inductance', label='Inductor Value', unit='μH', default=10.0, min=0.001, max=None, description=''),
            InputField(key='capacitance', label='Capacitor Value', unit='μF', default=10.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='resonantFreq', label='Filter Resonant Frequency', unit='kHz', description=''),
            OutputField(key='attenuation', label='Attenuation', unit='dB', description=''),
            OutputField(key='outputRipple', label='Output Ripple', unit='mV', description=''),
        ),
        keywords=('power supply ripple filter', 'LC filter ripple', 'ripple rejection', 'power supply EMC', 'LC EMI filter', 'ripple voltage filter',),
    ),
    'cable-shield-effectiveness': CalculatorInfo(
        slug='cable-shield-effectiveness',
        title='Cable Shield Effectiveness',
        category='emc',
        description='Calculate coaxial cable or shielded cable shield effectiveness (shielding factor) vs frequency using the transfer impedance model.',
        inputs=(
            InputField(key='shieldResistance', label='Shield DC Resistance', unit='mΩ/m', default=10.0, min=0.001, max=None, description='Per metre, from cable datasheet'),
            InputField(key='cableLength', label='Cable Length', unit='m', default=2.0, min=0.01, max=None, description=''),
            InputField(key='frequency', label='Frequency', unit='MHz', default=10.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='shieldingEffectDb', label='Shielding Effectiveness', unit='dB', description=''),
            OutputField(key='transferImpedance', label='Transfer Impedance', unit='mΩ', description=''),
        ),
        keywords=('cable shield', 'shielding effectiveness cable', 'transfer impedance', 'coaxial shield', 'EMC cable shielding', 'cable shield dB',),
    ),
    'chassis-resonance': CalculatorInfo(
        slug='chassis-resonance',
        title='Chassis Resonant Frequency',
        category='emc',
        description='Calculate the lowest resonant frequency of a metallic enclosure (cavity resonator) to identify potential EMC problems.',
        inputs=(
            InputField(key='length', label='Length', unit='cm', default=30.0, min=0.1, max=None, description=''),
            InputField(key='width', label='Width', unit='cm', default=20.0, min=0.1, max=None, description=''),
            InputField(key='height', label='Height', unit='cm', default=10.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='fLowest', label='Lowest Resonant Frequency', unit='MHz', description=''),
            OutputField(key='f101MHz', label='TE₁₀₁ Mode', unit='MHz', description=''),
            OutputField(key='f110MHz', label='TE₁₁₀ Mode', unit='MHz', description=''),
            OutputField(key='wavelengthAtResonance', label='Wavelength at f_min', unit='cm', description=''),
        ),
        keywords=('chassis resonance', 'enclosure resonance', 'cavity resonator', 'EMC chassis', 'metal box resonance', 'shielding resonance',),
    ),
    'emi-margin-budget': CalculatorInfo(
        slug='emi-margin-budget',
        title='EMI Margin Budget',
        category='emc',
        description='Calculate EMI compliance margin accounting for measurement uncertainty and safety margin to predict pre-compliance test pass/fail.',
        inputs=(
            InputField(key='measuredLevel', label='Measured Emission Level', unit='dBμV/m', default=30.0, min=-100.0, max=None, description=''),
            InputField(key='limitLevel', label='Regulatory Limit', unit='dBμV/m', default=40.0, min=-100.0, max=None, description='CISPR 22 Class B radiated: 40 dBμV/m (30–230 MHz) at 3m'),
            InputField(key='measurementUncertainty', label='Measurement Uncertainty', unit='dB', default=6.0, min=0.0, max=None, description='Typically 6 dB for pre-compliance setups'),
            InputField(key='safetyMargin', label='Design Safety Margin', unit='dB', default=6.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='rawMargin', label='Raw Margin', unit='dB', description=''),
            OutputField(key='adjustedMargin', label='Adjusted Margin', unit='dB', description=''),
            OutputField(key='requiredReduction', label='Reduction Required', unit='dB', description=''),
        ),
        keywords=('EMI margin', 'EMC compliance margin', 'pre-compliance testing', 'EMI budget', 'CISPR margin', 'EMC safety margin',),
    ),
    'conducted-emissions-filter': CalculatorInfo(
        slug='conducted-emissions-filter',
        title='Conducted Emissions LC Filter',
        category='emc',
        description='Design an LC filter to meet CISPR 22/FCC conducted emissions limits by calculating required L and C values for a target attenuation.',
        inputs=(
            InputField(key='emissionLevel', label='Measured Emission', unit='dBμV', default=80.0, min=0.0, max=None, description='CISPR 22 Class B limit: 66 dBμV at 150 kHz'),
            InputField(key='frequency', label='Problem Frequency', unit='kHz', default=150.0, min=0.1, max=None, description=''),
            InputField(key='targetAttenuation', label='Required Attenuation', unit='dB', default=20.0, min=0.0, max=None, description=''),
            InputField(key='loadImpedance', label='Load Impedance', unit='Ω', default=50.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='requiredF0', label='Filter Corner Frequency', unit='kHz', description=''),
            OutputField(key='cValue', label='Capacitor Value', unit='μF', description=''),
            OutputField(key='lValue', label='Inductor Value', unit='μH', description=''),
            OutputField(key='outputLevel', label='Output Emission Level', unit='dBμV', description=''),
        ),
        keywords=('conducted emissions filter', 'EMI filter design', 'CISPR conducted', 'LC EMI filter', 'line filter EMC', 'conducted emissions SMPS',),
    ),
    'differential-mode-filter': CalculatorInfo(
        slug='differential-mode-filter',
        title='Differential Mode EMI Filter',
        category='emc',
        description='Design a differential mode LC EMI filter: calculate corner frequency, attenuation, and characteristic impedance for SMPS output filtering.',
        inputs=(
            InputField(key='inductance', label='Differential Mode Inductance', unit='μH', default=47.0, min=0.001, max=None, description=''),
            InputField(key='capacitance', label='Differential Mode Capacitance', unit='μF', default=0.47, min=0.001, max=None, description=''),
            InputField(key='frequency', label='Problem Frequency', unit='kHz', default=150.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='cornerFreq', label='Corner Frequency', unit='kHz', description=''),
            OutputField(key='attenuation', label='Attenuation at f', unit='dB', description=''),
            OutputField(key='characteristicImpedance', label='Characteristic Impedance', unit='Ω', description=''),
        ),
        keywords=('differential mode filter', 'DM EMI filter', 'differential mode noise', 'SMPS EMI filter', 'EMI filter differential', 'power line filter',),
    ),
    'audio-power-amplifier': CalculatorInfo(
        slug='audio-power-amplifier',
        title='Audio Power Amplifier Calculator',
        category='audio',
        description='Calculate audio amplifier output power, efficiency, THD class estimate, SNR, and input sensitivity for Class A, AB, and D amplifiers.',
        inputs=(
            InputField(key='vcc', label='Supply Voltage', unit='V', default=12.0, min=1.0, max=100.0, description='Single supply voltage powering the amplifier'),
            InputField(key='rl', label='Speaker Impedance', unit='Ω', default=8.0, min=1.0, max=1000.0, description='Speaker load impedance (common: 4Ω, 8Ω, 16Ω)'),
            InputField(key='efficiency', label='Amplifier Efficiency', unit='%', default=70.0, min=1.0, max=99.0, description='Amplifier efficiency: Class A ≈ 20%, Class AB ≈ 70%, Class D ≈ 90%'),
            InputField(key='gain', label='Voltage Gain', unit='dB', default=26.0, min=0.0, max=80.0, description='Amplifier voltage gain'),
        ),
        outputs=(
            OutputField(key='poutMax', label='Maximum Output Power', unit='W', description='Maximum output power at clipping (Vout_peak² / 2RL)'),
            OutputField(key='poutRMS', label='RMS Program Power', unit='W', description='Typical RMS power for program material (≈50% of max)'),
            OutputField(key='thd_level', label='Typical THD', unit='%', description='Typical total harmonic distortion estimate by amplifier class'),
            OutputField(key='snr', label='Approx. SNR', unit='dB', description='Approximate signal-to-noise ratio estimate'),
            OutputField(key='inputSensitivity', label='Input Sensitivity', unit='mV', description='RMS input voltage required for full output power'),
        ),
        keywords=('audio amplifier power calculator', 'class d amplifier', 'speaker power output', 'amplifier efficiency', 'audio snr calculator',),
    ),
    'speaker-crossover': CalculatorInfo(
        slug='speaker-crossover',
        title='Passive Speaker Crossover Calculator',
        category='audio',
        description='Calculate passive 2-way speaker crossover component values for 1st order (6dB/oct) and 2nd order Butterworth (12dB/oct) networks.',
        inputs=(
            InputField(key='crossoverFreq', label='Crossover Frequency', unit='Hz', default=3000.0, min=100.0, max=20000.0, description='Crossover frequency between woofer and tweeter'),
            InputField(key='wooferImpedance', label='Woofer Impedance', unit='Ω', default=8.0, min=1.0, max=32.0, description='Woofer nominal impedance'),
            InputField(key='tweeterImpedance', label='Tweeter Impedance', unit='Ω', default=8.0, min=1.0, max=32.0, description='Tweeter nominal impedance'),
            InputField(key='order', label='Filter Order', unit='', default=2.0, min=1.0, max=2.0, description='1 = 1st order 6dB/octave, 2 = 2nd order Butterworth 12dB/octave'),
        ),
        outputs=(
            OutputField(key='wooferL', label='Woofer Inductor', unit='mH', description='Inductor in series with woofer (low-pass filter)'),
            OutputField(key='wooferC', label='Woofer Capacitor', unit='μF', description='Capacitor in parallel with woofer (2nd order only; equals tweeter cap value for 1st order)'),
            OutputField(key='tweeterC', label='Tweeter Capacitor', unit='μF', description='Capacitor in series with tweeter (high-pass filter)'),
            OutputField(key='tweeterL', label='Tweeter Inductor', unit='mH', description='Inductor in parallel with tweeter (2nd order only)'),
            OutputField(key='slopeDb', label='Filter Slope', unit='dB/oct', description='Crossover rolloff slope'),
        ),
        keywords=('speaker crossover calculator', 'passive crossover design', '2 way crossover components', 'butterworth crossover', 'woofer tweeter crossover',),
    ),
    'room-modes': CalculatorInfo(
        slug='room-modes',
        title='Room Acoustic Modes',
        category='audio',
        description='Calculate room axial resonant frequencies and Schroeder frequency for acoustic treatment and speaker placement.',
        inputs=(
            InputField(key='length', label='Room Length', unit='m', default=5.0, min=0.5, max=None, description=''),
            InputField(key='width', label='Room Width', unit='m', default=3.5, min=0.5, max=None, description=''),
            InputField(key='height', label='Room Height', unit='m', default=2.5, min=0.5, max=None, description=''),
            InputField(key='speedOfSound', label='Speed of Sound', unit='m/s', default=343.0, min=300.0, max=360.0, description='343 m/s at 20°C'),
            InputField(key='rt60', label='Reverberation Time (RT60)', unit='s', default=0.4, min=0.05, max=5.0, description='Typical rooms 0.3–0.8 s'),
        ),
        outputs=(
            OutputField(key='flLength', label='Length Mode (1st)', unit='Hz', description=''),
            OutputField(key='flWidth', label='Width Mode (1st)', unit='Hz', description=''),
            OutputField(key='flHeight', label='Height Mode (1st)', unit='Hz', description=''),
            OutputField(key='schroeder', label='Schroeder Frequency', unit='Hz', description=''),
            OutputField(key='volume', label='Room Volume', unit='m³', description=''),
        ),
        keywords=('room modes', 'room acoustics', 'standing waves', 'axial modes', 'Schroeder frequency', 'room resonance',),
    ),
    'speaker-sensitivity': CalculatorInfo(
        slug='speaker-sensitivity',
        title='Speaker Sensitivity & SPL',
        category='audio',
        description='Calculate speaker SPL at any power and distance from the rated sensitivity (dB/W/m) specification.',
        inputs=(
            InputField(key='sensitivity', label='Speaker Sensitivity', unit='dB/W/m', default=89.0, min=60.0, max=120.0, description='From speaker datasheet, measured at 1W, 1m'),
            InputField(key='power', label='Amplifier Power', unit='W', default=50.0, min=0.001, max=None, description=''),
            InputField(key='distance', label='Listening Distance', unit='m', default=3.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='splAtPower', label='SPL at Full Power (1m)', unit='dB', description=''),
            OutputField(key='splAtDistance', label='SPL at Distance', unit='dB', description=''),
        ),
        keywords=('speaker sensitivity', 'SPL calculator', 'speaker dB', 'speaker loudness', 'dB/W/m', 'speaker power',),
    ),
    'headphone-power': CalculatorInfo(
        slug='headphone-power',
        title='Headphone Amplifier Power',
        category='audio',
        description='Calculate the amplifier output power, voltage, and current required to drive headphones to a target SPL.',
        inputs=(
            InputField(key='impedance', label='Headphone Impedance', unit='Ω', default=300.0, min=8.0, max=None, description=''),
            InputField(key='sensitivity', label='Headphone Sensitivity', unit='dB/mW', default=100.0, min=70.0, max=130.0, description='From headphone datasheet, in dB SPL per milliwatt'),
            InputField(key='targetSpl', label='Target SPL', unit='dB', default=110.0, min=70.0, max=140.0, description=''),
        ),
        outputs=(
            OutputField(key='requiredPowerMw', label='Required Power', unit='mW', description=''),
            OutputField(key='requiredPowerW', label='Required Power (W)', unit='W', description='Power in watts (for amplifier datasheet comparison)'),
            OutputField(key='requiredVoltageRms', label='Required Voltage (RMS)', unit='V', description=''),
            OutputField(key='requiredCurrentMa', label='Required Current', unit='mA', description=''),
        ),
        keywords=('headphone amplifier', 'headphone power', 'headphone impedance', 'headphone SPL', 'amp output power', 'headphone sensitivity',),
    ),
    'audio-snr': CalculatorInfo(
        slug='audio-snr',
        title='Audio SNR & Dynamic Range',
        category='audio',
        description='Calculate audio signal-to-noise ratio, dynamic range, and equivalent noise bits from signal and noise floor levels.',
        inputs=(
            InputField(key='signalLevel', label='Signal Level', unit='dBV', default=0.0, min=-80.0, max=30.0, description=''),
            InputField(key='noiseFloor', label='Noise Floor', unit='dBV', default=-90.0, min=-140.0, max=0.0, description=''),
        ),
        outputs=(
            OutputField(key='snr', label='SNR', unit='dB', description=''),
            OutputField(key='dynamicRange', label='Dynamic Range', unit='dB', description='Span from noise floor to 0 dBFS maximum level'),
            OutputField(key='snrLinear', label='SNR (linear voltage ratio)', unit=':1', description=''),
            OutputField(key='noiseBits', label='Effective Noise Bits', unit='bits', description=''),
        ),
        keywords=('audio SNR', 'signal to noise ratio audio', 'dynamic range audio', 'noise floor audio', 'audio quality', 'ENOB audio',),
    ),
    'op-amp-slew-rate': CalculatorInfo(
        slug='op-amp-slew-rate',
        title='Op-Amp Slew Rate & Full-Power Bandwidth',
        category='audio',
        description='Calculate op-amp full-power bandwidth from slew rate and signal amplitude, and verify the op-amp can handle your signal without slew-rate distortion.',
        inputs=(
            InputField(key='slewRate', label='Op-Amp Slew Rate', unit='V/μs', default=13.0, min=0.001, max=None, description='From op-amp datasheet'),
            InputField(key='amplitude', label='Signal Peak Amplitude', unit='V', default=5.0, min=0.001, max=None, description=''),
            InputField(key='frequency', label='Signal Frequency', unit='Hz', default=20000.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='fullPowerBandwidth', label='Full-Power Bandwidth', unit='Hz', description=''),
            OutputField(key='minSlewRateRequired', label='Min. Slew Rate Required', unit='V/μs', description=''),
            OutputField(key='slewMargin', label='Slew Rate Margin', unit='V/μs', description=''),
        ),
        keywords=('op-amp slew rate', 'full power bandwidth', 'slew rate distortion', 'op amp bandwidth', 'audio op amp', 'slewing',),
    ),
    'audio-transformer': CalculatorInfo(
        slug='audio-transformer',
        title='Audio Transformer Turns Ratio',
        category='audio',
        description='Calculate audio transformer turns ratio for impedance matching between source and load, plus secondary voltage and current.',
        inputs=(
            InputField(key='primaryImpedance', label='Primary Impedance', unit='Ω', default=600.0, min=1.0, max=None, description=''),
            InputField(key='secondaryImpedance', label='Secondary Impedance', unit='Ω', default=8.0, min=1.0, max=None, description=''),
            InputField(key='primaryVoltage', label='Primary Voltage (RMS)', unit='V', default=1.0, min=0.0, max=None, description=''),
            InputField(key='primaryCurrent', label='Primary Current (RMS)', unit='A', default=0.001, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='turnsRatio', label='Turns Ratio (n)', unit=':1', description=''),
            OutputField(key='secondaryVoltage', label='Secondary Voltage', unit='V', description=''),
            OutputField(key='secondaryCurrent', label='Secondary Current', unit='A', description=''),
            OutputField(key='powerTransferred', label='Power Transferred', unit='W', description=''),
        ),
        keywords=('audio transformer', 'transformer turns ratio', 'impedance matching transformer', 'balun transformer audio', 'DI box transformer', '600 ohm matching',),
    ),
    'cable-capacitance-rolloff': CalculatorInfo(
        slug='cable-capacitance-rolloff',
        title='Cable Capacitance High-Frequency Rolloff',
        category='audio',
        description='Calculate the high-frequency rolloff (-3 dB point) caused by cable capacitance interacting with source impedance.',
        inputs=(
            InputField(key='sourceImpedance', label='Source Impedance', unit='Ω', default=10000.0, min=1.0, max=None, description=''),
            InputField(key='cableCapacitancePf', label='Cable Capacitance', unit='pF/m', default=100.0, min=1.0, max=None, description='Per metre, from cable datasheet (typical: 80–150 pF/m)'),
            InputField(key='cableLengthM', label='Cable Length', unit='m', default=5.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='totalCapacitancePf', label='Total Cable Capacitance', unit='pF', description=''),
            OutputField(key='cutoffFrequency', label='-3 dB Frequency', unit='Hz', description=''),
            OutputField(key='rolloffAt20k', label='Rolloff at 20 kHz', unit='dB', description=''),
        ),
        keywords=('cable capacitance', 'high frequency rolloff', 'guitar cable', 'audio cable rolloff', 'capacitance rolloff', 'cable treble loss',),
    ),
    'subwoofer-box': CalculatorInfo(
        slug='subwoofer-box',
        title='Subwoofer Enclosure Volume',
        category='audio',
        description='Calculate optimal subwoofer box (sealed and ported) volume and port tuning frequency from Thiele-Small parameters (Vas, Qts, Fs).',
        inputs=(
            InputField(key='vas', label='Vas (Equivalent Volume)', unit='L', default=50.0, min=0.1, max=None, description='From driver datasheet'),
            InputField(key='qts', label='Qts (Total Q)', unit='', default=0.35, min=0.01, max=2.0, description='Qts < 0.35 → vented, 0.35–0.7 → sealed'),
            InputField(key='fs', label='Fs (Resonant Frequency)', unit='Hz', default=35.0, min=5.0, max=200.0, description=''),
        ),
        outputs=(
            OutputField(key='vbSealed', label='Sealed Box Volume', unit='L', description=''),
            OutputField(key='vbVented', label='Ported Box Volume', unit='L', description=''),
            OutputField(key='portTuning', label='Port Tuning Frequency', unit='Hz', description=''),
            OutputField(key='f3Sealed', label='-3 dB (Sealed)', unit='Hz', description=''),
        ),
        keywords=('subwoofer box calculator', 'speaker enclosure', 'Thiele-Small', 'ported box', 'sealed box subwoofer', 'Vas Qts Fs',),
    ),
    'tweeter-capacitor': CalculatorInfo(
        slug='tweeter-capacitor',
        title='Tweeter Protection Capacitor',
        category='audio',
        description='Calculate the capacitor value for a first-order tweeter high-pass filter to protect tweeters from low-frequency damage.',
        inputs=(
            InputField(key='tweetImpedance', label='Tweeter Impedance', unit='Ω', default=8.0, min=1.0, max=None, description=''),
            InputField(key='crossoverFreq', label='Crossover Frequency', unit='Hz', default=3000.0, min=100.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='capacitanceMicroF', label='Capacitor Value', unit='μF', description=''),
            OutputField(key='reactanceAt1k', label='Reactance at 1 kHz', unit='Ω', description=''),
            OutputField(key='rolloffAt100Hz', label='Rolloff at 100 Hz', unit='dB', description=''),
        ),
        keywords=('tweeter capacitor', 'tweeter protection', 'crossover capacitor', 'high-pass filter speaker', 'tweeter crossover', 'speaker protection cap',),
    ),
    'class-d-efficiency': CalculatorInfo(
        slug='class-d-efficiency',
        title='Class D Amplifier Efficiency',
        category='audio',
        description='Estimate Class D amplifier efficiency from MOSFET conduction losses and quiescent current at a given output power.',
        inputs=(
            InputField(key='outputPower', label='Output Power', unit='W', default=50.0, min=0.1, max=None, description=''),
            InputField(key='supplyVoltage', label='Supply Voltage', unit='V', default=36.0, min=1.0, max=None, description=''),
            InputField(key='loadImpedance', label='Load Impedance', unit='Ω', default=8.0, min=1.0, max=None, description=''),
            InputField(key='rdson', label='MOSFET RDS(on)', unit='mΩ', default=50.0, min=1.0, max=None, description='Per MOSFET in milliohms'),
            InputField(key='mosfetCount', label='Number of MOSFETs', unit='', default=4.0, min=2.0, max=None, description=''),
            InputField(key='quiescentCurrent', label='Quiescent Current', unit='mA', default=30.0, min=0.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='efficiency', label='Efficiency', unit='%', description=''),
            OutputField(key='conductionLoss', label='Conduction Loss', unit='W', description=''),
            OutputField(key='quiescentLoss', label='Quiescent Loss', unit='W', description=''),
            OutputField(key='totalLoss', label='Total Power Loss', unit='W', description='Total heat dissipated — use for heatsink sizing'),
            OutputField(key='totalInput', label='Total Input Power', unit='W', description=''),
        ),
        keywords=('class D amplifier', 'class D efficiency', 'switching amplifier', 'class D audio', 'PWM amplifier efficiency', 'class D vs class AB',),
    ),
    'audio-adc-snr': CalculatorInfo(
        slug='audio-adc-snr',
        title='ADC Bit Depth to Dynamic Range',
        category='audio',
        description='Calculate the theoretical SNR and dynamic range of an audio ADC from its bit depth, and the improvement from oversampling.',
        inputs=(
            InputField(key='bitDepth', label='Bit Depth', unit='bits', default=24.0, min=1.0, max=32.0, description=''),
            InputField(key='oversamplingRatio', label='Oversampling Ratio', unit='×', default=1.0, min=1.0, max=None, description=''),
        ),
        outputs=(
            OutputField(key='theoreticalSnr', label='Theoretical SNR', unit='dB', description=''),
            OutputField(key='oversamplingGain', label='Oversampling Gain', unit='dB', description=''),
            OutputField(key='totalSnr', label='Total SNR', unit='dB', description=''),
            OutputField(key='dynamicRange', label='Dynamic Range', unit='dB', description=''),
        ),
        keywords=('ADC SNR', 'bit depth dynamic range', 'audio ADC', '24 bit audio', 'oversampling SNR', 'ENOB audio ADC',),
    ),
    'equalizer-q-factor': CalculatorInfo(
        slug='equalizer-q-factor',
        title='Equalizer Filter Q & Bandwidth',
        category='audio',
        description='Calculate equalizer Q factor from center frequency and bandwidth, or convert between Q, octaves, and frequency limits.',
        inputs=(
            InputField(key='centerFreq', label='Center Frequency', unit='Hz', default=1000.0, min=1.0, max=None, description=''),
            InputField(key='bandwidth', label='Bandwidth (−3 dB)', unit='Hz', default=200.0, min=0.1, max=None, description=''),
        ),
        outputs=(
            OutputField(key='qFactor', label='Q Factor', unit='', description=''),
            OutputField(key='octaves', label='Bandwidth', unit='octaves', description=''),
            OutputField(key='lowerFreq', label='Lower −3 dB Frequency', unit='Hz', description=''),
            OutputField(key='upperFreq', label='Upper −3 dB Frequency', unit='Hz', description=''),
        ),
        keywords=('equalizer Q factor', 'EQ bandwidth', 'parametric EQ', 'Q factor audio', 'octave bandwidth', 'EQ filter',),
    ),
    'amplifier-clipping': CalculatorInfo(
        slug='amplifier-clipping',
        title='Amplifier Clipping Level',
        category='audio',
        description='Calculate amplifier clipping voltage, power, and dBV level from supply voltage and load impedance.',
        inputs=(
            InputField(key='supplyVoltage', label='Supply Voltage (±V or single)', unit='V', default=36.0, min=1.0, max=None, description='For dual supply (±18V), enter 18V'),
            InputField(key='loadImpedance', label='Load Impedance', unit='Ω', default=8.0, min=1.0, max=None, description=''),
            InputField(key='headroom', label='Headroom Reserve', unit='%', default=100.0, min=10.0, max=100.0, description='100% = maximum output, lower to add headroom margin'),
        ),
        outputs=(
            OutputField(key='maxOutputVoltage', label='Max Output Voltage (peak)', unit='V', description=''),
            OutputField(key='rmsVoltage', label='Max Output Voltage (RMS)', unit='V', description=''),
            OutputField(key='clippingPower', label='Continuous Power at Clipping', unit='W', description=''),
            OutputField(key='clippingLevel', label='Clipping Level', unit='dBV', description=''),
        ),
        keywords=('amplifier clipping', 'clip level', 'amplifier output voltage', 'amp clipping power', 'headroom amplifier', 'clipping distortion',),
    ),
    'audio-delay-time': CalculatorInfo(
        slug='audio-delay-time',
        title='Audio Delay & Echo Time Calculator',
        category='audio',
        description='Calculate musically-synced delay times from BPM and note value, plus acoustic propagation delay from speaker distance.',
        inputs=(
            InputField(key='bpm', label='Tempo (BPM)', unit='bpm', default=120.0, min=20.0, max=300.0, description=''),
            InputField(key='noteValue', label='Note Division', unit='', default=4.0, min=1.0, max=None, description=''),
            InputField(key='distance', label='Speaker Distance', unit='m', default=10.0, min=0.0, max=None, description=''),
            InputField(key='speedOfSound', label='Speed of Sound', unit='m/s', default=343.0, min=300.0, max=360.0, description=''),
        ),
        outputs=(
            OutputField(key='beatMs', label='Quarter-Note Delay', unit='ms', description=''),
            OutputField(key='noteDelayMs', label='Selected Note Delay', unit='ms', description=''),
            OutputField(key='propagationMs', label='Propagation Delay', unit='ms', description=''),
        ),
        keywords=('audio delay time', 'BPM delay calculator', 'delay tempo sync', 'echo time', 'reverb time', 'delay milliseconds BPM',),
    ),
    'power-amplifier-gain': CalculatorInfo(
        slug='power-amplifier-gain',
        title='Power Amplifier Gain Calculator',
        category='audio',
        description='Calculate power amplifier voltage gain (V/V and dB) and power gain from input/output voltage and power measurements.',
        inputs=(
            InputField(key='inputVoltage', label='Input Voltage (RMS)', unit='V', default=1.0, min=0.001, max=None, description=''),
            InputField(key='outputVoltage', label='Output Voltage (RMS)', unit='V', default=28.0, min=0.001, max=None, description=''),
            InputField(key='inputPower', label='Input Power', unit='mW', default=0.1, min=0.001, max=None, description='Power consumed by amplifier input'),
            InputField(key='outputPower', label='Output Power', unit='W', default=100.0, min=0.001, max=None, description=''),
        ),
        outputs=(
            OutputField(key='voltageGain', label='Voltage Gain', unit='V/V', description=''),
            OutputField(key='voltageGainDb', label='Voltage Gain', unit='dB', description=''),
            OutputField(key='powerGain', label='Power Gain', unit='W/W', description=''),
            OutputField(key='powerGainDb', label='Power Gain', unit='dB', description=''),
        ),
        keywords=('amplifier gain', 'power amplifier dB', 'voltage gain amplifier', 'gain dB', 'amplifier sensitivity', 'audio gain',),
    ),
}
