diff --git a/hdyc-svelte/src/app.css b/hdyc-svelte/src/app.css index c10fe57..526f0c8 100644 --- a/hdyc-svelte/src/app.css +++ b/hdyc-svelte/src/app.css @@ -328,6 +328,9 @@ a:hover { .palette-dots { display: flex; gap: 0.25rem; + overflow: hidden; + max-width: 38px; + transition: max-width 0.2s ease, gap 0.2s ease; } .palette-dot { width: 30px; @@ -338,13 +341,18 @@ a:hover { background-size: 160%; background-position: center; cursor: pointer; - transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s; + transition: transform 0.2s, border-color 0.2s, box-shadow 0.2s, opacity 0.2s; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05); overflow: hidden; + flex-shrink: 0; + order: 0; } .palette-dot:hover { transform: translateY(-1px); } +.palette-dot.active { + order: -1; +} .palette-dot.active, .palette-dot:focus-visible { border-color: var(--accent); @@ -353,6 +361,23 @@ a:hover { .palette-dot:focus-visible { outline: none; } +.floating-palette-controls:not(:hover):not(:focus-within) .palette-dots { + gap: 0; +} +.floating-palette-controls:not(:hover):not(:focus-within) .palette-dot:not(.active) { + opacity: 0; + pointer-events: none; +} +.floating-palette-controls:hover .palette-dots, +.floating-palette-controls:focus-within .palette-dots { + max-width: 360px; + gap: 0.25rem; +} +.floating-palette-controls:hover .palette-dot:not(.active), +.floating-palette-controls:focus-within .palette-dot:not(.active) { + opacity: 1; + pointer-events: auto; +} @media (max-width: 520px) { .floating-palette-controls { diff --git a/hdyc-svelte/src/lib/data/calculators.ts b/hdyc-svelte/src/lib/data/calculators.ts index b69d0b6..e930d3b 100644 --- a/hdyc-svelte/src/lib/data/calculators.ts +++ b/hdyc-svelte/src/lib/data/calculators.ts @@ -284,7 +284,7 @@ export const calculators: CalculatorDef[] = [ {"slug": "horsepower-to-calories-per-second", "name": "Horsepower to Calories Per Second", "category": "speed", "type": "standard", "teaser": "Translate mechanical horsepower into calories per second.", "labels": {"in1": "Horsepower", "in2": "Calories Per Second"}, "factor": 178.226546845}, {"slug": "horsepower-to-electrical-horsepower", "name": "Horsepower to Electrical Horsepower", "category": "power", "type": "standard", "teaser": "Convert mechanical horsepower into electrical horsepower.", "labels": {"in1": "Horsepower", "in2": "Electrical Horsepower"}, "factor": 0.999597683646, "hidden": true}, {"slug": "kilowatts-to-kva", "name": "Kilowatts to kVA", "category": "power", "type": "standard", "labels": {"in1": "Kilowatts", "in2": "kVA"}}, - {"slug": "lusec-to-watts", "name": "Lusec to Watts", "category": "power", "type": "standard", "labels": {"in1": "Lusec", "in2": "Watts"}, "factor": 0.000133322}, + {"slug": "lusec-to-watts", "name": "Lusec to Watts", "category": "power", "type": "standard", "labels": {"in1": "Lusec", "in2": "Watts"}, "factor": 0.000133322, "hidden": true}, {"slug": "watts-to-btumin", "name": "Watts to BTU/min", "category": "energy", "type": "standard", "labels": {"in1": "Watts", "in2": "BTU/min"}, "factor": 0.0568690272522}, {"slug": "calories-per-second-to-metric-horsepower-ps", "name": "Calories Per Second to Metric Horsepower (ps)", "category": "speed", "type": "standard", "labels": {"in1": "Calories Per Second", "in2": "Metric Horsepower (ps)"}, "factor": 0.0056886568468}, {"slug": "horsepower-to-lusec", "name": "Horsepower to Lusec", "category": "power", "type": "standard", "labels": {"in1": "Horsepower", "in2": "Lusec"}, "factor": 5593224.46408}, @@ -882,6 +882,22 @@ export const calculators: CalculatorDef[] = [ {"slug": "kilowatts-to-btuhour", "name": "Kilowatts to BTU/hour", "category": "energy", "type": "standard", "teaser": "Convert kilowatts to BTU per hour.", "labels": {"in1": "Kilowatts", "in2": "BTU/hour"}, "factor": 3412.142}, {"slug": "kilowatts-to-megawatts", "name": "Kilowatts to Megawatts", "category": "power", "type": "standard", "teaser": "Convert power from kilowatts to megawatts.", "labels": {"in1": "Kilowatts", "in2": "Megawatts"}, "factor": 0.001, "hidden": true}, {"slug": "kilowatts-to-watts", "name": "Kilowatts to Watts", "category": "power", "type": "standard", "teaser": "Convert kilowatts to watts.", "labels": {"in1": "Kilowatts", "in2": "Watts"}, "factor": 1000.0}, + {"slug": "kilowatts-to-amps", "name": "Kilowatts to Amps", "category": "power", "type": "3col", "teaser": "Relate kilowatts to amperage when the voltage is known.", "labels": {"in1": "Kilowatts", "in2": "Amps", "in3": "Volts"}, "hidden": true}, + {"slug": "kilowatts-to-abamperes", "name": "Kilowatts to Abamperes", "category": "power", "type": "3col", "teaser": "Convert kilowatts into CGS abamperes using abvolts or current.", "labels": {"in1": "Kilowatts", "in2": "Abamperes", "in3": "Result"}}, + {"slug": "kilowatts-to-abvolts", "name": "Kilowatts to Abvolts", "category": "power", "type": "3col", "teaser": "Convert kilowatts into abvolts given CGS abamperes.", "labels": {"in1": "Kilowatts", "in2": "Abvolts", "in3": "Result"}}, + {"slug": "kilowatts-to-ampere-hours", "name": "Kilowatts to Ampere-hours", "category": "power", "type": "3col", "teaser": "Turn kilowatt draws into ampere-hours when you know the duration.", "labels": {"in1": "Kilowatts", "in2": "Ampere-hours", "in3": "Result"}}, + {"slug": "kilowatts-to-btumin", "name": "Kilowatts to BTU/min", "category": "energy", "type": "standard", "teaser": "Convert kilowatts into BTUs per minute for heat rate comparisons.", "labels": {"in1": "Kilowatts", "in2": "BTU/min"}, "factor": 56.8690272522}, + {"slug": "kilowatts-to-calories-per-second", "name": "Kilowatts to Calories Per Second", "category": "speed", "type": "standard", "teaser": "Translate kilowatts into calories per second for nutrition math.", "labels": {"in1": "Kilowatts", "in2": "Calories Per Second"}, "factor": 238.8458966}, + {"slug": "kilowatts-to-coulombs", "name": "Kilowatts to Coulombs", "category": "power", "type": "3col", "teaser": "Convert kilowatts into coulombs when the time or voltage is given.", "labels": {"in1": "Kilowatts", "in2": "Coulombs", "in3": "Result"}}, + {"slug": "kilowatts-to-farads", "name": "Kilowatts to Farads", "category": "power", "type": "3col", "teaser": "Estimate the capacitance in farads from kilowatt loads.", "labels": {"in1": "Kilowatts", "in2": "Farads", "in3": "Result"}}, + {"slug": "kilowatts-to-henries", "name": "Kilowatts to Henries", "category": "power", "type": "3col", "teaser": "Estimate inductance in henries using kilowatt load and frequency.", "labels": {"in1": "Kilowatts", "in2": "Henries", "in3": "Result"}}, + {"slug": "kilowatts-to-lusec", "name": "Kilowatts to Lusec", "category": "power", "type": "standard", "teaser": "Translate kilowatts into lusecs for legacy power ratings.", "labels": {"in1": "Kilowatts", "in2": "Lusec"}, "factor": 7500637.554192106}, + {"slug": "kilowatts-to-mechanical-hp", "name": "Kilowatts to Mechanical Hp", "category": "power", "type": "standard", "teaser": "Convert kilowatts into mechanical horsepower.", "labels": {"in1": "Kilowatts", "in2": "Mechanical Hp"}, "factor": 1.341021858656296}, + {"slug": "kilowatts-to-microfarads", "name": "Kilowatts to Microfarads", "category": "power", "type": "3col", "teaser": "Convert kilowatt loads into capacitance using voltage.", "labels": {"in1": "Kilowatts", "in2": "Microfarads", "in3": "Result"}}, + {"slug": "kilowatts-to-microhenries", "name": "Kilowatts to Microhenries", "category": "power", "type": "3col", "teaser": "Estimate inductance in microhenries for a kilowatt-level circuit.", "labels": {"in1": "Kilowatts", "in2": "Microhenries", "in3": "Result"}}, + {"slug": "kilowatts-to-milliampere-hours", "name": "Kilowatts to Milliampere-hours", "category": "power", "type": "3col", "teaser": "Turn kilowatt-hours into milliampere-hours given voltage.", "labels": {"in1": "Kilowatts", "in2": "Milliampere-hours", "in3": "Result"}}, + {"slug": "kilowatts-to-milliamps", "name": "Kilowatts to Milliamps", "category": "power", "type": "3col", "teaser": "Convert kilowatts into milliamps when you know the voltage.", "labels": {"in1": "Kilowatts", "in2": "Milliamps", "in3": "Volts"}}, + {"slug": "kilowatts-to-millihenries", "name": "Kilowatts to Millihenries", "category": "power", "type": "3col", "teaser": "Estimate inductance in millihenries from a kilowatt load.", "labels": {"in1": "Kilowatts", "in2": "Millihenries", "in3": "Result"}}, {"slug": "km-per-kwh-to-miles-per-kwh", "name": "Kilometers per kWh to Miles per kWh", "category": "length", "type": "standard", "teaser": "Convert energy efficiency from km/kWh to mi/kWh.", "labels": {"in1": "Kilometers per kWh", "in2": "Miles per kWh"}, "factor": 0.621371, "hidden": true}, {"slug": "kilometers-per-second-to-speed-of-light", "name": "Kilometers per Second to Speed of Light", "category": "length", "type": "standard", "teaser": "Express a speed in kilometers per second as a fraction of c (299,792.458 km/s).", "labels": {"in1": "Kilometers per Second", "in2": "Speed of Light"}, "factor": 3.33564095198152e-06, "hidden": true}, {"slug": "knots-to-feet-per-second", "name": "Knots to Feet per Second", "category": "length", "type": "standard", "teaser": "Convert a nautical mile per hour into feet per second.", "labels": {"in1": "Knots", "in2": "Feet per Second"}, "factor": 1.6878098376}, @@ -1241,6 +1257,30 @@ export const calculators: CalculatorDef[] = [ {"slug": "watts-to-calories-per-second", "name": "Watts to Calories per Second", "category": "speed", "type": "standard", "teaser": "Translate watts into calories per second for nutrition math.", "labels": {"in1": "Watts", "in2": "Calories per Second"}, "factor": 0.2388458966, "hidden": true}, {"slug": "watts-to-kilowatts", "name": "Watts to Kilowatts", "category": "power", "type": "standard", "teaser": "Express watts as kilowatts for appliance specs.", "labels": {"in1": "Watts", "in2": "Kilowatts"}, "factor": 0.001, "hidden": true}, {"slug": "watts-to-metric-horsepower", "name": "Watts to Metric Horsepower", "category": "power", "type": "standard", "teaser": "Convert watts into metric horsepower (PS) for vehicle specs.", "labels": {"in1": "Watts", "in2": "Metric Horsepower"}, "factor": 0.00135962162, "hidden": true}, + {"slug": "watts-to-volts", "name": "Watts to Volts", "category": "power", "type": "3col", "teaser": "Determine the voltage when you know the power and current.", "labels": {"in1": "Watts", "in2": "Volts", "in3": "Result"}}, + {"slug": "watts-to-abamperes", "name": "Watts to Abamperes", "category": "power", "type": "3col", "teaser": "Convert watts into CGS abamperes when you have voltage in abvolts.", "labels": {"in1": "Watts", "in2": "Abamperes", "in3": "Result"}}, + {"slug": "watts-to-abvolts", "name": "Watts to Abvolts", "category": "power", "type": "3col", "teaser": "Convert watts into CGS abvolts using abamperes.", "labels": {"in1": "Watts", "in2": "Abvolts", "in3": "Result"}}, + {"slug": "watts-to-ampere-hours", "name": "Watts to Ampere-hours", "category": "power", "type": "3col", "teaser": "Turn a watt draw into ampere-hours when you know the duration or voltage.", "labels": {"in1": "Watts", "in2": "Ampere-hours", "in3": "Result"}}, + {"slug": "watts-to-coulombs", "name": "Watts to Coulombs", "category": "power", "type": "3col", "teaser": "Translate watts into coulombs when voltage or time is provided.", "labels": {"in1": "Watts", "in2": "Coulombs", "in3": "Result"}}, + {"slug": "watts-to-farads", "name": "Watts to Farads", "category": "power", "type": "3col", "teaser": "Estimate capacitance required for a given wattage and voltage.", "labels": {"in1": "Watts", "in2": "Farads", "in3": "Result"}}, + {"slug": "watts-to-henries", "name": "Watts to Henries", "category": "power", "type": "3col", "teaser": "Estimate inductance from a wattage and frequency scenario.", "labels": {"in1": "Watts", "in2": "Henries", "in3": "Result"}}, + {"slug": "watts-to-kva", "name": "Watts to kVA", "category": "power", "type": "standard", "teaser": "Convert watts into kilovolt-amperes assuming unity power factor.", "labels": {"in1": "Watts", "in2": "kVA"}, "factor": 0.001}, + {"slug": "watts-to-lusec", "name": "Watts to Lusec", "category": "power", "type": "standard", "teaser": "Translate watts into lusecs for vintage motor specs.", "labels": {"in1": "Watts", "in2": "Lusec"}, "factor": 7500.637554192106}, + {"slug": "watts-to-mechanical-hp", "name": "Watts to Mechanical Hp", "category": "power", "type": "standard", "teaser": "Translate watts into mechanical horsepower.", "labels": {"in1": "Watts", "in2": "Mechanical Hp"}, "factor": 0.001341021858656296}, + {"slug": "watts-to-megawatts", "name": "Watts to Megawatts", "category": "power", "type": "standard", "teaser": "Scale watts down to megawatts.", "labels": {"in1": "Watts", "in2": "Megawatts"}, "factor": 1e-06}, + {"slug": "watts-to-microfarads", "name": "Watts to Microfarads", "category": "power", "type": "3col", "teaser": "Convert wattage into capacitance when voltage is known.", "labels": {"in1": "Watts", "in2": "Microfarads", "in3": "Result"}}, + {"slug": "watts-to-microhenries", "name": "Watts to Microhenries", "category": "power", "type": "3col", "teaser": "Convert wattage into inductance using frequency or current.", "labels": {"in1": "Watts", "in2": "Microhenries", "in3": "Result"}}, + {"slug": "watts-to-milliampere-hours", "name": "Watts to Milliampere-hours", "category": "power", "type": "3col", "teaser": "Convert power into milliampere-hours over time with voltage input.", "labels": {"in1": "Watts", "in2": "Milliampere-hours", "in3": "Result"}}, + {"slug": "watts-to-milliamps", "name": "Watts to Milliamps", "category": "power", "type": "3col", "teaser": "Convert wattage into milliamps given voltage.", "labels": {"in1": "Watts", "in2": "Milliamps", "in3": "Volts"}}, + {"slug": "watts-to-millihenries", "name": "Watts to Millihenries", "category": "power", "type": "3col", "teaser": "Estimate inductance in millihenries for a given power level.", "labels": {"in1": "Watts", "in2": "Millihenries", "in3": "Result"}}, + {"slug": "watts-to-millivolts", "name": "Watts to Millivolts", "category": "power", "type": "3col", "teaser": "Scale watts into millivolts with current data.", "labels": {"in1": "Watts", "in2": "Millivolts", "in3": "Result"}}, + {"slug": "watts-to-ohms", "name": "Watts to Ohms", "category": "power", "type": "3col", "teaser": "Derive resistance when you know wattage and current.", "labels": {"in1": "Watts", "in2": "Ohms", "in3": "Result"}}, + {"slug": "watts-to-picofarads", "name": "Watts to Picofarads", "category": "power", "type": "3col", "teaser": "Estimate capacitance in picofarads when voltage and frequency are known.", "labels": {"in1": "Watts", "in2": "Picofarads", "in3": "Result"}}, + {"slug": "watts-to-siemens", "name": "Watts to Siemens", "category": "power", "type": "3col", "teaser": "Convert wattage into siemens (conductance) when voltage or current is provided.", "labels": {"in1": "Watts", "in2": "Siemens", "in3": "Result"}}, + {"slug": "watts-to-statamperes", "name": "Watts to Statamperes", "category": "power", "type": "3col", "teaser": "Translate watts into statamperes within the CGS electromagnetic system.", "labels": {"in1": "Watts", "in2": "Statamperes", "in3": "Result"}}, + {"slug": "watts-to-statvolts", "name": "Watts to Statvolts", "category": "power", "type": "3col", "teaser": "Translate watts into statvolts when working with CGS fields.", "labels": {"in1": "Watts", "in2": "Statvolts", "in3": "Result"}}, + {"slug": "watts-to-tons-of-refrigeration", "name": "Watts to Tons Of Refrigeration", "category": "weight", "type": "standard", "teaser": "Translate continuous power into refrigeration tons.", "labels": {"in1": "Watts", "in2": "Tons Of Refrigeration"}, "factor": 0.000284345}, + {"slug": "watts-to-watt-hours", "name": "Watts to Watt-hours", "category": "power", "type": "3col", "teaser": "Convert instantaneous power into energy by supplying a time interval.", "labels": {"in1": "Watts", "in2": "Watt-hours", "in3": "Result"}}, {"slug": "watts-to-milliwatts", "name": "Watts to Milliwatts", "category": "power", "type": "standard", "teaser": "Scale watts down to milliwatts.", "labels": {"in1": "Watts", "in2": "Milliwatts"}, "factor": 1000.0}, {"slug": "weber-to-maxwell", "name": "Weber to Maxwell", "category": "other", "type": "standard", "teaser": "Express webers as maxwells for magnetic flux reports.", "labels": {"in1": "Weber", "in2": "Maxwell"}, "factor": 100000000.0}, {"slug": "wh-per-km-to-wh-per-mile", "name": "Wh per km to Wh per mile", "category": "length", "type": "standard", "teaser": "Convert EV efficiency from km to mile units.", "labels": {"in1": "Wh per km", "in2": "Wh per mile"}, "factor": 1.609344}, diff --git a/hdyc-svelte/src/lib/data/unitDefinitions.ts b/hdyc-svelte/src/lib/data/unitDefinitions.ts index 5ec69b0..768e839 100644 --- a/hdyc-svelte/src/lib/data/unitDefinitions.ts +++ b/hdyc-svelte/src/lib/data/unitDefinitions.ts @@ -75,6 +75,20 @@ const domainDefinitions: Record = }, }; +const canonicalLabelAliases: Record = { + pascals: 'Pascal', + gills: 'Gill', + newtons: 'Newton', +}; + +const normalizeLabel = (label?: string): string | undefined => { + if (!label) return undefined; + const trimmed = label.trim(); + if (!trimmed) return undefined; + const alias = canonicalLabelAliases[trimmed.toLowerCase()]; + return alias ?? trimmed; +}; + const definitions: Record> = {}; const categoryPriority = [...Object.keys(domainDefinitions)]; @@ -88,11 +102,12 @@ const buildDefinition = (label: string, categoryKey: string): string => { calculators.forEach(calc => { const { category, labels } = calc; Object.values(labels).forEach(label => { - if (!label) return; - const bucket = definitions[label] || {}; - const text = buildDefinition(label, category); + const normalized = normalizeLabel(label); + if (!normalized) return; + const bucket = definitions[normalized] || {}; + const text = buildDefinition(normalized, category); bucket[category] = text; - definitions[label] = bucket; + definitions[normalized] = bucket; }); }); @@ -107,7 +122,9 @@ const findByPriority = (entries: Record, preferred?: string): st }; export function getDefinition(label: string, category?: string): string | undefined { - const entries = definitions[label]; + const normalized = normalizeLabel(label); + if (!normalized) return undefined; + const entries = definitions[normalized]; return findByPriority(entries, category); }