- the ADM badge gains a trailing key glyph (ADM ✓ ⚿ / ADM ✗ ⚿) when the
preset matching the equipped card's ICCID carries an ADM key; the four
tooltip states cover key/no-key x verified/not-verified
- new gray SCP80/SCP81 markers after ADM, shown only when that preset has
all SCP80 fields (KIc/KID, SPI1/SPI2, counter, KIc/KID keys) or the SCP81
PSK pair filled in; hidden without a card session, a matching preset or
the fields, never color-coded
- cardsScp80Complete/cardsScp81Complete/cardsAdmPresent/cardsMatchedPreset
helpers; cardsRender reuses the SCP81 predicate
- tests: ADM four-state badge, marker show/hide, predicate whitespace
handling, header markup order; help EN/RU updated; SW cache simple-v201
- new #state-indicator-iccid span between the card image and the ADM badge;
shows the EF.ICCID digits of the equipped card (hidden without a card
session or when the ICCID is unreadable, cleared when the server is lost)
- pysimUpdateIccidIndicator() mirrors the ADM badge pattern (no rewrite when
the value is unchanged); wired into pysimCardStateUpdate() and
pysimSetServerAvailable()
- indicator/card_state tests for show/hide and markup order;
SW cache simple-v197
- The card create/edit form gets a From card button next to the ICCID
field: it fills the field with the equipped card's EF.ICCID. It uses the
availability model through a new 'card-iccid' requirement - enabled only
while /api/status reports a connected card with a readable iccid; with a
card but no readable ICCID the tooltip says so, otherwise the usual
'insert and equip' hint applies. The last status ICCID is kept in
_pysimCardIccid (cleared on disconnect) so the click needs no round-trip.
- Duplicate ICCID refusal now compares normalized values via
cardsNormIccid/cardsFindDuplicateIccid (digits, spaced digits and raw EF
hex all identify the same card), skips the row being edited, ignores an
empty field, and names the conflicting preset in the alert (translated).
- i18n RU: From card -> 'С карты', duplicate/unreadable alerts.
- Tests: cardsFindDuplicateIccid across formats and edit-skip,
cardsIccidFromCard fill + alert path, form wiring guards, _pysimCardIccid
tracking in the card-state harness, card-iccid availability gating in the
indicator harness. 261 Python + 400 frontend tests green.
- Docs: help EN+RU Cards field table, READMEs, AGENTS. SW otaman-v185.
- the SVG artwork occupies only ~46% x 63% of its 183x183 canvas, so
the 18px render showed ~8x11px of ink; 30px roughly doubles the
visible glyph while staying under the 32px h1 line-height, so the
header row height is unchanged
- guard test asserts the inline size stays within the 24-32px budget;
SW cache v112 -> v113.
- the dot carries its own title (Connecting... / No server connection),
matching the wrapper tooltip; it is cleared when the sim icons replace
the dot
- tests assert the dot title in both server states and its removal once
the server is up; SW cache v110 -> v111.
- #state-indicator is now a wrapper with a dot plus an 18px dark:invert
image; no new compiled Tailwind classes (h-4/w-5 are not in the
prebuilt CSS), so sizing uses an inline style and the header height
is unchanged
- gray dot while probing, red dot when the server is unreachable;
server up -> nosim.svg, animated sim_anim.svg while equipping, and
sim.svg when the card is equipped (`_pysimEquipping` tracked from
status.equipping, refreshed on every 2s poll)
- i18n reuses existing strings; tests for all five states, dot color
transitions and the markup; SW cache v109 -> v110.