/** * The City / State / ZIP row, sized in ONE place because two places is how it went wrong. * * MEASURED IN A BROWSER AT 390px, on a real record, before this existed: * * patient card editor flex City 54 State 80 ZIP 112 * register-patient dialog grid-3 City 98 State 80 ZIP 98 * * Two layout mechanisms, two sets of numbers, and neither based on how much text a field holds. In the * narrower of the two, `Burlington` had `clientWidth` 53 against `scrollWidth` 88 - so a receptionist * correcting an address could not read the value they were correcting, while ZIP had 112px for five * digits. * * THE ALLOCATION, and every part of it is a content decision rather than a taste one: * - CITY takes the slack, because it is the only one of the three whose length is unbounded. * - ZIP is fixed and small. `52601-1234` is the longest it can hold, which needs about 90px at this * font - so 6rem, not the 7rem it had. * - STATE's width does not come from here at all; it is a custom property inside `StateSelect`, * because an ID-scoped rule in `index.css` outranks any width class. See that component. * * THE ROW WRAPS RATHER THAN SQUEEZES, and that is the fix for the clipping. Three fields do not fit on * one line at phone width without starving City, so below roughly 20rem of row the State+ZIP pair drops * to a second line and City takes the full width. Driven by the SPACE AVAILABLE, not by a viewport * breakpoint - the same row appears in dialogs of different widths at one viewport size, which is * exactly how these two drifted apart. */ /** The row itself. Wraps, so a cramped container costs a line rather than costing City its text. */ export const ADDRESS_ROW_CLASS = "flex flex-wrap gap-2"; /** * City. `min-w-0` is still load-bearing: a flex item defaults to `min-width:auto`, so an input keeps * its intrinsic width and pushes the row past the viewport instead of shrinking. The `min-w-[7rem]` * floor is what makes the row WRAP instead of squeezing - without a floor there is nothing to fail to * fit, and City simply gets smaller until it is unreadable, which is what it did. */ export const ADDRESS_CITY_CLASS = "h-[var(--ak-field-height)] min-w-[7rem] flex-1 text-sm"; /** * State and ZIP travel together, so a wrapped row keeps them on one line. A grid, not flex: the * ID-scoped text-input rule gives ZIP `width: 100%`, which in flex took its ~190px intrinsic width and * pushed ZIP past the register dialog's edge; here it fills the 6rem track. */ export const ADDRESS_STATE_ZIP_GROUP_CLASS = "grid shrink-0 grid-cols-[auto_6rem] gap-2"; /** State. Height only - the WIDTH comes from `StateSelect`'s own custom property. */ export const ADDRESS_STATE_CLASS = "h-[var(--ak-field-height)] text-sm"; /** ZIP. Fixed at 6rem: enough for `52601-1234`, and no more. */ export const ADDRESS_ZIP_CLASS = "h-[var(--ak-field-height)] w-24 shrink-0 text-sm";