mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-12 13:28:55 +00:00
fix(scenarios): band picker order, letter contrast, quieter excluded chips
Design feedback: - Target-band picker reads A→G left-to-right (reading order; the gallery/detail meters stay G→A as they mirror the building passport's efficiency gauge, which fills low→high). - Unselected picker chips are now light band-colour tints with one consistent dark ink — no ink has legal contrast across all seven band colours at full saturation, so the old full-colour+opacity fade made letter colours look inconsistent and washed out. Only the selected chip goes full colour, with luminance-correct ink (shared bandInk()). - Excluded measure chips recede (gray, struck through) instead of filling dark navy — "Exclude all" no longer paints a wall of blue; the measures still in play are the visually dominant ones. State is never colour-only: ✓/✕ icon + strikethrough carry it too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
fdae966461
commit
34dcb0a54f
2 changed files with 35 additions and 16 deletions
|
|
@ -11,7 +11,7 @@ import {
|
|||
type MeasureKey,
|
||||
} from "@/app/db/schema/recommendations";
|
||||
import { EPC_BANDS, findExactDuplicate, SCENARIO_GOALS } from "@/lib/scenarios/model";
|
||||
import { BandChip, EPC_SOFT, GOAL_DESCRIPTIONS, GOAL_SHORT_LABELS, GoalIcon, formatMoney } from "../ui";
|
||||
import { BandChip, EPC_SOFT, GOAL_DESCRIPTIONS, GOAL_SHORT_LABELS, GoalIcon, bandInk, bandTint, formatMoney } from "../ui";
|
||||
|
||||
interface ExistingScenario {
|
||||
id: string;
|
||||
|
|
@ -293,20 +293,28 @@ export function NewScenarioJourney({
|
|||
<div className="mb-5 pb-5">
|
||||
<label className={fieldLabel}>Target band</label>
|
||||
<div className="flex max-w-[480px] gap-1.5">
|
||||
{[...EPC_BANDS].reverse().map((b) => (
|
||||
{EPC_BANDS.map((b) => (
|
||||
<button
|
||||
key={b}
|
||||
aria-pressed={band === b}
|
||||
className="relative h-[52px] rounded-xl border-2 font-manrope text-lg font-extrabold transition-all"
|
||||
style={{
|
||||
background: EPC_SOFT[b],
|
||||
color: ["C", "D", "E"].includes(b) ? "#333a1d" : "#fff",
|
||||
opacity: band === b ? 1 : 0.38,
|
||||
flexGrow: band === b ? 1.7 : 1,
|
||||
transform: band === b ? "translateY(-3px)" : undefined,
|
||||
borderColor: band === b ? "#14163d" : "transparent",
|
||||
boxShadow: "inset 0 -12px 16px rgba(0,0,0,.10)",
|
||||
}}
|
||||
style={
|
||||
band === b
|
||||
? {
|
||||
background: EPC_SOFT[b],
|
||||
color: bandInk(b),
|
||||
flexGrow: 1.7,
|
||||
transform: "translateY(-3px)",
|
||||
borderColor: "#14163d",
|
||||
boxShadow: "inset 0 -12px 16px rgba(0,0,0,.10)",
|
||||
}
|
||||
: {
|
||||
background: bandTint(b),
|
||||
color: "#3f4757",
|
||||
flexGrow: 1,
|
||||
borderColor: "transparent",
|
||||
}
|
||||
}
|
||||
onClick={() => setBand(b)}
|
||||
>
|
||||
{b}
|
||||
|
|
@ -395,10 +403,9 @@ export function NewScenarioJourney({
|
|||
aria-pressed={off}
|
||||
className={`inline-flex items-center gap-2 rounded-full border px-3.5 py-1.5 text-[13px] transition ${
|
||||
off
|
||||
? "border-transparent text-indigo-200 line-through"
|
||||
: "border-gray-200 bg-white hover:border-gray-400"
|
||||
? "border-gray-200 bg-gray-100 text-gray-400 line-through hover:border-gray-300"
|
||||
: "border-gray-200 bg-white text-brandblue hover:border-gray-400"
|
||||
}`}
|
||||
style={off ? { background: "linear-gradient(135deg,#20234f,#14163d)" } : undefined}
|
||||
onClick={() =>
|
||||
setExcluded((prev) => {
|
||||
const nextSet = new Set(prev);
|
||||
|
|
@ -408,7 +415,7 @@ export function NewScenarioJourney({
|
|||
})
|
||||
}
|
||||
>
|
||||
<span className={off ? "text-indigo-300" : "font-bold text-brandmidblue"}>
|
||||
<span className={off ? "text-gray-400" : "font-bold text-brandmidblue"}>
|
||||
{off ? "✕" : "✓"}
|
||||
</span>
|
||||
{measuresDisplayLabels[k]}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,18 @@ export const EPC_SOFT: Record<string, string> = {
|
|||
};
|
||||
const DARK_TEXT_BANDS = new Set(["C", "D", "E"]);
|
||||
|
||||
/** Letter ink with adequate contrast on the band's full colour (dark on the light mid-bands, white on the saturated ends). */
|
||||
export function bandInk(band: string): string {
|
||||
return DARK_TEXT_BANDS.has(band) ? "#333a1d" : "#fff";
|
||||
}
|
||||
|
||||
/** The band colour as a light tint — used for unselected picker chips so every letter can share one dark ink. */
|
||||
export function bandTint(band: string, alpha = 0.22): string {
|
||||
const hex = (EPC_SOFT[band] ?? "#9ca3af").slice(1);
|
||||
const [r, g, b] = [0, 2, 4].map((i) => parseInt(hex.slice(i, i + 2), 16));
|
||||
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
||||
}
|
||||
|
||||
export const GOAL_DESCRIPTIONS: Record<string, string> = {
|
||||
[PORTFOLIO_GOALS.EPC]: "Bring every property up to a target band.",
|
||||
[PORTFOLIO_GOALS.CO2]: "Cut carbon as far as possible, within any budget you set.",
|
||||
|
|
@ -49,7 +61,7 @@ export function BandChip({ band, size = 34 }: { band: string; size?: number }) {
|
|||
height: size,
|
||||
fontSize: size / 2,
|
||||
background: EPC_SOFT[band],
|
||||
color: DARK_TEXT_BANDS.has(band) ? "#333a1d" : "#fff",
|
||||
color: bandInk(band),
|
||||
boxShadow: "inset 0 -10px 14px rgba(0,0,0,.12)",
|
||||
}}
|
||||
>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue