Changelog

Semver release history for the Aurum AAR. Source of truth: aurum/CHANGELOG.md.

All notable changes to the Aurum design system are documented here.

Format follows Keep a Changelog.

[0.3.29] - 2026-07-30

Added

  • AurumIcons.Navigation.CaretBold{Up,Down,Left,Right} (+ Filled). Their masters have been sitting in the canonical icon sheet (5130:35416) without code counterparts, so the sheet↔catalog contract was one-sided. Single-weight in Figma, so both weights resolve to the same drawable — the same convention the existing Caret family uses. The heavier caret is what CaretCircleRight is built from, which is where consumers keep needing it.
  • Catalog gallery now lists the whole Caret family. CaretUp/Down/Left/Right shipped in code but were never added to IconGallery, so they were invisible in the catalog; listed now alongside the new bold set.

Fixed

  • AurumSectionHeaderAction.Link now renders neutral-subtle, matching its Figma master (5442:462). The link action was styled identically to the text action — Title/XS-SemiBold in interactive.textPrimaryNormal (brand purple) with a 20dp iconPrimaryNormal chevron — so "View All / See More" links shouted as loudly as the section title and were indistinguishable from a brand text-button. The sheet's action link layer specifies Body/S-Medium in interactive.textNeutralSubtle with a 12dp interactive.iconNeutralSubtle chevron; the component now follows it. TextAction is unchanged and remains the brand-emphasis option. Consumer impact: every existing Link action becomes grey and one step smaller — intended, but visible. aurum-ios mirrors this in 0.2.3.

[0.3.28] - 2026-07-21

Changed

  • AurumPhoneNumberInput displays the number grouped XXXXX XXXXX. A display-only VisualTransformation inserts a single space after the fifth digit (matching the Figma), while the stored value stays raw digits — public API unchanged (value: String is still the un-spaced number). Also widened the gap between the country-code divider and the number to 16dp (Figma 4904:2076).

[0.3.27] - 2026-07-21

Fixed

  • AurumPhoneNumberInput type, colour, and leading-slot order now match the Figma master (4904:2439). The entered number + placeholder render at Title/M-Bold (20sp) instead of the inherited bodyLMedium (16sp); the +91 country code is Title/S-Bold in textDefaultSubtle (was bodyLRegular in textDefaultNormal); and the leading slot is ordered flag → +91 → divider (was flag → divider → +91), so the divider trails the country code and separates the prefix from the number. Consumers should render the India flag at 36×24.
  • AurumTextField placeholder now matches the field's text size and renders in the correct disabled grey. The placeholder hard-coded bodyLMedium, and because AurumText falls back to textDefaultNormal when given no explicit colour, it painted the placeholder near-black regardless of the M3 placeholder-colour config. It now inherits the field's textStyle (so e.g. the phone field's 20sp placeholder matches its value — no size jump on first keystroke) and is explicitly coloured textDefaultDisabled. Affects every field that shows a placeholder.

[0.3.26] - 2026-07-20

Removed

  • AurumIcons.Navigation.CaretCircleUp/Down/Left/Right (+ Filled) — removed to restore the 1:1 sheet↔catalog contract. Their master components were deleted from the Figma "Component Icons" sheet (verified via the components API and the sheet subtree — no replacement nodes exist), and the current homefeed designs use Chevron icons exclusively (458 chevron instances, zero carets in the FINAL frames). Ghost entries also crashed make icons-import (null REST response for deleted nodes) and failed every Code Connect publish with "node not found". Removes the manifest entries, 8 drawables, 8 catalog vals, and 8 .figma.kt mappings. Consumer migration: jar-android's CaretCirclePill (the only production usage) moves to a disc + AurumIcons.Navigation.ChevronRight composition in the companion jar-android PR. aurum-ios removes the same icons in the same sitting.

[0.3.25] - 2026-07-20

Fixed

  • AurumTextField homes the caret at the end of a programmatically-set value. The field used the String-based BasicTextField, which seeds the text selection at position 0, so any externally-provided value — a pre-filled phone number on the login screen, an autofill / number-hint suggestion — placed the caret *before* the first character, forcing users to move it to the end before editing. Rebuilt on a TextFieldValue-backed buffer that seeds and re-homes the caret to the end whenever the incoming value changes from outside; live typing keeps its own caret. AurumPhoneNumberInput, AurumAmountInput, and AurumSearchField inherit the fix; public API is unchanged (value: String / onValueChange: (String) -> Unit).

[0.3.24] - 2026-07-16

Changed

  • **Renamed the Silver palette visual.indigo*visual.silver*** (and the backing primitive Indigo*Silver*), matching the design-system rename in Figma (_primitives + visual_colors both use silver now). Values are unchanged — a pure rename. visual.indigo* shipped only in 0.3.23 with a single internal consumer, so this corrects the name before it spread. Use Aurum.colors.visual.silver50..1000.

[0.3.23] - 2026-07-16

Added

  • Aurum.colors.visual.indigo50..1000 — the Silver brand palette. A new chromatic family, the cool blue-grey Silver analogue to how visual.yellow* is Gold (from the Figma "Silver Indigo" palette section). Silver surfaces (the Silver locker/tab, silver savings cards) previously had no brand palette and mis-borrowed Blue/Neutral/Purple. Backed by new AurumPalette.Indigo50..1000 primitives + IndigoA50..A200 alpha tiers, and by real colors/indigo/* variables added to the Figma _primitives + visual_colors collections so the token source stays faithful. Purely additive — no existing token changed.

[0.3.22] - 2026-07-15

Fixed

  • AurumGlobalHeader renders a URL avatar full-bleed in the profile pill. profileContent was placed at its intrinsic size, centered in the 44 dp pill, so a URL-loaded photo showed as a small inset with a wide ring of background around it. The slot now fills the pill's inner circle (inside the 1 dp border, clipped circular), so a full-bleed image reads as the avatar. The default profileIcon glyph path is unchanged (still a 20 dp icon). Callers pass a fillMaxSize image with ContentScale.Crop — no manual sizing or clipping.

[0.3.21] - 2026-07-08

Changed

  • AurumTextField matches the Figma anatomy — no Material floating label. The label was passed into M3 OutlinedTextField's label slot, so it rested inside the box and floated up into a notch cut in the top border on focus, and the placeholder stayed hidden until focused. Per the component sheet the label is a *static* Title/S-SemiBold caption above the field (greyed when disabled) and the placeholder shows whenever the value is empty. Rebuilt on BasicTextField + OutlinedTextFieldDefaults.DecorationBox: continuous 1.5 dp border (borderWidth.md; lg on focused error/success), default/disabled border interactive.borderNeutralHighlighted (was one shade too faint), container bgSurfaceLowContrast (bound white, was transparent), readonly bgSurfaceMidContrast fill + borderSurfaceMidContrast border, value/placeholder bodyLMedium, support text bodySMedium. AurumPhoneNumberInput, AurumAmountInput, and AurumSearchField inherit the fix; public API unchanged.

Added

  • AurumTextField(isLoading = …) — trailing loading spinner per the Figma loading state; error / success states now auto-surface their trailing status icon when the caller supplies no trailing. AurumPhoneNumberInput delegates to the shared affordance.

[0.3.20] - 2026-07-08

Added

  • AurumBanner(windowInsets = …) — M3 app-bar convention: insets are padded *inside* the tone background, so a top-anchored band paints its colour under the status bar while content stays clear. Pass WindowInsets.statusBars for window-edge banners; defaults to none.

Changed

  • AurumBannerHost pushes instead of overlaying. Enter/exit now animates expandVertically/shrinkVertically (plus the existing slide + fade), so a host placed in the layout flow (first child of the root Column / a top slot the chrome is constrained below) smoothly pushes the content beneath it down and releases it — the structural-band behaviour used by the app-wide connectivity strip. Overlay placements keep working.
  • AurumChip state colours match the Figma component set (4446-701) exactly. Selected fills the 9% brand wash (borderPrimaryMuted — the spec's bound fill) instead of white, with borderPrimaryDefault border; the Neutral default border is now type-aware (Other → hairline borderNeutralMuted, ActionborderNeutralHighlighted); Neutral pressed fills borderNeutralDefault (Neutral50) per the spec binding.

Fixed

  • AurumChip disabled chips no longer double-dim — the extra 0.40 alpha layer is gone; the disabled tokens (bgNeutralDisabled / textNeutralDisabled / borderNeutralMuted) already encode the muted look and the Figma disabled variants are opacity 1.

[0.3.19] - 2026-07-06

Added

  • Modifier.aurumInnerShadow(color, blur, offsetX, offsetY, shape) — Figma INNER_SHADOW for Compose, which has no inner-shadow primitive. Clips to shape and draws the shape's *inverse* ring behind a setShadowLayer paint, so only the shadow bleeding inward is visible — the same construction Figma uses. Positive offsetY casts from the top edge, negative from the bottom. First consumer: the DS-swipe gold hero panel (yellow800 @ 24%, blur 16, offsetY −4), Figma 10103:18130.

[0.3.18] - 2026-07-06

Added

  • aurumShadow(alphaMask: Brush?) — Figma derives a drop shadow from the node's *rendered* alpha, so a surface whose fill fades to transparent needs its shadow to fade with it. Pass the fill brush and the shadow is masked through it (saveLayer + BlendMode.DstIn); null keeps the plain outline shadow. Built for fade-out cards (e.g. the transactions empty-state CTA card, Figma 8498:34146).

Changed

  • AurumButton primary press is dimensional, not tonal. Pressed no longer swaps the radial fill for bgPrimaryHighlighted + 4 dp muted ring — the fill and top-lit rim stay constant, and on full-width primaries the cue is the purple/800 hard shadow dropping while the button sinks 2 dp onto it (ripple suppressed there; inline primaries keep the ripple as their only cue). Product call (2026-07-06): press feedback should read as 3D depth, never a colour shift — deviates from the Figma pressed variant, pending a design rebind.

Fixed

  • aurumShadow no longer paints under the node itself (Figma drop shadows are showShadowBehindNode=false): the blurred silhouette used to bleed a tint wash through translucent/gradient fills. The node's own area is now clipped out of the shadow draw; opaque surfaces render identically.

[0.3.17] - 2026-07-06

Changed

  • AurumButton rebuilt as a custom composable — no Material 3. The old material3.Button wrapper drew its border inside the Surface's own shape-clip, shaving the top-lit rim's outer edge and leaving a visible seam ("doubled" upper edge) on the radial primary. Replaced with a Row + clickable(ripple) + Aurum-painted surface and a 48 dp touch target; public API is unchanged (zero call-site changes). Every state now matches the Figma component exactly — primary: default (radial purple600→400 + white 60→0% rim), pressed (purple800 fill + borderPrimaryMuted 4 dp ring), disabled (neutral 9% + textPrimaryDisabled), loading (solid purple500 + white 20→0% rim + spinner), progress (purple100 track + purple500 fill); secondary outline/pressed/disabled; tertiary grey/pressed-ring/disabled. This also unblocks bespoke press interactions (e.g. a 3D press) that M3 constrained.

Fixed

  • AurumLinkButton — pressed state now shifts the label to textPrimarySubtle (purple300) with no background, per the Figma link-button spec (was a static colour with a ripple).

[0.3.16] - 2026-07-03

Fixed

  • AurumChip — Black variant filled bgStaticWhite* (white-on-white text); now bgStaticBlack*. Every variant gains its spec 1 dp stroke (neutral borderNeutralHighlighted; pressed/black/disabled borderNeutralMuted; brand borderPrimaryMuted). Small-chip icons 14 dp.
  • AurumBadge — intense-emphasis content colour text*Subtle (tints) → text*Inverse (white on solid tone) across all six roles.
  • AurumToast — drop shadow added on every variant via aurumShadow (nearest tint highRaised @18% vs spec #000 @16% — no exact token, flagged); brand stroke follows the spec binding bgPrimarySubtle; label→close gap 4 dp.

[0.3.15] - 2026-07-03

Added

  • Token resync to live Figmafeedback/*/subtle rebound from white to real tints (green/red/orange 400, blue/purple 300, neutral 500; text/neutral/intense 600→900), interactive/background/*/faded 100→50 shades, interactive/border/{information,primary}/disabled → 9% alpha neutral. Typography atoms 3xl=40 / 4xl=48 / lineHeight 3xl=48 / ExtraBold=800 and the new Aurum.type.num3XL (Inter Bold 40/48). Export JSONs mirrored to live. The borderRadius re-index (xl 16→12) is deliberately HELD pending design confirmation.
  • AurumIcons.Media.PlayCircle (89th glyph) + knockout-aware icon importer: <rect>/<circle>/<ellipse> converted to path data and dark-base + white-overlay glyphs merged into single tintable even-odd paths (CaretCircle* restyle).
  • Component spec fingerprintsmake component-audit diffs every component's live Figma master against committed baselines (design-tokens/component-specs/); weekly component-drift.yml CI files an issue on drift; RECONCILIATION.md tracks code↔spec status (full 2026-07-03 sweep recorded).

Fixed

  • AurumButton primary matches the restyled Figma master — elliptical radial fill purple600→400 (bottom-centre anchor), 1 dp top-lit white 60→0% rim, and a purple/800 hard shadow (y=2) only when isFullWidth (inline primaries are flat, per the Figma variants). Pressed is a real state: flat highlighted fill + 4 dp borderPrimaryMuted ring; tertiary's ring is now pressed-only.
  • AurumIconCaretCircleRight Code Connect re-pointed to the re-created master 7085:15336 — un-breaks the Code Connect publish that failed on every release tag.

[0.3.14] - 2026-07-02

Added

  • AurumSmoothCornerShape + Aurum.shape.smooth(radius, smoothing) — continuous-curvature ("squircle") rounded rectangle, the Compose analogue of Figma's cornerSmoothing. Backed by AndroidX graphics-shapes (RoundedPolygon.rectangle + CornerRounding): each corner renders as three cubic curves (circular centre + edge-blending flanks). smoothing maps Figma's 0..1 slider, default 0.6 (Figma's "iOS" preset); 0 degrades to the Outline.Rounded fast path. Path cached per size, so scroll-feed safe. New dependency: androidx.graphics:graphics-shapes:1.0.1.
  • Figma plugin 0.7.0 — cornerSmoothing decode. analyzeShape now reads the node's cornerSmoothing: uniform-radius nodes with smoothing > 0.05 emit Aurum.shape.smooth(N.dp) (with an explicit smoothing = …f argument when it deviates from the 0.6 preset); per-corner-radius nodes with smoothing surface a visible // note: drift marker instead of silently dropping it.

Fixed

  • AurumNavBar CenterQr dome — three drifts from Figma 5575:14061: the dome's radial was a circular (0.5, −1) × 2 approximation (now the plugin-decoded elliptical recipe: centre (0.5, 0), radii 2.96 × 0.91, rotated −26°); the QR glyph rendered ~22 dp of drawn content in a 27 dp box (icon paths cover 19.5/24 of the viewport — the box is now 33 dp so the glyph measures the design's 27 dp); and the selected-icon gradient reached full pink/50 at the glyph bottom while the design's gradient handles extend 1.64× past it (the ramp now ends at the 61% purple/500 → pink/50 blend, shared by selected tabs and the QR glyph).

[0.3.13] - 2026-07-01

Added

  • aurumRadialBrush — elliptical / transform-aware overload aurumRadialBrush(vararg stops, centerFraction, radiusFractionX, radiusFractionY, rotationDegrees). The circular overload uses a single radiusFraction = fraction · max(w, h), which collapses a Figma GRADIENT_RADIAL with unequal/rotated axes to a circle — so on a wide-short surface (e.g. a 308×58 card) the glow washes out flat. The new overload gives the horizontal and vertical extents independent radii (+ rotation) by stretching the shader via a localMatrix, so the glow fades across the height as designed. The circular overload is unchanged.

Fixed

  • Figma plugin radialGradientParams took the gradient centre as T⁻¹(0, 0.5) — an axis *endpoint* (e.g. (0.5, −1), a full card-height above the surface) — instead of the true centre T⁻¹(0.5, 0.5), and collapsed the ellipse to one radius. It now emits the true centre plus radiusFractionX/Y + rotationDegrees (principal axes via the 2×2 SVD of the conjugate half-axes), so the plugin's Compose recipe reproduces elliptical Figma radials faithfully instead of a flat circle.

[0.3.12] - 2026-07-01

Fixed

  • AurumOtpInput — fixes two regressions from the 0.3.11 masking approach. (1) The system's selection/cursor teardrop handle leaked over the cells: cursorBrush = Transparent hides only the cursor *line*, while the handle is drawn from LocalTextSelectionColors.handleColor (Aurum purple) — so a purple teardrop rendered on cell 1 after a re-tap. (2) The keyboard did not reopen after a back-press dismissed it — requestFocus() is a no-op on a still-focused field and SoftwareKeyboardController.show() can't restart a dismissed session. The field now suppresses selection handles entirely (transparent LocalTextSelectionColors; the active-cell underline is the sole caret cue, correct for a masked input), and the tap-catcher gates on WindowInsets.isImeVisible: keyboard up → just re-focus (no flicker); hidden (first tap / after back) → cycle focus (clear → re-pin caret to end → re-request) to fire a fresh focus-gain that reopens the IME without stranding the caret at offset 0. Device-verified on the catalog OTP demo: no teardrop, keyboard reopens after back, and input always appends. Internal-only; the public API is unchanged. Visually identical — Roborazzi baselines unaffected.

[0.3.11] - 2026-06-30

Fixed

  • AurumOtpInput — the 0.3.10 caret fix was insufficient (PFPD-99 reopened). Pinning the TextFieldValue selection to TextRange(text.length) only corrects the caret on onValueChange, but a bare tap on a filled cell reaches the hidden BasicTextField's built-in tap-to-position gesture — which repositions the caret with no text change — so the next digit still overwrote the tapped cell. A transparent tap-catcher overlay now sits above the hidden field and only calls requestFocus(), so taps can never reach the field's positioning gesture: the caret stays pinned to the end and input always appends. Device-verified on the catalog OTP demo (tap cell 1 → type → digit appends at the end). Internal-only; the public API (value: String / onValueChange: (String) -> Unit) is unchanged. Visually identical — Roborazzi baselines unaffected. (Trade-off: long-press-to-paste on the cells is intercepted; OTP paste continues to work via the keyboard's SMS-autofill chip / auto-read.)

[0.3.10] - 2026-06-29

Fixed

  • AurumOtpInput — tapping the cell row no longer snaps the caret to the first cell (PFPD-99). The hidden field used the BasicTextField(value: String, …) overload, which carries no selection, so the clickable row's requestFocus() could land the caret at offset 0 and the next typed digit overwrote the first cell instead of appending. It now drives the field with a TextFieldValue whose selection is pinned to TextRange(text.length) on both external value changes (SMS autofill / resend reset) and onValueChange, so input always continues from the last entered digit. Internal-only — the public API (value: String / onValueChange: (String) -> Unit) is unchanged.

[0.3.9] - 2026-06-22

Fixed

  • AurumPhoneNumberInput — leading slot now matches the Figma master (file YvIxqu2oTlM6UnkL0OloHc, node 4904-2455): the country flag was pinned to the rounded border (the M3 leadingIcon slot gives a full-bleed flag image no optical inset, so it visually clipped against the field edge), and the divider sat *after* the country code (flag +91 │ number) instead of between the flag and code. Now: a start inset keeps the flag clear of the border, and the order is flag │ +91 number. The divider is also dropped when no flag is supplied (so the code never leads with a stray rule). Visual-only; the public API is unchanged.

[0.3.8] - 2026-06-18

Fixed

  • AurumPhoneNumberInput — now renders the trailing validation icon and loading spinner from its Figma component (file YvIxqu2oTlM6UnkL0OloHc, node 4904-2455), reaching parity with AurumAmountInput (which got this in 0.3.7 — the phone input was missed in that pass). isSuccess shows AurumIcons.Status.SuccessFilled (tinted interactive.iconPositiveNormal), isError shows WarningFilled (tinted interactive.iconNegativeNormal), and a new isLoading param renders an AurumLoader — matching the Figma state x validationState variants. Previously isSuccess / isError only recoloured the border (no icon) and there was no loading state at all. Additive, non-breaking. New PreviewAurumPhoneNumberInputLoading; Code Connect maps state=loading -> isLoading.

[0.3.7] - 2026-06-09

Added

  • Responsive width-scaling in AurumTheme (AurumWidthScaling) — every .dp / .sp under the theme now scales by k = (smallestScreenWidthDp / 360).coerceIn(1.0, 1.15), so a layout authored at the 360dp Figma reference keeps its proportions on wider phones instead of looking "airy" (a 411dp phone → ×1.14; verified on-device — a raw-dp home-feed card grew height ×1.14 with width unchanged). Implemented as a LocalDensity.density override at the single AurumTheme choke point — zero call-site churn, no .sdp/.ssp — that preserves fontScale, so the user's accessibility text-scaling still composes on top. Up-only clamp (never shrinks below the reference → touch targets stay safe; caps growth so tablets/foldables hand off to WindowSizeClass rather than ballooning). Nested AurumTheme is idempotent via the new LocalAurumBaseDensity (re-scales the same base, never ). New widthScaling param on AurumTheme (default AurumWidthScaling.Default; Disabled renders pixel-exact to Figma; fixed() pins a factor for previews). Catalog Scaling gallery demonstrates the spectrum on one device. Additive API (optional param + new class), non-breaking — renders identically at 360dp — but default-on, so every Aurum surface scales up on >360dp phones by design. Replaces the temptation to reintroduce .sdp/.ssp; see README → *Sizing*.

Changed

  • AurumTextField — additive textStyle param (defaults to bodyLRegular). Lets specialised inputs set the entered-value typography; existing callers are unaffected (byte-identical default).

Fixed

  • AurumAmountInput — aligned to the Figma component (file YvIxqu2oTlM6UnkL0OloHc, node 5080-261) after a layer-by-layer audit. The entered amount now renders in numXL (Inter Bold 28) and the ₹ prefix in numL (Inter Bold 24) — previously the value fell back to bodyLRegular (Inter 16 Regular) and the ₹ used displayLBold (the serif Frank Ruhl Libre, wrong family). The gold-grams suffixText is now bodyMRegular (14, was bodyLRegular 16) and inset from the field's trailing edge (was flush). The success / error validation states now render the trailing status icon (AurumIcons.Status.SuccessFilled tinted interactive.iconPositiveNormal / WarningFilled tinted interactive.iconNegativeNormal), matching the Figma validationState variants. Verified against the Figma state×validation variants via Roborazzi.
  • AurumBottomSheet carries the width-scale into the sheet window — a ModalBottomSheet hosts its content in a new window that re-provides the platform LocalDensity from the system config, which dropped AurumTheme's width-scale (the Aurum token locals still inherited; the platform density did not). The sheet now re-applies the enclosing scaled density to its content and drag handle, so sheet content matches the page behind it — verified on-device (a sheet tile's chevron measured 42 px unscaled → 48 px after the fix, matching the page's k=1.14). Raw material3.ModalBottomSheet / Dialog used directly in feature code need the same one-liner — prefer AurumBottomSheet.
  • AurumBottomSheet no longer forces consumers to opt in to ExperimentalMaterial3Api — its sheetState default was rememberModalBottomSheetState(...), and for a @Composable that default is evaluated at the caller's site, so every feature-code caller had to add @OptIn(ExperimentalMaterial3Api::class) — defeating the point of a material-free DS wrapper (it broke the jar-android LightCriticalActionsBottomSheet migration). the sheetState parameter was removed from the public signature — its androidx.compose.material3.SheetState type leaked the experimental opt-in to consumers of the published AAR (a binary consumer doesn't honour the wrapper's @OptIn for an *exposed experimental type*). The state is created internally now; callers drive the sheet by toggling whether it is composed, plus onDismiss (no caller passed sheetState). Programmatic state control can return later via an Aurum-owned wrapper. Source-compatible for every existing caller.

[0.3.6] - 2026-06-02

Added

  • AurumPageHeader.colorScheme — new AurumPageHeaderColorScheme { OnLight; OnDark } param (default OnLight). OnDark flips the title, subtitle, and all icon tints to the theme-invariant surface.iconStaticWhiteNormal / surface.textStaticWhiteNormal tones so a Page Header can sit over a dark hero backdrop (pair with containerColor = Color.Transparent). Mirrors AurumGlobalHeaderColorScheme 1:1. contentColor becomes an optional text override (Color.Unspecified default defers to the scheme); icon tints now follow the scheme instead of a hardcoded interactive.iconNeutralNormal (which contentColor never actually reached). Additive, non-breaking — OnLight renders byte-identically to before. New PreviewOnDark. Unblocks the jar-android Instant Save hero toolbar (back + title over a dark BE-image hero).

[0.3.5] - 2026-05-31

Added

  • AurumPill — a compact, label-first status / token element (quieter than AurumChip). Mirrors the Figma "Pills" set (file YvIxqu2oTlM6UnkL0OloHc, node 5891-802): type = Rounded / Rectangular / WithTags, state = default / selected (Figma focus) / disabled, optional leading/trailing icons, and a tag ribbon for WithTags. Scratch (sibling to AurumChip), full @AurumFigma + Code Connect binding, catalog PillsDemo. Closes one of the three Figma-coverage gaps.
  • AurumProgressBar — a determinate linear progress bar (8dp pill track + primary indicator). Mirrors the Figma "Progress Bar - Linear" set (node 5934-846): progress (0f..1f), optional label header (Figma shownHeader) and trailing % (Figma shownProgress). Scratch, in feedback/, @AurumFigma + Code Connect, catalog ProgressDemo. Closes the second Figma-coverage gap.
  • AurumSegmentedProgressBar — discrete N-segment progress. Mirrors the Figma "Progress Bar - Segmented" set (node 5889-2361): type = Bars / Bubbles (numbered-checkpoint stepper), intent (6: Default + 5 feedback tones), filled/total counts, optional header + %. Scratch, in feedback/, @AurumFigma + Code Connect, catalog demo. Closes the third and final Figma-coverage gap — every ✅ Ready-for-dev Figma component now has code.
  • 12 feedback inverse tokensfeedback.{icon,text}.{primary,information,positive,negative,notice,neutral}.inverse, all resolving to Neutral0 (#FFFFFF). White icon/text content for feedback rendered on a tonal-intense (saturated) surface — the third intensity alongside intense/subtle, and the exact gap that forced the toast/snackbar white-on-tone workarounds. Added to FeedbackColors on the icon + text axes only (background + border keep 2 intensities, matching Figma). Surfaced by auditing live Figma variables against the committed token layer (plugin-API drift detection) — design had added them since the last export. Additive, non-breaking.
  • Figma token export artifacts re-synced to live Figmadesign-tokens/figma-export/*.json brought back in line with the live variable set: the 12 inverse entries added to theme.onLight; colour primitive leaf-names de-prefixed (colors/blue/blue_500colors/blue/500 — a Figma-side cleanup, values unchanged); typography fontFamily keys lowercased (Displaydisplay, Primaryprimary) and the orphaned lineHeight/4xs dropped; Boolean primitive added. Zero residual drift, re-verified by replaying the plugin-API audit against the refreshed files. The cosmetic renames don't touch the generated Kotlin.
  • AurumBanner + AurumBannerHost — a persistent, top-anchored, full-bleed tonal status strip (offline / downtime / account warnings) and its caller-driven host. It is the persistent counterpart of the transient AurumToast — same 6-tone tonal language and per-tone status glyphs (feedback.* subtle fill over opaque surface.bgPageBase + matching intense content) — but structural rather than floating: square corners, full-bleed fillMaxWidth, a 1dp bottom hairline, no clip. Supports an optional inline text action (e.g. "Retry") and an optional trailing dismiss ✕ (onDismiss / dismissible); state banners are non-dismissible and persist until the condition resolves. AurumBannerHost animates a single banner in from the top (slideInVertically { -it }) with no auto-dismiss timer (vs. the toast host's queue + timer) — the caller owns show/dismiss. No Figma node yet — proposal-grade, to reconcile when design produces the spec. Catalog BannerDemo (all tones, with/without action, dismissible, host). Code Connect stub (AurumBanner.figma.kt, url pending design) + classification.md rows added per the add-component ritual.
  • 11 icons synced from the Figma "Component Icons" frame (node 5130:35416): Navigation.Caret{Up,Down,Left,Right} + Navigation.CaretCircle{Up,Down,Left,Right} (single-weight; distinct from the existing Chevron set), Content.Star, Content.ChartBar, and Commerce.Bank (each line + fill). The catalog is now 88 icons / 176 drawables. Imported via tooling/icons/import_from_figma.py (ICON_MANIFEST extended) + Code Connect bindings regenerated. Also refreshed 6 existing glyphs the design team refined (action_qr_code, content_broadcast_filled, media_replay, user_nek).

Removed

  • AurumSnackbar (internal component/scaffold/) — deleted. It paired surface.bgSurfaceHighContrast (#DCDDE3, a *light* surface) with surface.textDefaultInverse (#FFFFFF, white) and rendered white-on-light-grey (illegible), and it had no Figma counterpart. The design system's feedback primitive is the Figma-backed AurumToast (a light, tone-coloured strip — file YvIxqu2oTlM6UnkL0OloHc, node 6014:2621), not a dark M3 snackbar.

Changed

  • AurumLoader — added optional label + labelPosition (right / bottom) to match the Figma Spinner's shownLabel variants, and added the previously-missing Code Connect binding + @AurumFigma (node 4530-2084). It was wrongly tagged code-only; it's a Figma-backed component (the size / color Figma axes were already covered by its continuous Dp / Color params).
  • Renamed AurumTopAppBarAurumPageHeader (and AurumTopAppBarAction/AurumTopAppBarButtonAurumPageHeaderAction/AurumPageHeaderButton; file AurumPageHeader.kt). The component's Figma name is "Page Header" (file YvIxqu2oTlM6UnkL0OloHc, set 4826:1058), and "Page Header" is the industry convention for a content-level title-and-actions row (Atlassian, GitHub Primer, Polaris, Ant Design, Salesforce). The old Material-derived name wrongly implied it wraps material3.TopAppBar — which it explicitly does not (it's a scratch component). Clean rename, no deprecation alias (Aurum is pre-release / in active light-theme migration); the single jar-android consumer migrated in lockstep.
  • AurumPageHeader primary button synced to Figma (4826:1058, chip 5431:2985) — the snackbarHost slot renders the canonical AurumToast (Neutral tone, Large) instead of the removed AurumSnackbar. The public snackbarHostState: SnackbarHostState API is unchanged (non-breaking); snackbarHostState.showSnackbar(...) now surfaces the legible, Figma-faithful toast. M3 SnackbarData carries no tone, so screen-level snackbars are Neutral — for tone-specific feedback (Error/Success/…), use AurumToastHost + showToast(tone = …) directly.
  • AurumToast leading-icon override — new optional leadingIcon: ImageVector? = null param (default → the tone's status glyph). Supply to swap the glyph — still tinted to the tone's content colour + sized by the toast — or showLeadingIcon = false to hide it. A controlled override (not a free @Composable slot) so the DS keeps tint/size consistent; lets consumers (and the snackBar() migration) keep a bespoke icon without losing the tonal default.
  • AurumTopAppBar primary button synced to Figma (4826:1058, chip 5431:2985) — now 36dp tall with a 1dp interactive.borderPrimaryMuted ring, 12dp horizontal padding, and a labelLMedium (12/16 Medium) label (was 32dp, no border, 8dp, titleXSSemiBold 14/20). Every other Page Header slot (variant axes, title titleSSemiBold, subtitle, back chevron, 56dp/16dp layout, icons) already matched the design.

Fixed

  • AurumToast now renders opaque — composites each tone's subtle (low-alpha) fill (e.g. feedback.bgNegativeSubtle = #D8320917, 9% alpha) over surface.bgPageBase (opaque white) inside the component. Previously only the low-alpha tint was painted, so a toast floating over app content — rather than the white Figma page the design was drawn on — let the backdrop bleed through. It now reads as the intended solid pastel on any surface.
  • AurumToastHost applies a consistent 16dp margin — the default renderer now insets the toast by space.s5 (16dp) on the sides and the bottom (was horizontal-only), so it floats with the design's 16dp gap on any screen. Callers supply only window insets (e.g. navigationBarsPadding()); no per-screen bottom offset needed.
  • Error toast iconleadingIconFor(Error) now uses the filled (Navigation.CloseFilled, the fill variant of Icons/X) instead of the plain Navigation.Close (✕), which duplicated the trailing dismiss ✕. Matches the Figma Error toast (node 6014:2621); the other five tones were already correct.

[0.3.4] - 2026-05-21

Added

  • AurumButton.progress param — optional Float? (0f..1f) that renders the auto-advance progress state from the Figma button state=progress variant (file YvIxqu2oTlM6UnkL0OloHc, node 4692:1074). When non-null the button paints a faded-primary track (interactive.bgPrimaryFaded) with a primary fill (interactive.bgPrimaryDefault) that grows to progress, swaps the M3 container to transparent, and dims the label/icon to interactive.textOnPrimaryDisabled. null (default) keeps the normal fill — non-breaking, additive. Drive progress from a countdown for CTAs that proceed on their own (e.g. onboarding auto-advance). New PreviewProgressVariants.

Fixed

  • AurumGlobalHeader OnDark pill fidelity — restored translucent radial fill + linear-gradient border + linear-gradient divider per the Figma Global Header component (file CXq7IVmAMMc7qCKT82GrM9, node 7174:11139). The previous OnDark arm rendered every pill as SolidColor(interactive.bgStaticWhiteFaded) with a baked Color.White.copy(alpha = 0.09f) hairline and Color.White.copy(alpha = 0.18f) divider — flat and tokenless. Now matches the Aurum Compose Figma plugin emission verbatim: pill fill is aurumRadialBrush(bgStaticWhiteFaded@α0.18 → bgStaticBlackFaded@α0.18, center=(1.55, -0.56), radius=1.47), border is aurumLinearBrush(180°, borderNeutralMuted@α0.09 → borderSurfaceHighContrast → borderNeutralMuted@α0.09), divider is aurumLinearBrush(90°, borderNeutralMuted@α0.04 → borderSurfaceHighContrast@α0.4 → borderNeutralMuted@α0.04). HeaderPillColors.border and dividerTint widened from Color to Brush (and the field renamed divider) to carry the gradients — internal type, no public API impact. OnLight arm visually unchanged (the existing solid border is wrapped in SolidColor(…)). Consumers that render the header with colorScheme = OnDark (e.g. the jar-android home feed) pick up the canonical translucent-glass treatment automatically.

[0.3.3] - 2026-05-19

Added

  • AurumGlobalHeader.colorScheme param — new AurumGlobalHeaderColorScheme sealed type (OnLight, OnDark). Default OnLight preserves the existing pill treatment; OnDark swaps every pill background to a solid translucent-white wash (interactive.bgStaticWhiteFaded), border to a faded white hairline, and icon + text tints to the iconStaticWhiteNormal / textStaticWhiteNormal / textStaticWhiteSubtle tones. Use OnDark when the header sits on a dark hero backdrop (e.g. the home-feed locker zone); pair with containerColor = Color.Transparent so the underlying backdrop reads through. New PreviewOnDarkLivePrice covers the dark path. Internal refactor: a private HeaderPillColors data class threads the resolved tone set into every sub-component (ProfilePill / SingleIconPill / RewardsAndNotificationsPill / LiveBuyPricePill / PillFrame), replacing the previous in-line pillSheen() brush + hardcoded iconDefaultNormal / textDefaultNormal reads. No call-site change required for existing consumers.

Changed

  • Typography scale rebuilt as a 1:1 mirror of the Figma Typography page (YvIxqu2oTlM6UnkL0OloHc#5077:1488). The old hand-curated scale (20 tokens) had multiple sizes (11sp, 18sp, 40-72sp) and weights (Inter Medium in Title family, SemiBold at 14sp Label) that don't exist in Figma's catalog. The new scale ships 44 composites across 5 Figma-aligned families: Display (Frank Ruhl Libre S/M/L/XL/XXL × Bold/Medium), Title (Inter XS/S/M/L/XL/XXL × Bold/SemiBold), Body (Inter XS/S/M/L/XL × Regular/Medium), Label (Inter S/M/L × Bold/Medium), Num (Inter Bold XS/S/M/L/XL/XXL). Naming follows <family><Size><Weight> (e.g. numXL, bodyMMedium, titleSSemiBold). All ~210 internal Aurum usages migrated to the new tokens; M3 MaterialBridge.kt remapped to the new scale.
  • Breaking — every removed legacy token has a clear replacement. Migration map:

| Removed | Replacement | Notes |

|---|---|---|

| bodyLarge / bodyMedium / bodySmall / bodyXSmall | bodyLRegular / bodyMRegular / bodySRegular / bodyXSRegular | Same value, Figma-aligned naming |

| bodyB3 | bodySRegular | Was duplicate of bodySmall |

| captionMedium (11sp) | bodySRegular (12sp) | 11sp not in Figma scale; 1sp upsize |

| titleT1 (Inter Medium 16/24) | bodyLMedium | Title family is Bold/SemiBold only in Figma; this was Body-shaped |

| titleT2 (Inter Medium 14/20) | bodyMMedium | Same reasoning |

| titleT1.copy(SemiBold) | titleSSemiBold | Exact value preserved |

| titleT2.copy(SemiBold) | titleXSSemiBold | Exact value preserved |

| titleT2.copy(Bold) | titleXSBold | Exact value preserved |

| labelL1 (SemiBold 14/20) | titleXSSemiBold | 14sp not in Label scale (Label tops at 12sp); SemiBold lives in Title |

| labelL1.copy(Bold) | titleXSBold | Exact value preserved |

| labelL2 (SemiBold 12/16) | labelLMedium | SemiBold→Medium weight shift (no Inter SemiBold 12/16 in Figma) |

| headingH6 (Inter Bold 14/20) | titleXSBold | Same value, Figma-aligned naming |

| headingSmall (display 18/22) | displaySBold | 18sp not in Figma; size 16sp + weight Bold |

| headingMedium (display 20/24) | displayMBold | Line height 24→28 + SemiBold→Bold |

| headingLarge (display 24/28) | displayLBold | Line height 28→32 + SemiBold→Bold |

| headingXLarge (display 32/36) | displayXXLBold | Line height 36→40 + SemiBold→Bold |

| heading2XLarge (display 40/44) | displayXXLBold | 40sp not in Figma; size 32sp |

| displayXLarge (72sp) / displayLarge (64sp) / displayMedium (56sp) / displaySmall (48sp) | displayXXLBold (32sp) | None in Figma; size capped at scale max 32sp |

Roborazzi baselines will shift wherever a visible-value change applies (line-height fixes on Display, SemiBold→Bold on Display family, captionMedium 11→12, labelL2 SemiBold→Medium, hand-tuned Display 40-72sp clamped to 32sp). The migration is mechanical 1:1 for >80% of call sites.

  • **Token drift fix — interactive.borderNeutral* realigned.** borderNeutralDefault Neutral300→Neutral50, borderNeutralHighlighted Neutral400→Neutral200, borderNeutralDisabled Neutral200→NeutralA50 (translucent wash). Matches Figma. Visible on every neutral-bordered Aurum control — borders ~5 shades lighter than before.
  • Typography fix — headingH6.lineHeight 14sp → 20sp. Matches Figma's Title/XS-Bold spec (verified via plugin API: fontSize 14, lineHeight 20 PIXELS, Inter Bold); fixes collapsed leading on wrap.
  • AurumTransactionListCard realigned with Figma. Corner radius shape.lgshape.xl on both outer wash and inner card (8dp → 16dp; designers updated the spec). Status icons remapped: Error Status.Warning (exclamation) → Navigation.CloseFilled (X-in-circle, matches Figma Icons/X at 5311:823); Pending Status.Pending (clock) → Status.Warning (exclamation-in-circle, matches Figma Icons/Warning at 5308:802). All glyphs now match the canonical component instances verified via figma.getNodeByIdAsync().

[0.3.2] - 2026-05-14

Changed

  • AurumBottomSheet close button removed. The onClose: (() -> Unit)? parameter is gone from both AurumBottomSheet and the private StrictPageHeader; the top-right X icon is no longer rendered. Figma 5564:43216 shows the canonical bottom sheet component (6002:939) with only the drag handle + title + bottom CTA — no close affordance. Dismissal is now exclusively via drag-handle / scrim / system-back. Source-incompatible for any caller that was passing onClose; the sole in-tree consumer (TransactionV2FilterBottomSheet in jar-android) never set it. KDoc updated; Spacer, AurumIconButton, AurumIcon, and AurumIcons imports dropped from the file.
  • AurumBadge Painter overload now ships MCP-readiness KDoc. The Painter-flavoured overload was missing all three required tags (@AurumIntendedUse, @AurumDo, @AurumDont); the published manifest would have surfaced a stub on hover. The full block is mirrored verbatim from the ImageVector overload so both shapes ship identical identity / axes / dos / don'ts.
  • AurumTabRow preview annotation aligned. The lone @Preview(name = "tablet-wide(640dp)", widthDp = 640) on PreviewTabRowFourTabsTablet is now @AurumPreview so the catalog preview sweep + screenshot pipeline pick it up alongside every other Aurum preview. The redundant androidx.compose.ui.tooling.preview.Preview import is dropped.
  • docs/components/classification.md refresh. Table was ~6 months stale at 30 rows; now lists every public composable (29 scratch / 13 wrap). Reclassified AurumChip, AurumCheckbox, and AurumNavBar from Wrap to Scratch (source confirms none of them imports material3.*); renamed AurumRadioAurumRadioButton and AurumBottomNavBarAurumNavBar to match actual file names; moved AurumTab from the Wrap half to the Scratch half. Added rows for AurumLinkButton, AurumOtpInput, AurumAmountInput, AurumStepper, AurumSectionHeader, AurumRadioGroup, AurumCheckboxGroup, AurumGlobalHeader, AurumTransactionListCard, AurumLabel.
  • Icon slots inside Aurum surfaces now inherit the surface's content color via LocalContentColor. AurumIcon's default tint resolves to LocalContentColor.current.takeOrElse { Aurum.colors.surface.iconDefaultNormal }, so icons in an AurumButton leading/trailing slot (and any future Aurum surface that provides LocalContentColor) auto-tint to match the label — no more manual tint = Aurum.colors.interactive.textOnPrimaryNormal boilerplate at each call site. AurumButton now wraps its content Row in CompositionLocalProvider(LocalContentColor provides labelColor) so slotted icons follow the button's variant + enabled state. Callers passing an explicit tint are unaffected.
  • AurumPreviewSurface defaults to no content padding. Previously hardcoded a 16 dp (Aurum.space.s5) inset on every preview, which clipped full-bleed components (locker cards, top app bars, hero gradients) into looking like they had a white margin. New signature accepts contentPadding: Dp = 0.dp; component previews that want breathing room pass an explicit value (e.g. AurumPreviewSurface(contentPadding = Aurum.space.s5) { … }). Source-incompatible only for callers that were relying on the inset; trailing-lambda usage (AurumPreviewSurface { … }) compiles unchanged.
  • AurumTopAppBar back icon now matches Figma source. The leading back-button glyph defaults to AurumIcons.Navigation.ChevronLeft (Figma node 5426:1363, exactly what the canonical Page Header component_set 4826:1058 renders) instead of the previously hardcoded AurumIcons.Navigation.ArrowLeft. Implementation had drifted from the Figma source; this realigns them. Visible on every existing call-site (catalog NavigationDemo, jar-android transaction-detail hero, etc.) — a one-glyph swap with no API change for callers that took the default.
  • AurumTopAppBar.backIcon slot. Added an optional backIcon: ImageVector = AurumIcons.Navigation.ChevronLeft parameter so callers can override the leading glyph (e.g. AurumIcons.Navigation.Close on modal-style surfaces) without losing the 32×40 dp wrapper or interactive/icon/neutral/normal tint. New PreviewWithBackIconClose covers the override path; BackIconButton made glyph-agnostic.
  • AurumTopAppBar icon wrappers honour Figma's 32×40 dp bounds. BackIconButton and ActionIconButton previously inflated their wrappers to a 48×48 dp Material minimum-touch-target box that centered the visible 32×40 dp icon inside, which (a) shifted each glyph 8 dp inward of where Figma places it (Icon_wrapper 4826:1086 is w-[32px] h-[40px]) and (b) cumulatively pushed the page title 16 dp right of its design position. Both wrappers now collapse to a single 32×40 dp clickable box, matching Figma exactly. Net effect: tighter leading and trailing slots flush with the 16 dp container padding, page title visually anchored at its Figma-spec 60 dp from the screen left edge.
  • Compose BOM bumped 2026.01.002026.04.01. Re-resolves compose-ui from 1.10.1 to 1.11.0, fixing a Layout Inspector crash that prevented live component-tree inspection of the catalog app. material3 is pinned outside the BOM at 1.3.2 and is unaffected.

Added

  • AurumToast + AurumToastHost — toast feedback family (component/feedback/). Mapped to Figma wrapper (6014:2621). AurumToast is a scratch composable: rounded 8 dp container (borderRadius.large) with 1 dp feedback/border/<tone>/subtle border, feedback/background/<tone>/subtle wash (Neutral falls back to surface/background/surface/lowcontrast + surface/border/surface/lowcontrast), per-tone leading status glyph (Selection.CheckFilled for Neutral / Brand; matching Status.<Tone>Filled for Success / Warning / Info; Navigation.Close for Error per Figma's Icons/X reference at node 6107:432), label rendered at Body/M-Medium (Inter 14 / 20, weight 500) tinted with feedback/text/<tone>/intense, and a trailing close AurumIconButton wired through onDismiss. Six tones (Neutral / Brand / Success / Error / Warning / Info) × two sizes (Small fixed 48 dp single-line ellipsis · Large vertical-padded multi-line wrap up to 3 lines) = 12 variants matching the Figma component set. showLeadingIcon parameter hides the leading glyph for text-only status. Wraps its label in CompositionLocalProvider(LocalContentColor provides toneColor) so any nested AurumIcon inherits the tone tint without per-call boilerplate. Ships Code Connect mapping (AurumToast.figma.kt) with state and size axes wired to AurumToastTone / AurumToastSize enums, MCP-readiness KDoc tags (@AurumIntendedUse + 3 × @AurumDo + 3 × @AurumDont), and 3 @AurumPreview previews (small all-tones · large all-tones · showLeadingIcon = false). AurumToastHost is the codebase-only orchestration glue (no Figma counterpart): a Stable AurumToastHostState with a Mutex-serialised single-toast slot plus a suspend fun showToast(label, tone, size, duration): AurumToastResult API that resumes when the strip is dismissed (timer / X tap / explicit dismiss()). AurumToastDuration.{Short=4s, Long=10s, Indefinite} drives the auto-dismiss timer; rememberAurumToastHostState() is the canonical entry point. AurumToastHost wraps AnimatedVisibility with a 220 ms slide-up + fade enter and 180 ms slide-down + fade exit, preserving lastVisible across the exit animation so the strip keeps rendering while it slides out. Default toast slot renders an AurumToast with fillMaxWidth + 16 dp horizontal padding; callers can override for custom width / placement. Catalog ToastDemo extended with a live host section: 6 trigger buttons (one per tone) + a "Queue 3 in a row" button proving the FIFO mutex queue.
  • AurumGlobalHeader — persistent top bar for top-level destinations (component/navigation/). Mapped to Figma Global Header (5252:2274). Sealed AurumGlobalHeaderRightContent with two variants: Default (optional Support pill + optional Rewards/Notifications pill) and LivePrice (live gold-buy-price pill on a dark surface + optional Rewards/Notifications pill). Each pill is 44 dp tall, 22 dp corner radius, 1 dp interactive/border/neutral/muted border, with a subtle aurumRadialBrush sheen overlay matching Figma's SVG-encoded radial fill. Profile pill accepts either an ImageVector glyph (default AurumIcons.User.User) or a caller-supplied profileContent slot — the slot pattern lets consumers render URL-loaded avatars (Glide / Coil) without dragging an image-loading dep into Aurum. Ships Code Connect mapping (AurumGlobalHeader.figma.kt), MCP-readiness KDoc tags (@AurumIntendedUse + 3 × @AurumDo + 3 × @AurumDont), and 6 @AurumPreview previews covering all variant combinations. Catalog NavigationDemo extended with three live examples.
  • AurumTab + AurumTabRow — tab navigation family (component/navigation/). Mapped to Figma _Tabs (5430:3115) and GroupRoot (5531:795). AurumTab is a scratch composable (Foundation Box + Row + selectable, role = Role.Tab) with an optional leading ImageVector icon at Aurum.iconSize.xl (24 dp) and a label rendered at Title/XS-Bold (14/20 sp, Bold 700) with TextOverflow.Clip. Selected uses interactive/text/primary/normal + interactive/icon/primary/normal; unselected uses interactive/text/neutral/subtle + interactive/icon/neutral/subtle. No disabled variant — Figma's _Tabs set has none; callers omit unavailable destinations. AurumTabRow uses a SubcomposeLayout probe pass to measure each tab's natural width, then auto-fits or scrolls: when tabCount × max(widestNatural, 100.dp) ≤ viewport it wraps material3.PrimaryTabRow and tabs flex to share the row equally (matching Figma's two/three-tab flex-[1_0_0] variants); otherwise it wraps material3.PrimaryScrollableTabRow and pins each tab to the computed width via LocalAurumTabWidth (matching Figma's four-tab fixed-100px+scroll variant and gracefully extending to 5 + tabs). Indicator is borderWidth/lg (2 dp) interactive/border/primary/default; bottom divider is borderWidth/sm (1 dp) interactive/border/neutral/highlighted. Both ship Code Connect mappings (AurumTab.figma.kt, AurumTabRow.figma.kt) and 10 @AurumPreview previews including a 640 dp tablet tile and a 5-tab scroll demo. Catalog TabGallery added under Navigation with two/three/four/with-icons sections.

Manifest

  • Manifest jumps from 28 → 33 components: AurumToast, AurumToastHost, AurumGlobalHeader, AurumTab, AurumTabRow (5 new). AurumBottomSheet was already in the manifest — this cycle ships its first Code Connect mapping plus the close-button removal. Code Connect mappings ~158 → 178: 5 new component mappings (AurumToast, AurumGlobalHeader, AurumTab, AurumTabRow, AurumBottomSheet) plus 18 new icon mappings (9 pairs: ArrowDownLeft, ArrowUpRight, ChatBubble, Filter, Nek, Phone, Replay, Timer, WhatsApp × line + filled). The 7 drift-fix mappings from PR #22 updated existing files, not new ones. Schema version unchanged ("2"); changes are additive.

[0.3.0] - 2026-05-04

Added

  • AurumCheckbox + AurumCheckboxGroup — multi-select selection family (component/selection/). AurumCheckbox is a tri-state control (AurumCheckState.Unchecked / Checked / Indeterminate) mapped to Figma 5169:1314. Closed enum chosen over Boolean? to avoid null-as-indeterminate ambiguity. Mirrors AurumRadioButton's API: selected, onCheckStateChange, label, subtext, enabled, error, labelPosition (End/Start). The 24 dp box is rendered via Canvas — checked state fills with Aurum.colors.interactive.bgPrimaryDefault and overlays a stroked checkmark; indeterminate fills the box and overlays a centred horizontal bar; error tints both outline and glyph with feedback-negative. AurumCheckboxGroup<T> mirrors AurumRadioGroup<T> but with selected: ImmutableSet<T> and onSelectionChange: (T, Boolean) -> Unit; uses triStateToggleable per row so Indeterminate → Checked advancement is a single tap. Both ship Code Connect mappings (AurumCheckbox.figma.kt at 5169:1314, AurumCheckboxGroup.figma.kt at 5169:1796) plus 8 + 5 @AurumPreview previews. Catalog SelectionDemo extended with single-checkbox and group examples.
  • AurumAmountInput — currency-prefixed numeric input mapped to Figma 5080:261 (component/field/AurumAmountInput.kt). Delegates to AurumTextField for state, validation, helper/error/success text, label plumbing — currency symbol (default ) is rendered in the leading slot using Aurum.type.headingLarge; optional suffixText (e.g. "0.0097 g") sits in the trailing slot. loading = true swaps the trailing slot for an inline AurumLoader(size = Aurum.iconSize.lg) and forces read-only. Caller is responsible for formatting both value and suffixText (locale + currency conventions are app-level concerns) — flagged in KDoc. Numeric keyboard via KeyboardOptions(keyboardType = KeyboardType.Number). 8 @AurumPreview previews + Code Connect.
  • AurumNavBar + AurumNavBarItem — bottom navigation family (component/navigation/). Mapped to the layout component_set at Figma 5575:14226. AurumNavBar is a slot-based composable taking an ImmutableList<AurumNavBarItem> (label + line/fill icon pair) plus selectedIndex, onSelect, and a layout: AurumNavBarLayout. AurumNavBarLayout is a sealed interface exposing four data variants — Standard3, Standard4, Standard5, CenterQr5(onQrClick) — each carrying an itemCount enforced via require() at composition time. CenterQr5 takes 4 items (the QR action is rendered by the layout, not surfaced as an item) and inserts the raised QR FAB between items 1 and 2 using AurumIcons.Action.QrCode. The per-cell renderer AurumNavBarCell is private — exposing it would only invite cells without a parent bar. 6 @AurumPreview previews (one per layout + selected-state variants) + Code Connect. Catalog NavigationDemo extended with all 4 layouts running interactive selectedIndex state.
  • AurumTransactionListCard — opens the Cards family (component/card/, new package). Mapped to Figma 5576:19749. Status-tinted card (AurumTransactionStatus.{Success, Error, Pending}) composing AurumSurface + AurumText + AurumIcon. Outer wash uses Aurum.colors.feedback.{positive, negative, notice}/subtle; status badge icons map to the new AurumIcons.Status.{Success, Warning, Pending} glyphs landed in v0.2.1; amount and helper-text colours match the wash family. Caller hands in pre-formatted strings for dateText and amount — no locale or currency handling inside (consistent with AurumAmountInput). helperText and leadingIcon are optional. 7 @AurumPreview previews + Code Connect. Standalone CardDemo composable wired into the catalog showcase as a new "Cards" section between Navigation and Chips.

Changed

  • tooling/gallery/generate.py — registered the card family in FAMILY_LABELS so the gallery site renders the new component/card/ family with a proper "Cards" heading rather than falling back to the raw directory name.
  • AurumLinkButton Code Connect mapping validated against Figma 4784:1286 ("Component 1") — the existing AurumLinkButton.figma.kt already targets the right node, no changes needed. The Figma component name is misleading ("Component 1") but the underlying variant=link button axis maps cleanly.

Manifest

  • Manifest jumps from 24 → 28 components: AurumAmountInput, AurumCheckbox, AurumCheckboxGroup, AurumNavBar, AurumTransactionListCard (5 new) — AurumNavBarItem is a public data class but not a composable, so it doesn't count. Code Connect mappings 150 → ~158. Schema version unchanged ("2"); changes are additive.

Known gaps

  • Icons/NEK (Figma 5566:781) is referenced by Jar's nav bar item set but not yet imported into AurumIcons. Catalog NavBar previews use placeholder icons (Home, Gift, Document, etc.) so compile + render succeed. Action: design to confirm the canonical NEK glyph node, then add an IconEntry to tooling/icons/import_from_figma.py:ICON_MANIFEST and re-run make icons-import.
  • Icons/Check still resolves to a single-weight glyph (5308:800); Icons/Check at 5480:5047 remains an empty/orphaned component in Figma (see v0.2.1 ghost-component note in add-an-icon.md). No action.

[0.2.1] - 2026-05-04

Added

  • 11 new Figma-derived icons imported via tooling/icons/import_from_figma.py. Sourced authoritatively from the Jar Light Design System file (YvIxqu2oTlM6UnkL0OloHc) by enumerating every Icons/* master component via the Figma REST /v1/files/{key}/components endpoint and diffing against ICON_MANIFEST. Each ships a 24×24 vector drawable + AurumIcons accessor (line + filled) + per-weight Code Connect mapping. Breakdown: AurumIcons.Action.{Minus, MoreHorizontal}, AurumIcons.Content.Image, AurumIcons.Status.{Pending, Warning, Success, Loader}, AurumIcons.Commerce.Withdraw. Single-weight icons (Success, Loader, Selection.Check) reuse the same Figma node id for both weights, producing identical line/fill XMLs while keeping the <Name> + <Name>Filled API contract intact.

Changed

  • AurumIcons.Action.Add and AurumIcons.Action.Overflow now Figma-derived. Previously hand-drawn aurum_ic_action_add.xml and aurum_ic_action_overflow.xml are replaced with imports from Figma's Icons/Plus (5322:1592/5322:1593) and Icons/DotsThreeVertical (5431:2848/5431:2850). Public Kotlin API names unchanged — call sites in AurumButton, AurumIconButton, AurumTextField, and AurumTopAppBar need no edits. Their Filled accessors (AddFilled, OverflowFilled) are now also available.
  • AurumIcons.Selection.Check now Figma-derived. Hand-drawn aurum_ic_selection_check.xml replaced with import from Figma's Icons/Check (5308:800). Used by AurumSwitch for the on-state tick. Initial discovery missed this node because the file's components index points at a stale duplicate (5480:5047) that's an empty/orphaned component; 5308:800 lives near the Warning glyphs and renders fine. Aurum now has zero hand-drawn icons — every icon flows from Figma through make icons-import.
  • Icons/X (Close) fill node updated from 5162:9545311:823. Design moved the X fill variant; the old node returns null from /v1/images. Visual unchanged.
  • tooling/icons/import_from_figma.py cleanup. Removed the special-case blocks at the end of generate_aurum_icons_kt that hand-wired Action.Add, Action.Overflow, and Selection.Check from legacy XMLs — all three are now regular IconEntry rows. Added selection to CATEGORY_ORDER + CATEGORY_DOCSTRINGS. Removed aurum_ic_selection_check.xml from the obsolete-detection exception set.
  • aurum-catalog/.../IconGallery.kt extended with the 11 new icons (Action, Content, Status, Commerce sections) plus a new Selection section showing Check.

Tooling

  • Documented icon ghosts in aurum/docs/workflows/add-an-icon.md. Five Icons/* names appear in the file's /components index but are deleted/orphaned components in Figma — opening their URLs prompts a "Restore component" dialog and /v1/images returns null. They are NOT placeholders awaiting drawings: Icons/InstantSave (5343:1795/1796), Icons/DailySavings (5343:1779/1780), Icons/WeeklySavings (5343:1781/1782), Icons/MonthlySavings (5343:1783/1784), older Icons/Withdraw on 5343:* (superseded by the live pair at 5358:456/5358:465 which is imported as Commerce.Withdraw). The doc explicitly tells future contributors to skip them rather than chase a "fix it in Figma" thread.

Manifest

  • Manifest jumps from 60 → 68 icons. Code Connect mappings 130 → 150. Components count unchanged (24).
  • Schema version unchanged ("2"); changes are additive on the existing icon list.

[0.2.0] - 2026-05-04

Tooling

  • MCP manifest schema v2 — enrichment fields for aurum-mcp v0.3. Bumped tooling/manifest/schema.json schemaVersion enum from ["1"] to ["1","2"] and added four optional, additive fields:
  • component.intendedUse: string — when-to-reach-for prose authored in a new @AurumIntendedUse KDoc tag.
  • component.usage: { do: string[]; dont: string[] } — guardrails authored in @AurumDo / @AurumDont KDoc tags (one bullet per tag instance).
  • component.relatedTokens: string[] — qualified Aurum token names (surface.bgPageBase, spacing.s12, typography.bodyMedium) the component references in its source. Static-analyzed by analyze_token_refs(source) against Aurum.{colors,space,type,radius,borderWidth,elevation,iconSize}.<leaf> accessors.
  • icon.tags: string[] — hand-curated synonyms (Delete[trash, remove, bin, garbage, discard]) sourced from a new aurum/icons/tags.toml file. Powers the synonym-aware aurum_search_icons tool.

All four are absent from v1 manifests and ignored gracefully by older readers. The generator emits schemaVersion: "2" whenever any of them are populated, otherwise stays on "1".

  • @AurumIntendedUse / @AurumDo / @AurumDont KDoc tags authored on all 24 components. Every component in the manifest now carries intended-use prose + Do/Don't guardrails. Counts: 24 × intendedUse, 70 total do entries, 70 total dont entries. The 6 priority components (Chip, Button, RadioButton, RadioGroup, TopAppBar, OtpInput) landed first; this extends coverage to AurumIconButton, AurumLinkButton, AurumTextField, AurumPhoneNumberInput, AurumSearchField, AurumSwitch, AurumBadge, AurumLoader, AurumSkeleton, AurumSectionHeader, AurumSurface, AurumScreen, AurumSnackbar, AurumStepper, AurumDivider, AurumIcon, AurumText, AurumLabel. Tags are stripped from the rendered KDoc body and re-emitted as structured manifest fields.
  • Cross-repo dispatch wired up. Committed .github/workflows/notify-mcp.yml, which fires a repository_dispatch: aurum-content-changed event at Changejarapp/aurum-mcp on every push to main and every release. Drops the manifest-sync latency in aurum-mcp from ≤24 h (cron) to ~1 min. Requires the MCP_DISPATCH_PAT org secret (a fine-grained PAT scoped to aurum-mcp with Actions: read+write).
  • README — manifest pipeline section. Documents how component changes propagate to aurum-mcp end-to-end: pages.yml → manifest URL → notify-mcp dispatch → sync-manifest auto-PR → human merge + release dispatch. Includes the @AurumIntendedUse / @AurumDo / @AurumDont authoring convention and the aurum/icons/tags.toml synonym format with quality-bar guidance.
  • aurum/icons/tags.toml — curated synonyms for all 60 icons across 9 categories (Action / Commerce / Content / Media / Navigation / Selection / Status / System / User). 222 tags total. Format is TOML keyed by category → icon name → tag list.
  • Pages workflow now publishes the manifest. .github/workflows/pages.yml invokes generate.py --emit-manifest build/gallery/data/manifest.json --also-build-gallery --validate on every deploy, exposing https://changejarapp.github.io/aurum-android/data/manifest.json (previously 404). Closes the cross-repo sync gap that left aurum-mcp's drift-check soft-failing on every PR.
  • MCP manifest pipeline. Added tooling/manifest/schema.json defining a JSON Schema for an LLM-consumable Aurum manifest, and extended tooling/gallery/generate.py with --emit-manifest <path> and --validate flags. The same parsers that drive the static gallery now also emit a structured JSON describing every component (KDoc + signature + params + Figma deeplink + Code Connect path + gallery URL), every token (semantic colour / visual palette / spacing / radius / border-width / icon-size / elevation / typography), every icon (with paired line/fill Figma node IDs), every Code Connect mapping, and the full Keep-a-Changelog history. Single source of truth, two render targets — HTML for humans, JSON for agents. Consumed by the new atri-jar/aurum-mcp (and later Changejarapp/aurum-mcp) MCP server. Manifest carries a platforms[] field on each component for forward-compatible cross-platform support (aurum-ios plugs in as a sibling manifest source without restructuring).

[0.1.5] - 2026-04-28

Fixed

  • All 114 icons re-rendered to match Figma. The previous import pipeline used Figma MCP asset URLs that returned only the inner SVG path with viewBox set to the path's tight bounding box (e.g. 7.5 × 13.5 for ChevronRight). Combined with width/height = 24dp, this caused non-uniform stretch and stripped the surrounding 24×24 frame padding — the chevron rendered fat and squashed, every other non-square icon was distorted, and even square-bbox icons lost their intended 2-3 dp inset.
  • Stroke-only icons no longer get a fill. Phosphor regular-weight SVGs carry fill="none" at the <svg> root, cascading to children. The previous import didn't honour the cascade and emitted both fillColor and strokeColor — so e.g. Home rendered as a solid black house instead of the intended outline.

Changed

  • Icon import pipeline rewritten to fetch via the Figma REST API (/v1/images?…&format=svg) using $FIGMA_ACCESS_TOKEN. REST exports include the 24×24 frame and proper SVG-level fill cascade, so the conversion is a clean 1:1 to Vector Drawable. The per-icon COMPOUND_TRANSLATES workaround (previously hand-coded for SpeakerSimpleX) is no longer needed and was removed. The stale figma-icon-urls.json URL manifest was deleted.

Added

  • /icons.html page on the gallery website — every icon's line + fill weights side by side, grouped by category, with live search and click-to-copy on AurumIcons.<Category>.<Symbol>. Reads AurumIcons.kt and inlines each Vector Drawable as currentColor SVG so icons follow the page theme. No longer need to install the catalog APK to scan the icon set.

[0.1.4] - 2026-04-28

Changed

  • AurumChip realigned with the Figma "Action" chip component (YvIxqu2oTlM6UnkL0OloHc, node 4446-701). Adds size (AurumChipSize.Large / Small) and leadingIcon parameters; height tightened to 38 dp Large / 30 dp Small (from 40 dp); padding now asymmetric (12 dp text-side, 8 dp icon-side); inter-element gap reduced 8 → 4 dp; text style varies by size (titleT2 / bodySmall). Existing call sites are unaffected — new parameters default to the prior behaviour. Previews regrouped into Large-trailing / Large-leading / Large-both / Large-text-only / Small / Disabled.
  • Code Connect for AurumChip picks up the new Size axis (largeLarge, smallSmall).

[0.1.3] - 2026-04-27

Added

  • Compose perf guardrails. Detekt + mrmans0n/compose-rules wired in, with the perf/stability rules active (UnstableCollections, MutableStateAutoboxing, MutableParams, MutableStateParam, LambdaParameterInRestartableEffect, Material2). Compose Compiler Metrics enabled on :aurum and :aurum-catalog (build/compose_compiler/).
  • Compose stability CI gate. New verifyComposeStability Gradle task in :aurum fails the build when aurum_release-classes.txt reports more inferred-unstable classes than composeStabilityThreshold (currently 0). Wired into check.yml after detekt.
  • Compose metrics dashboard deployed alongside the gallery at changejarapp.github.io/aurum-android/metrics/, rendered from build/compose_compiler/ via PatilShreyas/compose-report-to-html. Per-PR compose-metrics artifact uploaded by check.yml.
  • Aurum icon set — 57 icons × 2 weights = 114 vector drawables imported from the Figma "Component Icons" frame, exposed under AurumIcons.<Category>.<Name> (and <Name>Filled for the fill variant). 8 categories: Navigation, Action, Content, Media, Commerce, System, Status, User. Ingested by the new tooling/icons/import_from_figma.py script (make icons-import); idempotent re-runs.
  • IconGallery screen in the catalog showing every icon × weight, grouped by category.
  • 114 Code Connect mappings for the new icons under aurum/src/main/kotlin/com/jar/app/aurum/component/icon/figma_connect/AurumIcon*.figma.kt. Auto-published to Figma via the figma-code-connect.yml workflow.

Changed

  • 6 overlapping icons replaced from the Figma source-of-truth: Navigation.BackArrowLeft, Navigation.ChevronForwardChevronRight, Media.LikeContent.Heart (renames; 12 call-site migrations across AurumTopAppBar, AurumChip, AurumSectionHeader, AurumLinkButton, and the catalog gallery). Navigation.Close, Action.Edit, Action.Search kept their names — only their underlying XML content was replaced.
  • 5 components marked codebase-only: AurumSearchField, AurumIconButton, AurumDivider, AurumLoader, AurumSkeleton — verified absent from the Figma library via MCP search. File-level marker added so future Code-Connect audits don't keep flagging them.
  • AurumIcons.kt regenerated from the import script. The 3 legacy entries that lack a Figma counterpart (Action.Add, Action.Overflow, Selection.Check) remain hand-authored under res/drawable/ and are flagged in-file pending design escalation.
  • record.yml now also dispatches pages.yml after committing fresh baselines on main, so the gallery's snapshot embeds redeploy without a manual trigger.

Fixed

  • AurumOtpInput: keyed LaunchedEffect on the completion-boundary transition (value.length == maxLength) instead of value itself, so the coroutine no longer relaunches on every keystroke.
  • AurumSkeleton: moved the shimmerProgress state read out of the drawWithCache cache block and into onDrawBehind, so the cache is no longer invalidated on every animation frame. The gradient colors list is now remember-ed.
  • AurumText: inlineContent parameter typed as ImmutableMap<…> instead of Map<…>, restoring skippability (caught by the new compose-rules UnstableCollections rule).
  • CI Java mismatch: compose-report-to-html v1.5.0 JAR is built against Java 21; check.yml and pages.yml now install JDK 21 alongside JDK 17 and invoke the JAR via $JAVA_HOME_21_X64/bin/java.

Tooling

  • New Makefile targets: make lint-compose, make compose-metrics, make compose-metrics-html, make icons-import, make icons-brand (rename of the prior make icons for clarity vs the new icon-set sync).
  • New tooling scripts: tooling/icons/import_from_figma.py (Figma SVG → Vector Drawable + AurumIcons.kt + Code Connect codegen) and tooling/gallery/render_metrics_index.py (gallery /metrics/ landing page).

[0.1.2] - 2026-04-23

Added

  • Screenshot testing via Roborazzi + ComposablePreviewScanner. 334 baseline

PNGs committed under aurum/src/test/snapshots/ (Git LFS-tracked) covering

every @Preview and every tile of the @AurumPreview 6-device fan-out.

Any visual regression fails CI before merge. Tasks: recordRoborazziDebug

(refresh baselines), verifyRoborazziDebug (CI check), compareRoborazziDebug

(diff without failing).

  • .github/workflows/check.yml — PR + main-push workflow running library +

catalog build, lint, and snapshot verification. Diff PNGs uploaded as a

workflow artifact on any screenshot drift so design reviewers can eyeball

the exact delta.

  • Git LFS (.gitattributes) tracking aurum/src/test/snapshots/**/*.png

— keeps pack files small, surfaces binary diffs in PR UIs.

[0.1.1] - 2026-04-23

Changed

  • Maven coordinate realigned with Jar's library convention.
  • Before: com.jarapp:aurum:<ver>
  • After: com.jar.internal.library.aurum-android:core:<ver>
  • Kotlin import package inside the AAR stays com.jar.app.aurum.* — no source rename.
  • This lets consumers resolve Aurum via the existing Changejarapp/* wildcard

Maven repo in jar-android/settings.gradle.kts, identical to how

com.jar.internal.library.core-network:shared and siblings are resolved.

  • The previous com.jarapp:aurum:0.1.0 artifact is stale and should not be

consumed — it's kept in GitHub Packages only to avoid the "published once,

cannot re-publish the same coord" rule.

Removed

  • AurumElevation.toast + ElevationTintColors.toast + AurumLightElevation.toast entry + AurumLightColors.elevationTint.toast value — Figma ships only a tint for elevation/_toast (no dedicated dims) and the fallback shape matched lowRaised, so the Kotlin surface added API surface without semantic value. Snackbars/toasts now use Aurum.elevation.lowRaised directly. The plugin mapping (figma-plugin-aurum-sync) marks _toast as an explicitly skipped elevation token and bumps to 0.1.1.

Added

  • AurumColors.visual — new decorative palette subgroup exposing 77 chromatic tokens (blue/green/orange/pink/purple/red/yellow × shades 50…1000). Mirrors Figma's visual_colors collection 1:1 and sources values from AurumPalette primitives. Feature code uses Aurum.colors.visual.<family><shade> for palette-keyed decorative colours that have no semantic meaning. Raw AurumPalette stays internal.
  • AurumPhoneNumberInput — phone-number variant of AurumTextField with country-code prefix slot, optional flag composable, digit-only input filter, KeyboardType.Phone, and a default 10-digit max length. Mirrors the Figma "Phone Number Input" component set.
  • AurumTextField.figma.kt — Code Connect stub against Figma 4623:373 mapping state, validationState, multi_line, label, showHelpText to AurumTextField API props.
  • AurumPhoneNumberInput.figma.kt — Code Connect stub against Figma 4904:2455 mapping state, validationState, hasValue, label, showHelpText.
  • AurumOtpValidationState.Timer — fourth validation state for resend-countdown UX. Renders identically to None but provides a semantic channel matching the Figma validationState=timer variant.
  • Modifier.aurumHardShadow(color, offsetY, shape) — solid-colour offset drop shadow for skeuomorphic "stacked card" effects (matches Figma's shadow(0, Ypx, 0, 0, color) spec). Encapsulates the double-box idiom into a single modifier that expands layout by offsetY and paints the shape outline behind content.

Fixed

  • AurumOtpInput disabled digits now use surface.textDefaultDisabled (matching Figma text/default/disabled) instead of textDefaultNormal at 10% alpha.
  • AurumTopAppBar synced to Figma 4826:1057 Page Header: title uses SemiBold (was Medium); subtitle uses labelL2 Medium 12/16 in textDefaultNormal (was bodyB3 Normal in textDefaultSubtle); primary button uses SemiBold label and natural 36 dp height from 8 dp padding (was fixed 32 dp, Medium); back + action icons tint via interactive.iconNeutralNormal (was surface.textDefaultNormal — same hex, correct token). Docstring fix: icon wrapper is 32 × 40 dp (w × h), not 40 × 32.
  • AurumBadge synced to Figma 4240:10843: both emphases now render at Label/L-Medium (12/16 Inter Medium) — previously had a 18 sp line-height and Intense emphasis rendered Normal weight. Emphasis-specific text styles collapsed to a single shared style.
  • AurumSectionHeader synced to Figma 3702:162168: title, link label, and text-action label render SemiBold (Title/S-SemiBold / Title/XS-SemiBold); icon-action tint uses interactive.iconNeutralNormal (was surface.iconDefaultNormal — same hex, correct semantic).
  • AurumSwitch synced to Figma 4018:557: thumb now uses interactive.bgNeutralInverse (was surface.bgPageBase — same hex, correct semantic); checked icon uses interactive.iconPrimaryNormal (was bgPrimaryDefault); disabled-checked icon uses interactive.iconNeutralDisabled (was bgNeutralDisabledreal hex drift fixed).
  • AurumStepper synced to Figma 3834:139631: numeric value and ± symbols render Bold (Num/XS); Neutral and Brand state colours moved to the interactive.* token family; disabled-state bg/border/icon hexes corrected (#6C849D17 / #C3C7D1 were previously rendering as #ECEEF3 / #848A99).
  • AurumLabel synced to Figma 3774:137816: all variants render Medium weight (was SemiBold); Strong variant now uses labelL2 size (was labelL1) and feedback.textPrimaryIntense colour (was surface.textDefaultNormal).
  • AurumButton synced to Figma 4692:1074: primary-disabled text token changed to textPrimaryDisabled (was textOnPrimaryDisabled); secondary variant border uses borderPrimaryDefault when enabled and borderNeutralMuted when disabled (was borderNeutralDefault / borderNeutralDisabled).

[0.2.0] - 2026-04-16

Added

  • Figma Code Connect infrastructure: Gradle plugin, CLI, *.figma.kt pattern
  • AurumIcons namespace with 8 XML Vector Drawables from Figma exports
  • AurumLinkButton — new component from Figma Button page
  • AurumBadge — 6 colors × 2 emphases × 2 sizes from Figma
  • AurumOtpInput — digit-by-digit OTP from Figma spec
  • AurumStepper — numeric +/− from Figma spec
  • AurumLabel — styled text label from Figma spec
  • AurumSectionHeader — section divider from Figma spec
  • AurumSwitch — toggle from Figma spec
  • version.properties for semver tracking

Changed

  • AurumButton rebuilt from Figma spec: 3 variants (removed Ghost/Destructive), corrected heights (40/48/56dp), added isFullWidth + isLoading, 12dp corner radius
  • AurumTypography restructured to match Figma type scale: 14 scale composites (Display/Heading/Body/Caption) + 6 component-level styles
  • AurumTextField audited: added success state, readonly treatment, character counter, fixed error token layer
  • All Material Icons replaced with AurumIcons.* (XML Vector Drawables loaded via ImageVector.vectorResource())
  • Button size enum renamed Sm/Md/LgSmall/Medium/Large
  • Button style enum renamed AurumButtonStyleAurumButtonVariant

Fixed

  • Secondary button was filled grey — now transparent bg + outline border per Figma
  • Typography composites were engineering assumptions — now 14 match actual Figma scale
  • Hand-drawn ImageVector.Builder paths replaced with proper XML drawables

[0.1.0] - 2026-04-16

Added

  • Initial Aurum module scaffold (:core-designsystem + :core-designsystem-catalog)
  • 196 semantic colour tokens from Figma export (6 sub-structs)
  • Spacing, radius, border-width, icon-size, elevation, motion, opacity tokens
  • AurumTheme composable with MaterialBridge (hybrid M3 architecture)
  • Foundation primitives: AurumText, AurumIcon, AurumSurface, AurumDivider
  • Interactive primitives: AurumButton, AurumIconButton, AurumTextField, AurumSearchField
  • Navigation: AurumTopAppBar (10 Figma variants)
  • Feedback: AurumLoader, AurumSkeleton
  • Preview infrastructure: @AurumPreview, AurumPreviewSurface
  • Modifier.aurumShadow() for elevation rendering
  • CLAUDE.md module guide + 30 documentation files
  • Catalog app with 6 foundation gallery screens