# W2-FS-3 — vitals card composes specialty + context packs; modes; round I/O (FE + BE)

Read _COMMON.md first. Review rows: A #31 #32; B #55; D N15, G9, I6, bugs 2-3. Prototype: resolveLayout `vitals:` composition (line 572), vitals renderer (~803-811), F field catalog lines 413-421 (waist/hip/whr, lmp/ga/fundal/fhr/urine_alb, rr/avpu/pain/o2/io/news2), SPECIALTIES vitalsPack (495, 516), CONTEXTS.inpatient.vitalsPack (530); screenshot 08_gyn.png shows «باقة نسا وتوليد» inside the vitals card.

## Goal
«العلامات الحيوية» = the 8 core vitals + the specialty pack + the context pack, all in the same card, saved to the same observation store, with computed read-only fields. Today the card is capped at 8 (`features/clinic/services/clinic-vitals.service.ts:~30` VITALS_WHITELIST; `features/clinic/encounter/vitals-panel/vitals-panel.component.*`), while ClinicObservationDefinitionSeeder (Modules/Clinic/database/seeders/ClinicObservationDefinitionSeeder.php:~88-112) already seeds nut_waist/nut_hip, gyn_fundal_height/gyn_fetal_hr, rr/consciousness/pain/intake/output/news2 that nothing renders.

## Tasks
1. **BE:** expose the pack definitions per clinical type + context: e.g. `GET clinic/encounters/{id}/vitals` (or the existing vitals read) returns `pack: [{code, label_ar, label_en, unit, input:'number'|'select'|'yesno'|'text', options?, min/max/normal range, computed?:true, group:'specialty'|'context'}]` + current values; the save endpoint accepts those codes (validated against the definitions) and stores them through the same ObservationService/VitalsService path the core vitals use (find D1 observations code: Modules/Clinic … ObservationService, VitalsService). Packs: nutrition → waist, hip, WHR (computed = waist/hip, 2 dp, risk flag by gender: F>0.85, M>0.90); gyn_ob → LMP (date, read from/written to the same place the GYN pregnancy module keeps LMP — reuse, don't duplicate; if LMP is a history answer, show it read-only with a link instead), GA (computed from LMP, read-only), fundal height (cm), FHR (/min), urine albumin (select: سلبي/أثر/+/++/+++); inpatient/day_case context → RR, AVPU/ACVPU (select), pain 0-10, on O₂ (yes/no), intake ml / output ml, NEWS2 (computed read-only via ComputedRegistry). Missing definitions: add to the seeder (idempotent) and run it on dev. Tests for read + save + validation + computed.
2. **FE vitals panel:** render core 8 + a «باقة <التخصص>» subsection + «باقة الإقامة» subsection (like the prototype screenshot: a small titled row inside the same card), same input style, computed fields read-only with their flag colour. Inputs: `[clinicalType]`, `[context]` (or pass the encounter) from the shell (visit-shell.component.html ~243 — coordinate: W1-FE-1 owns that file right now; add only the input bindings at the very end of your task in ONE small edit and say so in your report). New input `mode: 'full'|'compact'|'readonly'` (compact = one-row summary chips with an expand, readonly = no inputs) — the dental/nutrition read-only uses can use readonly.
3. **Inpatient round I/O (bug 3):** features/hospital/nursing/vital-round.component.* — add intake ml / output ml inputs (BE NursingController already accepts intake_ml/output_ml), shown with the running balance if the BE gives it.
4. Classic consultation screen also uses the vitals panel — packs must appear there too for that type (that's desired), and nothing breaks when no pack exists.

Run ng build at the end. Do not deploy, do not commit.

## Out of scope
visit-shell.component.* (except the single binding edit), picker files, nutrition board files (W2-FE-6), dental files.
