diff --git a/messages/de.json b/messages/de.json index 10302180e..24ebef389 100644 --- a/messages/de.json +++ b/messages/de.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Körperumriss", "injectionSitePickerAriaLabel": "Injektionsstelle auswählen", "injectionSiteRecommendedAriaLabel": "{site} – empfohlene nächste Stelle", + "injectionSiteLegendAriaLabel": "Legende der Markierungen", + "injectionSiteLegendRecommended": "Empfohlene nächste Stelle", + "injectionSiteLegendLastUsed": "Zuletzt verwendete Stelle", "siteAbdomenLeft": "Bauch, unten links", "siteAbdomenRight": "Bauch, unten rechts", "siteAbdomenUpperLeft": "Bauch, oben links", diff --git a/messages/en.json b/messages/en.json index d8fe8ad56..e0832a629 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Body outline", "injectionSitePickerAriaLabel": "Injection site picker", "injectionSiteRecommendedAriaLabel": "{site} — recommended next site", + "injectionSiteLegendAriaLabel": "Marker legend", + "injectionSiteLegendRecommended": "Recommended next site", + "injectionSiteLegendLastUsed": "Last used site", "siteAbdomenLeft": "Abdomen, lower left", "siteAbdomenRight": "Abdomen, lower right", "siteAbdomenUpperLeft": "Abdomen, upper left", diff --git a/messages/es.json b/messages/es.json index 0c78edc61..0537ec304 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Silueta del cuerpo", "injectionSitePickerAriaLabel": "Selector de sitio de inyección", "injectionSiteRecommendedAriaLabel": "{site}: sitio siguiente recomendado", + "injectionSiteLegendAriaLabel": "Leyenda de marcadores", + "injectionSiteLegendRecommended": "Próximo sitio recomendado", + "injectionSiteLegendLastUsed": "Último sitio usado", "siteAbdomenLeft": "Abdomen, inferior izquierdo", "siteAbdomenRight": "Abdomen, inferior derecho", "siteAbdomenUpperLeft": "Abdomen, superior izquierdo", diff --git a/messages/fr.json b/messages/fr.json index 81d7b018b..ef6105d02 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Silhouette du corps", "injectionSitePickerAriaLabel": "Sélecteur de site d'injection", "injectionSiteRecommendedAriaLabel": "{site} — prochain site recommandé", + "injectionSiteLegendAriaLabel": "Légende des repères", + "injectionSiteLegendRecommended": "Prochain site recommandé", + "injectionSiteLegendLastUsed": "Dernier site utilisé", "siteAbdomenLeft": "Abdomen, en bas à gauche", "siteAbdomenRight": "Abdomen, en bas à droite", "siteAbdomenUpperLeft": "Abdomen, en haut à gauche", diff --git a/messages/it.json b/messages/it.json index 61a22b2af..aaff084e5 100644 --- a/messages/it.json +++ b/messages/it.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Sagoma del corpo", "injectionSitePickerAriaLabel": "Selettore del sito di iniezione", "injectionSiteRecommendedAriaLabel": "{site} — prossimo sito consigliato", + "injectionSiteLegendAriaLabel": "Legenda dei segnaposto", + "injectionSiteLegendRecommended": "Prossimo sito consigliato", + "injectionSiteLegendLastUsed": "Ultimo sito utilizzato", "siteAbdomenLeft": "Addome, basso a sinistra", "siteAbdomenRight": "Addome, basso a destra", "siteAbdomenUpperLeft": "Addome, alto a sinistra", diff --git a/messages/pl.json b/messages/pl.json index 1c83dc2f0..7d2b48da2 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -1035,6 +1035,9 @@ "injectionSiteBodyOutlineAriaLabel": "Sylwetka ciała", "injectionSitePickerAriaLabel": "Wybór miejsca iniekcji", "injectionSiteRecommendedAriaLabel": "{site} — zalecane następne miejsce", + "injectionSiteLegendAriaLabel": "Legenda oznaczeń", + "injectionSiteLegendRecommended": "Zalecane następne miejsce", + "injectionSiteLegendLastUsed": "Ostatnio użyte miejsce", "siteAbdomenLeft": "Brzuch, dolny lewy", "siteAbdomenRight": "Brzuch, dolny prawy", "siteAbdomenUpperLeft": "Brzuch, górny lewy", diff --git a/src/components/medications/injection-site-picker.tsx b/src/components/medications/injection-site-picker.tsx index 423edccf4..2f7d90364 100644 --- a/src/components/medications/injection-site-picker.tsx +++ b/src/components/medications/injection-site-picker.tsx @@ -19,9 +19,12 @@ import { * The silhouette is an INLINE SVG so it inherits the app's theme tokens * (`currentColor` + CSS variables) and tints correctly in light/dark and * across the zinc/Dracula palettes with no raster asset and no luminance - * key. The body is traced to the proportions the iOS client calibrated - * against (see `.planning/ios-coord/v0.12-…-injection-bodymap-coords.md`) - * so dots land on the same anatomy on both platforms. + * key. The body is hand-authored to the proportions the iOS client + * calibrated against (see `.planning/ios-coord/v0.12-…-injection-bodymap-coords.md`): + * an oval head + short neck, sloped shoulders, a torso that tapers to the + * waist and flares to the hips, arms held slightly out to mid-thigh with + * simple hands, and separated legs ending in feet — so dots land on the + * same anatomy on both platforms. * * `viewBox="0 0 100 200"` (aspect ≈0.5). `SITE_COORDS` is expressed on * the same viewBox; the recommended-next ring, the last-used marker and @@ -142,61 +145,139 @@ export function InjectionSitePicker({ - {/* Anatomical front-of-body silhouette — one continuous outline - traced to the iOS reference proportions (upright, arms slightly - out, plain oval head). Filled with the soft wash + a hairline - stroke so it reads as a calm medical illustration. */} - + strokeLinecap="round" + > + {/* Head + neck — a clean oval head with small ears, a short + tapering neck blending into the trapezius line. */} + + {/* Ears */} + + + {/* Torso + legs — one outline. From the neck the shoulders slope + out to the top of the arms, dive into the armpit notch, run + down the torso side (narrowing to the waist, flaring to the + hips), split at the crotch into two legs ending in feet, and + mirror back up the right side. The arms are drawn separately + (below) so there is a clean underarm gap and the arm anchors + sit on real arm mass, not on the torso edge. */} + + {/* Left arm — held slightly out, tapering from the shoulder to a + rounded hand around hip height, with a clear underarm gap from + the torso. The arm anchor (≈x26 @ y72) sits squarely on the + upper-arm mass: at that height the arm spans ≈x21–31, so the + dot is centred on the muscle. */} + + {/* Right arm — mirror of the left. */} + + {/* Feet — small forward-pointing shapes anchoring each leg so the + figure reads as a full body rather than truncated calves. */} + + + {/* Centre + waist references — barely-there guides that help the eye read the abdomen quadrants. Kept low-alpha so they never @@ -211,9 +292,9 @@ export function InjectionSitePicker({ strokeOpacity="0.35" /> )} - {/* Last-used marker — a soft solid ring so the user can see + {/* Last-used marker — a solid amber ring so the user can see where they injected most recently at a glance, distinct - from the dashed recommendation ring. Suppressed on the - active selection (the filled dot already says "here"). */} + from the dashed primary recommendation ring. The amber tone + matches the dialog legend and reads in light + dark. + Suppressed on the active selection (the filled dot already + says "here"). */} {isLastUsed && !disabled && ( )} {isRecommended && !isActive && !disabled && ( diff --git a/src/components/medications/log-injection-site-dialog.tsx b/src/components/medications/log-injection-site-dialog.tsx index 2b8ee7753..132983fc2 100644 --- a/src/components/medications/log-injection-site-dialog.tsx +++ b/src/components/medications/log-injection-site-dialog.tsx @@ -109,12 +109,57 @@ export function LogInjectionSiteDialog({ {t("medications.logInjectionSiteNoneAvailable")}

) : ( - + <> + + {/* Marker legend — explains the two body-map annotations so the + dashed primary ring and the amber ring read at a glance. The + swatches mirror the picker's own marker strokes exactly. */} +
    +
  • + + {t("medications.injectionSiteLegendRecommended")} +
  • +
  • + + {t("medications.injectionSiteLegendLastUsed")} +
  • +
+ )}