From 3438a18d92009b40b6e7a6f1f012ef438c09919b Mon Sep 17 00:00:00 2001 From: innolove-dev Date: Tue, 1 Sep 2026 14:04:04 +0100 Subject: [PATCH 01/11] fix(ds): sweep composition drift against design.md, ratchet five new metrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The token ratchet was green while law-level drift kept growing: weights stacked on type tokens minted off-ramp styles, spacing/radius/motion used off-scale values, and icons sat between the 16/20/24 steps. Fix the product-UI sites (page shells to gap-*, durations to motion tokens, weight stacks to their ramp tokens, icons and spacing snapped by role, skeleton tints to the ruled interim class) and add five ds-lint ratchet metrics so the residual — quests pending a ruling, geometry-driven indents, board-pending primitives — is frozen in the baseline instead of silently regrowing. --- scripts/ds-lint-baseline.json | 9 ++++- scripts/ds-lint-counts.mjs | 37 +++++++++++++++++++ .../add-money/[country]/bank/page.tsx | 2 +- src/app/(mobile-ui)/profile/backup/page.tsx | 6 +-- src/app/(mobile-ui)/qr-pay/page.tsx | 6 +-- .../(mobile-ui)/qr/[code]/success/page.tsx | 2 +- src/app/(mobile-ui)/rewards/page.tsx | 4 +- .../withdraw/[country]/bank/page.tsx | 2 +- src/app/(mobile-ui)/withdraw/crypto/page.tsx | 2 +- src/app/(mobile-ui)/withdraw/page.tsx | 2 +- src/app/(setup)/setup/finish/page.tsx | 2 +- src/app/(setup)/setup/page.tsx | 2 +- src/app/kyc/success/page.tsx | 2 +- src/components/0_Bruddle/DataRow.tsx | 2 +- .../AddMoney/components/ChainChip.tsx | 2 +- .../AddMoney/components/HowToDepositModal.tsx | 4 +- .../AddMoney/components/InputAmountStep.tsx | 6 +-- .../AddMoney/views/CryptoDeposit.view.tsx | 20 +++++----- .../AddMoney/views/RhinoDeposit.view.tsx | 12 +++--- .../AddWithdraw/AddWithdrawRouterView.tsx | 2 +- src/components/Badges/BadgesRow.tsx | 2 +- src/components/Card/CancelCardModal.tsx | 2 +- .../Card/CardCountryConfirmScreen.tsx | 2 +- src/components/Card/CardFace.tsx | 2 +- src/components/Card/CardLimitEditModal.tsx | 2 +- src/components/Card/CardLimitsScreen.tsx | 2 +- src/components/Card/CardRejectionScreen.tsx | 6 +-- src/components/Card/CardUnlockHistoryItem.tsx | 2 +- .../Card/share-asset/ShareAssetActions.tsx | 4 +- .../Claim/Generic/ClaimError.view.tsx | 2 +- .../Common/ContactsListSkeleton.tsx | 6 +-- src/components/Common/CountryList.tsx | 2 +- src/components/Common/CountryListSkeleton.tsx | 4 +- src/components/Global/AmountInput/index.tsx | 2 +- .../Global/CancelSendLinkDrawer/index.tsx | 4 +- src/components/Global/Drawer/index.tsx | 2 +- .../Global/ExchangeRateWidget/index.tsx | 15 ++++---- src/components/Global/FAQs/index.tsx | 2 +- .../Global/GuestVerificationModal/index.tsx | 2 +- src/components/Global/HoldToClaimButton.tsx | 4 +- src/components/Global/IframeWrapper/index.tsx | 2 +- src/components/Global/Modal/index.tsx | 8 ++-- src/components/Global/MoreInfo/index.tsx | 4 +- src/components/Global/QRScanner/index.tsx | 12 +++--- src/components/Global/ShareButton/index.tsx | 4 +- src/components/Global/SupportDrawer/index.tsx | 4 +- .../Components/NetworkButton.tsx | 2 +- .../Components/TokenListItem.tsx | 2 +- .../Global/TokenSelector/TokenSelector.tsx | 4 +- .../Global/ValidatedInput/index.tsx | 2 +- .../Home/GettingStartedChecklist.tsx | 7 +--- src/components/Home/HomeHistory.tsx | 6 +-- .../Home/PendingVerificationTasks.tsx | 2 +- src/components/Home/PerkClaimModal.tsx | 4 +- .../UnlockRegionModal.tsx | 2 +- .../Kyc/AdditionalVerificationView.tsx | 2 +- src/components/Kyc/KycPrepChecklist.tsx | 4 +- src/components/Migration/StoreBadges.tsx | 2 +- .../Payment/Views/Error.validation.view.tsx | 4 +- .../Profile/components/BetaUpdatesCard.tsx | 2 +- .../Profile/components/ProfileHeader.tsx | 4 +- .../Profile/components/ProfileMenuItem.tsx | 2 +- .../Profile/components/PublicProfile.tsx | 6 +-- .../Profile/views/UnlockPayments.view.tsx | 14 +++---- .../link/views/Create.request.link.view.tsx | 2 +- .../link/views/Success.link.send.view.tsx | 2 +- src/components/Send/views/Contacts.view.tsx | 6 +-- .../Settings/DeleteAccountButton.tsx | 2 +- src/components/Setup/Setup.consts.tsx | 2 +- src/components/Setup/Views/InstallPWA.tsx | 4 +- src/components/Setup/Views/Landing.tsx | 2 +- src/components/Setup/Views/Residence.tsx | 8 ++-- src/components/Setup/Views/SetupPasskey.tsx | 2 +- .../Setup/Views/SignTestTransaction.tsx | 6 +-- src/components/Tooltip/TooltipContent.tsx | 2 +- .../TransactionDetails/ReceiptActions.tsx | 6 +-- .../provider-actions/CancelDepositActions.tsx | 2 +- src/components/UserHeader/index.tsx | 6 +-- .../limits/components/CryptoLimitsSection.tsx | 2 +- .../limits/components/LimitsWarningCard.tsx | 6 +-- .../limits/views/MantecaLimitsView.tsx | 2 +- 81 files changed, 198 insertions(+), 164 deletions(-) diff --git a/scripts/ds-lint-baseline.json b/scripts/ds-lint-baseline.json index 1078dc37a4..aa8e1cab33 100644 --- a/scripts/ds-lint-baseline.json +++ b/scripts/ds-lint-baseline.json @@ -2,7 +2,7 @@ "rawHex": 65, "rawHexFiles": 41, "inlineStyle": 50, - "stockTextSize": 362, + "stockTextSize": 361, "dsTextScale": 10, "nonDsClassesInViews": 138, "useSearchParamsFiles": 47, @@ -11,5 +11,10 @@ "offRampPalette": 0, "deadLegacyTokens": 0, "consumedUndefinedTokens": 0, - "classNameSitesInPages": 314 + "classNameSitesInPages": 314, + "fontWeightOnTypeToken": 13, + "offScaleSpacing": 124, + "iconOffScale": 42, + "offScaleRadius": 33, + "rawDuration": 9 } diff --git a/scripts/ds-lint-counts.mjs b/scripts/ds-lint-counts.mjs index d9712ee592..8b04de6569 100644 --- a/scripts/ds-lint-counts.mjs +++ b/scripts/ds-lint-counts.mjs @@ -252,6 +252,38 @@ counts.classNameSitesInPages = files .filter((f) => /^app\/\(mobile-ui\)\//.test(f.path) && /(^|\/)page\.tsx$/.test(f.path) && !f.path.includes('/dev/')) .reduce((sum, f) => sum + countMatches(f.text, /className=/g), 0) +// composition-drift metrics (2026-09-01 sweep). design.md laws the token +// metrics above cannot see: stacked weights mint off-ramp type styles, the +// spacing/radius/motion scales ban off-scale values, icons have three sizes. +// deliberate holds (geometry-driven indents like Notification's pl-7, boards +// pending a ruling) live inside the baseline, not an allowlist — a ruling +// drives the count down, new drift pushes it up and fails. +const WEIGHT_STACK_RE = /\bfont-(?:bold|semibold|extrabold)\b/ +const TYPE_TOKEN_RE = /\btext-(?:body|heading|label|button)-[a-z-]+\b/ +counts.fontWeightOnTypeToken = files + .filter((f) => isTsx(f) && !allowed(f.path)) + .reduce( + (sum, f) => sum + f.text.split('\n').filter((l) => TYPE_TOKEN_RE.test(l) && WEIGHT_STACK_RE.test(l)).length, + 0 + ) +const OFF_SCALE_SPACING_RE = + /(? isTsx(f) && !allowed(f.path)) + .reduce((sum, f) => sum + countMatches(f.text, OFF_SCALE_SPACING_RE), 0) +const OFF_SCALE_ICON_RE = /(?:]*\bsize|\biconSize)=\{(?!16\}|20\}|24\})[0-9]+\}/g +counts.iconOffScale = files + .filter((f) => isTsx(f) && !allowed(f.path)) + .reduce((sum, f) => sum + countMatches(f.text, OFF_SCALE_ICON_RE), 0) +const OFF_SCALE_RADIUS_RE = /\brounded(?:-[trbl]{1,2})?-(?:md|lg|xl|2xl|3xl)\b/g +counts.offScaleRadius = files + .filter((f) => isTsx(f) && !allowed(f.path)) + .reduce((sum, f) => sum + countMatches(f.text, OFF_SCALE_RADIUS_RE), 0) +const RAW_DURATION_RE = /\bduration-(?:75|100|150|200|300|500|700|1000)\b/g +counts.rawDuration = files + .filter((f) => isTsx(f) && !allowed(f.path)) + .reduce((sum, f) => sum + countMatches(f.text, RAW_DURATION_RE), 0) + // dsTextScale and nuqsFiles are adoption counts (should go UP) — everything // else is debt (must only go DOWN). the ratchet only enforces the debt keys. const DEBT_KEYS = [ @@ -266,6 +298,11 @@ const DEBT_KEYS = [ 'classNameSitesInPages', 'deadLegacyTokens', 'consumedUndefinedTokens', + 'fontWeightOnTypeToken', + 'offScaleSpacing', + 'iconOffScale', + 'offScaleRadius', + 'rawDuration', ] const mode = process.argv[2] ?? '' diff --git a/src/app/(mobile-ui)/add-money/[country]/bank/page.tsx b/src/app/(mobile-ui)/add-money/[country]/bank/page.tsx index 2bb95cb976..7bf8d8e52b 100644 --- a/src/app/(mobile-ui)/add-money/[country]/bank/page.tsx +++ b/src/app/(mobile-ui)/add-money/[country]/bank/page.tsx @@ -476,7 +476,7 @@ function BridgeBankOnrampPage() {
-
{t('howMuchToAdd')}
+
{t('howMuchToAdd')}
-
    +
      {backupSteps.map((step, index) => (
    1. {step.title}

      @@ -104,7 +104,7 @@ export default function BackupPage() { titleClassName="text-heading-xs" content={
      -
        +
        1. {t('changePhoneModal.step1')}
        2. {t('changePhoneModal.step2', { platform })}
        3. {t('changePhoneModal.step3')}
        4. @@ -135,7 +135,7 @@ export default function BackupPage() {

          {t('exportKeysModal.saferIntro')}

          -
            +
            • {t('exportKeysModal.bullets.screenshot')}
            • {t('exportKeysModal.bullets.textMessage')}
            • {t('exportKeysModal.bullets.noteApp')}
            • diff --git a/src/app/(mobile-ui)/qr-pay/page.tsx b/src/app/(mobile-ui)/qr-pay/page.tsx index 71a2834bc5..706d755282 100644 --- a/src/app/(mobile-ui)/qr-pay/page.tsx +++ b/src/app/(mobile-ui)/qr-pay/page.tsx @@ -1454,7 +1454,7 @@ export default function QRPayPage() { )} -
              +
              {/* Show Claim Reward button if eligible and not claimed yet */} {rewardClaimable ? ( diff --git a/src/components/AddMoney/views/RhinoDeposit.view.tsx b/src/components/AddMoney/views/RhinoDeposit.view.tsx index f0a4528b7c..b8008f8fad 100644 --- a/src/components/AddMoney/views/RhinoDeposit.view.tsx +++ b/src/components/AddMoney/views/RhinoDeposit.view.tsx @@ -85,9 +85,7 @@ const RhinoDepositView = ({ {t('marketMovedDescription')}

              -

              - {t('marketMovedNote')} -

              +

              {t('marketMovedNote')}

              -

              {t('title')}

              +

              {t('title')}

              {/* Badge viewport container */}
              = ({ cardId, isOpen, onClose }) => { ) : isFeedback ? (
              -