trdr-ds-install 1.6.8 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trdr-ds-install",
3
- "version": "1.6.8",
3
+ "version": "1.7.0",
4
4
  "description": "Installs the TRDR Design System skill for Claude Code",
5
5
  "bin": {
6
6
  "trdr-ds-install": "./bin/install.js"
@@ -2,11 +2,11 @@
2
2
  name: trdr-ds
3
3
  description: Applies the TRDR Design System to any project. Runs a multi-phase workflow - first analyzes the project and saves DS_ANALYSIS.md, then executes implementation in 4 checkpointed sub-phases (Foundation → Violations → Components → Final), each saving progress to DS_PROGRESS.md and resumable at any time. Trigger when developer mentions "apply design system", "implement TRDR DS", "add TRDR tokens", "design system setup", "migrar design system", "aplicar design system", or invokes /trdr-ds.
4
4
  user-invocable: true
5
- argument-hint: "[analyze|apply|foundation|violations|components|final|resume|status|sync|batch N]"
5
+ argument-hint: "[analyze|apply|foundation|violations|components|final|resume|status|sync|batch N|rollback]"
6
6
  allowed-tools: [Read, Glob, Grep, Edit, Write, Bash, WebFetch]
7
7
  ---
8
8
 
9
- **Skill version:** 1.6.8
9
+ **Skill version:** 1.7.0
10
10
  **npm package:** trdr-ds-install
11
11
 
12
12
  You are implementing the **TRDR Design System** in a developer's project. The Design Hub is the single source of truth and lives at **https://trdr.mrocontent.com.br**.
@@ -26,16 +26,17 @@ Execute in multiple checkpointed phases: **PHASE 1: ANALYZE (saves DS_ANALYSIS.m
26
26
 
27
27
  | Arg | Behaviour |
28
28
  |-----|-----------|
29
- | `analyze` *(default when none given)* | Run Phase 1 only — scan project, save `DS_ANALYSIS.md`, present plan. Do not modify any project file |
29
+ | `analyze` *(default when none given)* | Run Phase 1 only — scan project, save `DS_ANALYSIS.md` + `SPRINT_PLAN.md`, present plan. Do not modify any project file |
30
30
  | `apply` | Run Phase 1 + Phase 2 (all 4 sub-phases, with STOP between each) |
31
31
  | `foundation` | Run Sub-fase A only — create tokens.css, components.css, CLAUDE.md, @imports. Requires DS_ANALYSIS.md |
32
32
  | `violations` | Run Sub-fase B only — process next pending violation batch. Requires DS_ANALYSIS.md + DS_PROGRESS.md |
33
33
  | `components` | Run Sub-fase C only — apply DS component classes. Requires DS_ANALYSIS.md + DS_PROGRESS.md |
34
34
  | `final` | Run Sub-fase D only — fix logos + generate DS_MIGRATION.md. Requires DS_PROGRESS.md |
35
- | `resume` | Read `DS_PROGRESS.md` from the project root and continue from the last checkpoint (detects current sub-fase automatically) |
36
- | `status` | Read `DS_PROGRESS.md` and display a progress summary table — no files modified |
35
+ | `resume` | Read `SPRINT_PLAN.md` + `DS_PROGRESS.md`, find the next pending sprint, and execute it. Designed for use after `/clear` or in a new conversation — each sprint is self-contained |
36
+ | `status` | Read `SPRINT_PLAN.md` + `DS_PROGRESS.md` and display sprint progress table — no files modified |
37
37
  | `batch [N]` | Override default violation batch size (default: 5 files/batch) |
38
38
  | `sync` | Re-fetch `https://trdr.mrocontent.com.br/components.json` and `https://trdr.mrocontent.com.br/tokens.css`, overwrite `data/components.json` and `references/tokens.css` in the skill directory, report the diff. No project changes. |
39
+ | `rollback` | Read `DS_PROGRESS.md` to find the backup branch, reset working branch to that state, remove DS artifacts. Requires `DS_PROGRESS.md` with a `Backup branch:` entry |
39
40
  | `--latest` *(modifier on `analyze` or `apply`)* | Same as `sync` first, then continue normally |
40
41
 
41
42
  ---
@@ -59,7 +60,7 @@ Compare the result with the **Skill version** constant at the top of this file (
59
60
  - If registry version == local version: skip silently, continue.
60
61
  - If registry version > local version:
61
62
  ```
62
- 🔄 Nova versão da skill disponível: trdr-ds-install@[registry-version] (instalada: 1.6.8)
63
+ 🔄 Nova versão da skill disponível: trdr-ds-install@[registry-version] (instalada: 1.7.0)
63
64
 
64
65
  Responda:
65
66
  - `"atualizar"` / `"update"` — instalar a nova versão agora (requer reiniciar /trdr-ds após)
@@ -337,6 +338,12 @@ Use Grep (not Bash grep) to search for the patterns below. Group patterns from t
337
338
  | `card` | `<Card`, `\.card`, `<article` |
338
339
  | `boleta` | `<Boleta`, `boleta` |
339
340
  | `janela` | `<Janela`, `trading.{0,10}window` |
341
+ | `tabela-cotacoes` | `<TabelaCotacoes`, `.quotes-table`, `.price-list`, `<table` with price/ticker/cotacao columns |
342
+ | `tabela-ordens` | `<TabelaOrdens`, `.orders-table`, `.order-list`, `<table` with order/position columns |
343
+ | `floating-menu` | `<FloatingMenu`, `.floating-menu`, `position:absolute` + `z-index` + list pattern |
344
+ | `news-card` | `<NewsCard`, `.news-card`, `.article-card`, `<article` with image + title + date pattern |
345
+ | `header` | `<Header`, `<header`, `.header`, `.navbar`, `<nav` at top-level page position |
346
+ | `badge` | `<Badge`, `.badge`, `.tag`, `.chip`, `.label-status`, `<span` with short status-like text |
340
347
 
341
348
  **Rules:**
342
349
  - For each slug, count the distinct files that matched (not total lines) — one file counts as one occurrence.
@@ -355,7 +362,55 @@ Use Grep (not Bash grep) to search for the patterns below. Group patterns from t
355
362
 
356
363
  For each match, add to `replacementCandidates[]` with a `customCssClass` field noting the project's class name, so Phase 2 Step 6 can add DS classes to those elements.
357
364
 
358
- **Output:** `replacementCandidates[]` — passed to Step 5 template and Phase 2 Step 6.
365
+ **Output:** `replacementCandidates[]` — passed to Step 3.5b, Step 5 template and Phase 2 Step 6.
366
+
367
+ ### Step 3.5b — Capture structural context for each candidate
368
+
369
+ For each file:line match found in Step 3.5, read the surrounding context (10 lines before and after the match) and classify the replacement complexity:
370
+
371
+ | Classification | Criteria | Phase 2 action |
372
+ |---|---|---|
373
+ | `simple` | Element has only text content. No event handlers (`onClick`, `onChange`, etc.), no conditional rendering (`{condition && ...}`, ternary), no dynamic props beyond basic HTML attributes (`id`, `name`, `class`, `placeholder`, `type`) | Full DS component replacement — swap the element entirely with the DS component structure, adapting content |
374
+ | `complex-preservable` | Element has event handlers, data bindings (`value={state}`, `checked={state}`), refs, or conditional rendering, BUT the DOM structure maps cleanly to a DS component | Apply DS structure + classes, preserving ALL handlers, bindings, and conditional logic |
375
+ | `complex-manual` | Element has deeply nested custom logic, multiple conditional branches affecting structure, dynamically generated children, or domain-specific behavior that doesn't map to any DS component pattern | Flag for manual review in DS_MIGRATION.md — do NOT auto-modify |
376
+
377
+ **For each candidate, store:**
378
+ ```json
379
+ {
380
+ "slug": "button",
381
+ "file": "src/components/Hero.tsx",
382
+ "line": 42,
383
+ "classification": "simple",
384
+ "existingContent": "Get Started",
385
+ "existingHandlers": [],
386
+ "existingClasses": "btn-primary hero-cta",
387
+ "existingProps": [],
388
+ "suggestedDsVariant": "trdr-btn-primary"
389
+ }
390
+ ```
391
+
392
+ **Variant detection rules (by signals in existing code):**
393
+
394
+ | Existing pattern signals | Suggested DS variant |
395
+ |---|---|
396
+ | `.btn-primary`, `.cta`, `type="submit"`, prominent/brand color (cyan, blue) | `trdr-btn-primary` |
397
+ | `.btn-secondary`, `.btn-cancel`, muted/gray color | `trdr-btn-secondary` |
398
+ | `.btn-outline`, `.btn-ghost`, transparent background + border | `trdr-btn-ghost` |
399
+ | `.btn-danger`, `.btn-delete`, red/orange/destructive color | `trdr-btn-destructive` |
400
+ | `.btn-link`, `<a>` styled as button, no border/bg | `trdr-btn-link` |
401
+ | `type="text"`, `type="email"`, `type="password"`, `type="search"`, `<textarea>` | `trdr-text-input` |
402
+ | `type="checkbox"` | `trdr-checkbox` |
403
+ | `type="radio"` | `trdr-radio-button` |
404
+ | `role="switch"`, `.toggle`, `.switch` | `trdr-switch` |
405
+ | `<select>`, `role="listbox"` | `trdr-dropdown` |
406
+ | `role="tablist"`, `.tabs` | `trdr-abas` or `trdr-segment-control` |
407
+ | `.badge` + green/success color | `trdr-badge-success` |
408
+ | `.badge` + blue/brand color | `trdr-badge-brand` |
409
+ | `.badge` + yellow/warning color | `trdr-badge-warning` |
410
+ | `.badge` + neutral/gray color | `trdr-badge-neutral` |
411
+ | `<Tooltip>`, `role="tooltip"`, `data-tooltip` | `trdr-tooltip` |
412
+
413
+ **Output:** Updated `replacementCandidates[]` — each entry now includes `classification`, `existingContent`, `existingHandlers`, `existingProps`, and `suggestedDsVariant`.
359
414
 
360
415
  ### Step 3.6 — Logo audit
361
416
 
@@ -480,9 +535,32 @@ All projects use the same checkpointed 4-sub-phase execution regardless of size.
480
535
  | J — SVG icons inline | N | `<svg>` in index.html (search, close, play icons) |
481
536
  | K — Logo incorrect/missing | N | `<span>TRDR</span>` used as logo in index.html:45 |
482
537
 
483
- ### TRDR COMPONENTS REFERENCED IN PROJECT:
484
- (Candidatos detectados no Step 3.5 — substituição recomendada)
538
+ ### TRDR COMPONENTS IMPLEMENTATION PLAN:
539
+ (Candidatos detectados no Step 3.5 — com classificação de complexidade)
540
+
541
+ #### Simple swaps (substituição completa pelo componente DS):
542
+ | Componente | Variante DS | Arquivo | Conteúdo atual |
543
+ |------------|------------|---------|----------------|
544
+ [For each candidate where classification === 'simple':]
545
+ | [c.name] | [suggestedDsVariant] | [file:line] | "[existingContent]" |
546
+
547
+ #### Complex-preservable (estrutura DS + lógica preservada):
548
+ | Componente | Arquivo | Handlers/Props preservados |
549
+ |------------|---------|----------------------------|
550
+ [For each candidate where classification === 'complex-preservable':]
551
+ | [c.name] | [file:line] | [existingHandlers], [existingProps] |
552
+
553
+ #### Manual review (complexidade alta — sem modificação automática):
554
+ | Componente | Arquivo | Motivo |
555
+ |------------|---------|--------|
556
+ [For each candidate where classification === 'complex-manual':]
557
+ | [c.name] | [file:line] | [reason] |
485
558
 
559
+ > **Simple:** substituição completa, conteúdo adaptado do projeto.
560
+ > **Complex-preservable:** estrutura DS aplicada, toda lógica (handlers, bindings, conditionals) preservada.
561
+ > **Manual:** flagged em DS_MIGRATION.md para revisão pelo desenvolvedor.
562
+
563
+ #### Stubs e catálogo:
486
564
  | Componente | Status no catálogo | Arquivos detectados |
487
565
  |------------|--------------------|---------------------|
488
566
  [For each entry in replacementCandidates[], look up the slug in the loaded catalog:]
@@ -586,8 +664,28 @@ Total files with violations: [total_files_with_violations]
586
664
  [list all violations with line numbers]
587
665
 
588
666
  ## Component Replacement Candidates
589
- [For each entry in replacementCandidates[]:]
590
- - [slug]: [file:line] [implemented | stub ⚠️]
667
+
668
+ ### Simple swaps (full DS component replacement)
669
+ [For each candidate where classification === 'simple':]
670
+ | Component | DS Variant | File | Existing Content |
671
+ |-----------|-----------|------|------------------|
672
+ | [c.name] | [suggestedDsVariant] | [file:line] | "[existingContent]" |
673
+
674
+ ### Complex-preservable (DS structure + preserved logic)
675
+ [For each candidate where classification === 'complex-preservable':]
676
+ | Component | File | Handlers/Props Preserved |
677
+ |-----------|------|--------------------------|
678
+ | [c.name] | [file:line] | [existingHandlers], [existingProps] |
679
+
680
+ ### Manual review required
681
+ [For each candidate where classification === 'complex-manual':]
682
+ | Component | File | Reason |
683
+ |-----------|------|--------|
684
+ | [c.name] | [file:line] | [brief description of why it's complex] |
685
+
686
+ ### Stubs (not yet implemented in DS)
687
+ [For each candidate where c.implemented === false:]
688
+ - [slug]: [file:line] — ⚠️ stub (figmaId: [c.figmaId])
591
689
 
592
690
  ## Logo Audit
593
691
  [For each file in logoAudit.correct:] - [path] — ✅ CORRECT
@@ -604,9 +702,97 @@ Batch size: [N] (default 5)
604
702
  - ...
605
703
  ```
606
704
 
607
- After writing `DS_ANALYSIS.md`, confirm with:
705
+ ### Step 5.6 Generate SPRINT_PLAN.md
706
+
707
+ After writing `DS_ANALYSIS.md`, generate `SPRINT_PLAN.md` at the project root. This file breaks the entire migration into **self-contained sprints** — each sprint can be executed in an independent conversation with a clean context window.
708
+
709
+ **Sprint sizing rules:**
710
+ - Each sprint should process at most **15 files** (keeps context comfortable even for complex files)
711
+ - Group files by **folder** (natural boundary — violations in the same folder share CSS patterns)
712
+ - If a folder has >15 files, split into sub-sprints (e.g., `Sprint 3a`, `Sprint 3b`)
713
+ - Foundation, Components, and Final are each their own sprint (regardless of file count)
714
+
715
+ **Generate the plan:**
716
+
717
+ ```markdown
718
+ # TRDR DS — Sprint Plan
719
+ Generated: [ISO datetime]
720
+ Project: [project name]
721
+ Total sprints: [N]
722
+ Estimated context windows: [N] (one per sprint + one for this analysis)
723
+
724
+ > Cada sprint é independente. Entre sprints, você pode limpar o contexto (`/clear`) ou iniciar uma nova conversa.
725
+ > Para continuar: `/trdr-ds resume`
726
+
727
+ ---
728
+
729
+ ## Sprint 1 — Foundation
730
+ **Scope:** Create tokens.css, components.css, CLAUDE.md, @import in global CSS
731
+ **Sub-fase:** A
732
+ **Files to create:** 3 (tokens.css, components.css, CLAUDE.md)
733
+ **Files to modify:** 1 (global CSS)
734
+ **Status:** PENDING
735
+
736
+ ---
737
+
738
+ ## Sprint 2 — Violations: [first-folder/]
739
+ **Scope:** Fix [N] violations in [M] files
740
+ **Sub-fase:** B
741
+ **Files:** [list each file path]
742
+ **Violation count:** [N] (A:[n], B:[n], C:[n], ...)
743
+ **Status:** PENDING
744
+
745
+ ---
746
+
747
+ ## Sprint 3 — Violations: [second-folder/]
748
+ **Scope:** Fix [N] violations in [M] files
749
+ **Sub-fase:** B
750
+ **Files:** [list each file path]
751
+ **Violation count:** [N]
752
+ **Status:** PENDING
753
+
754
+ ---
755
+
756
+ [... repeat for each folder/batch ...]
757
+
758
+ ---
759
+
760
+ ## Sprint [N-1] — Components
761
+ **Scope:** Implement DS components ([S] simple, [P] complex-preservable, [M] manual review)
762
+ **Sub-fase:** C
763
+ **Candidates:** [total]
764
+ **Status:** PENDING
765
+
766
+ ---
767
+
768
+ ## Sprint [N] — Final
769
+ **Scope:** Replace logos, replace SVG icons with Material Icons (size-preserved), generate DS_MIGRATION.md
770
+ **Sub-fase:** D
771
+ **Status:** PENDING
608
772
  ```
609
- ✅ DS_ANALYSIS.md salvo. Revise o plano acima e responda 'Apply' para iniciar.
773
+
774
+ **Sprint naming convention:**
775
+ - Foundation sprints: `Sprint 1 — Foundation`
776
+ - Violation sprints: `Sprint N — Violations: [folder/]`
777
+ - If folder split: `Sprint Na — Violations: [folder/] (part 1 of 2)`
778
+ - Component sprint: `Sprint N — Components`
779
+ - Final sprint: `Sprint N — Final`
780
+
781
+ After writing `SPRINT_PLAN.md`, update the output to include the sprint summary:
782
+
783
+ ```
784
+ ✅ DS_ANALYSIS.md e SPRINT_PLAN.md salvos.
785
+
786
+ 📋 Sprint Plan: [N] sprints planejados
787
+ Sprint 1: Foundation (4 arquivos)
788
+ Sprint 2-[M]: Violations ([total_files] arquivos em [folders] pastas)
789
+ Sprint [M+1]: Components ([candidates] candidatos)
790
+ Sprint [N]: Final (logos + ícones + DS_MIGRATION.md)
791
+
792
+ Cada sprint é independente — entre sprints, limpe o contexto com /clear.
793
+ Para continuar de qualquer ponto: /trdr-ds resume
794
+
795
+ Responda 'Apply' para iniciar o Sprint 1.
610
796
  ```
611
797
 
612
798
  **STOP HERE. Wait for explicit developer approval before Phase 2.**
@@ -620,13 +806,42 @@ Parse the developer's reply:
620
806
  - Extract skip paths from `"Apply, skip [path]"` → exclude those from violation processing.
621
807
  - `"Only tokens"` → skip Sub-fases B and C (no violation fixes, no component banners).
622
808
 
623
- **Context rule (critical):** At the start of EVERY sub-phase, before doing anything else:
624
- 1. Read `DS_ANALYSIS.md` from the project root — this is the canonical source of all analysis data
625
- 2. Read `DS_PROGRESS.md` from the project root this is the canonical source of progress state
809
+ ### Sprint execution model
810
+
811
+ Each sprint is a **self-contained unit of work** designed to fit comfortably in a single context window. The developer can `/clear` or start a new conversation between sprints and resume with `/trdr-ds resume`.
812
+
813
+ **Context rule (critical):** At the start of EVERY sprint, before doing anything else:
814
+ 1. Read `SPRINT_PLAN.md` from the project root — find the current sprint (first with `Status: PENDING` or `Status: IN_PROGRESS`)
815
+ 2. Read `DS_ANALYSIS.md` from the project root — but ONLY the sections relevant to the current sprint's scope (e.g., for a violation sprint, only read the `§ By File` entries for the files listed in that sprint)
816
+ 3. Read `DS_PROGRESS.md` from the project root — this is the canonical source of progress state
817
+
818
+ **Never read the entire DS_ANALYSIS.md at once for large projects.** Only read the sections needed for the current sprint. This prevents context overflow.
626
819
 
627
820
  Never rely on conversation memory for violation counts, file paths, batch assignments, or framework detection. Always re-read from files.
628
821
 
629
- Report progress after each major step.
822
+ **Sprint lifecycle:**
823
+ 1. Read state files (SPRINT_PLAN.md + relevant sections of DS_ANALYSIS.md + DS_PROGRESS.md)
824
+ 2. Update SPRINT_PLAN.md: set current sprint `Status: IN_PROGRESS`
825
+ 3. Execute the sprint's scope (Foundation / Violations for specific files / Components / Final)
826
+ 4. Update DS_PROGRESS.md with results
827
+ 5. Update SPRINT_PLAN.md: set current sprint `Status: ✅ COMPLETE`
828
+ 6. Output sprint summary with next sprint info
829
+ 7. **STOP** — wait for developer to continue or `/clear` + `/trdr-ds resume`
830
+
831
+ **End-of-sprint output (MANDATORY after every sprint):**
832
+ ```
833
+ ✅ Sprint [N] completo — [sprint name]
834
+ [Brief summary of what was done: files modified, violations fixed, components applied, etc.]
835
+
836
+ 📋 Progresso: [done]/[total] sprints ([percentage]%)
837
+ Próximo: Sprint [N+1] — [next sprint name]
838
+
839
+ → Você pode limpar o contexto agora: /clear
840
+ → Para continuar: /trdr-ds resume
841
+ → Para ver status completo: /trdr-ds status
842
+ ```
843
+
844
+ Report progress after each major step within a sprint.
630
845
 
631
846
  ### Step 0 — Initialize checkpoint
632
847
 
@@ -638,6 +853,10 @@ Started: [ISO datetime]
638
853
  Project: [project name from package.json]
639
854
  Batch size: [N]
640
855
  Status: IN_PROGRESS
856
+ Backup branch: [branch-name or NONE]
857
+ Original branch: [branch-name]
858
+ Sprint plan: SPRINT_PLAN.md
859
+ Current sprint: 1
641
860
 
642
861
  ## Sub-fase A: Foundation — PENDING
643
862
  - [ ] tokens.css
@@ -667,6 +886,99 @@ Total de lotes: [N]
667
886
  [empty — filled during execution]
668
887
  ```
669
888
 
889
+ ### Step 0.5 — Git backup (safety net)
890
+
891
+ Before modifying any project file, create a git backup so the entire migration can be rolled back.
892
+
893
+ **Step 0.5a — Check git status:**
894
+
895
+ Run via Bash:
896
+ ```bash
897
+ git rev-parse --is-inside-work-tree 2>/dev/null
898
+ ```
899
+
900
+ **If NOT a git repo:**
901
+ ```
902
+ ⚠️ Este projeto não tem repositório git. Um backup automático não é possível sem git.
903
+
904
+ Responda:
905
+ - "git init" — inicializar repositório git e criar backup antes de continuar
906
+ - "continuar sem backup" — prosseguir sem safety net (irreversível)
907
+ ```
908
+ **STOP. Wait for reply.**
909
+
910
+ If reply is `"git init"`:
911
+ 1. Run: `git init`
912
+ 2. Run: `git add -A && git commit -m "Initial commit (before TRDR DS migration)"`
913
+ 3. Continue to Step 0.5b.
914
+
915
+ If reply is `"continuar sem backup"`:
916
+ - Update `DS_PROGRESS.md`: set `Backup branch: NONE (user opted out)`
917
+ - Skip to Sub-fase A.
918
+
919
+ **If IS a git repo:** Continue to Step 0.5b.
920
+
921
+ **Step 0.5b — Check for existing backup branch:**
922
+
923
+ Run via Bash:
924
+ ```bash
925
+ git branch --list "trdr-ds/backup-*"
926
+ ```
927
+
928
+ If one or more `trdr-ds/backup-*` branches exist:
929
+ ```
930
+ ⚠️ Backup branch(es) encontrado(s) de execução anterior:
931
+ [list each branch name]
932
+
933
+ Responda:
934
+ - "manter" — criar novo backup com timestamp diferente (mantém os anteriores)
935
+ - "substituir" — apagar o backup anterior e criar um novo
936
+ ```
937
+ **STOP. Wait for reply.**
938
+
939
+ If `"substituir"`: delete all existing `trdr-ds/backup-*` branches via `git branch -D [name]` for each.
940
+
941
+ **Step 0.5c — Create the backup branch:**
942
+
943
+ 1. Record the current branch name:
944
+ ```bash
945
+ git branch --show-current
946
+ ```
947
+ Save as `originalBranch`. If in detached HEAD state (empty output), save the commit hash via `git rev-parse HEAD` instead.
948
+
949
+ 2. Generate timestamp branch name: `trdr-ds/backup-{YYYY-MM-DD-HHmmss}` (use current local time).
950
+
951
+ 3. Check for uncommitted changes:
952
+ ```bash
953
+ git status --porcelain
954
+ ```
955
+ If output is non-empty (uncommitted changes exist):
956
+ ```bash
957
+ git stash push -m "trdr-ds-pre-migration-stash"
958
+ ```
959
+
960
+ 4. Create the backup branch from current HEAD:
961
+ ```bash
962
+ git branch trdr-ds/backup-{timestamp}
963
+ ```
964
+
965
+ 5. If stash was created in step 3, pop it back:
966
+ ```bash
967
+ git stash pop
968
+ ```
969
+
970
+ 6. Update `DS_PROGRESS.md`:
971
+ ```
972
+ Backup branch: trdr-ds/backup-{timestamp}
973
+ Original branch: {originalBranch}
974
+ ```
975
+
976
+ 7. Output:
977
+ ```
978
+ ✅ Backup criado: branch `trdr-ds/backup-{timestamp}`
979
+ Para desfazer toda a migração a qualquer momento: `/trdr-ds rollback`
980
+ ```
981
+
670
982
  ---
671
983
 
672
984
  ## Sub-fase A: Foundation
@@ -828,9 +1140,10 @@ bg.primary (base) → bg.secondary/tertiary (content areas) → surface.* (cards
828
1140
  - HTML/Vue: `<span class="material-icons mi-sm">nome</span>` via Google Fonts CDN
829
1141
  - React: `<NomeIcon />` via @mui/icons-material
830
1142
  - Cor: SEMPRE via classe CSS com token DS (`.icon-brand`, `.icon-success`, `.icon-dim`, etc.)
831
- - Tamanho: via classe `.mi-sm` (16px), `.mi-xs` (14px); padrão sem classe = 20px
1143
+ - Tamanho: `.mi-2xs` (12px), `.mi-xs` (14px), `.mi-sm` (16px), default (20px), `.mi-lg` (24px), `.mi-xl` (28px), `.mi-2xl` (32px)
1144
+ - Para tamanhos não padrão: `style="font-size:Npx"` (aceito APENAS para font-size de ícones, nunca para cor)
832
1145
  - **NUNCA** usar `<svg>` inline para ícones
833
- - **NUNCA** usar `style=""` para cor ou tamanho de ícones
1146
+ - **NUNCA** usar `style=""` para cor de ícones
834
1147
 
835
1148
  ## Logo
836
1149
  - HTML: `<img src="logo-trdr.svg" alt="TRDR" height="24">`
@@ -1114,90 +1427,297 @@ When a CSS class has a `font-size` that maps to a DS text style, the fix is **tw
1114
1427
  ## Sub-fase C: Components
1115
1428
 
1116
1429
  > **Before starting:** Read `DS_ANALYSIS.md` (§ Component Replacement Candidates) and `DS_PROGRESS.md` (§ Sub-fase C) from the project root.
1430
+ > Also read `data/components.json` from the skill directory to have all component code blocks available.
1117
1431
 
1118
1432
  Update `DS_PROGRESS.md`: set `Sub-fase C: Components — IN_PROGRESS`.
1119
1433
 
1120
- ### Step 6 — Apply DS component classes to HTML/JSX/Vue elements
1434
+ ### Step 6 — Implement DS components in project files
1121
1435
 
1122
- Use the `replacementCandidates[]` list from `DS_ANALYSIS.md` § Component Replacement Candidates. For each entry:
1436
+ Process candidates from `DS_ANALYSIS.md` § Component Replacement Candidates in three passes:
1437
+ 1. **Pass 1** — Simple replacements (full DS component swap)
1438
+ 2. **Pass 2** — Complex-preservable (DS structure + logic preservation)
1439
+ 3. **Pass 3** — Manual review flagging (no auto-modification)
1123
1440
 
1124
- 1. **Look up the component** in the loaded catalog by slug (or by category, if slug is ambiguous).
1441
+ ---
1125
1442
 
1126
- 2. **If `c.implemented === true`** apply DS classes to the actual elements (CSS alone is not enough):
1443
+ #### Step 6Pass 1: Simple replacements
1127
1444
 
1128
- **Step 6a Identify the project's custom CSS class** for that component role.
1129
- Grep the CSS/HTML/JSX for classes like `.btn-enroll`, `.lang-selector`, `.search-bar`, etc. that serve the same function.
1445
+ For each candidate classified as `simple` in DS_ANALYSIS.md:
1130
1446
 
1131
- **Step 6bMap to DS classes:**
1132
- | Component role | DS classes to add |
1133
- |---|---|
1134
- | Primary / CTA button | `.trdr-btn .trdr-btn-primary` (+ `.trdr-btn-lg` if height ≥ 28px) |
1135
- | Ghost / outline button | `.trdr-btn .trdr-btn-ghost` |
1136
- | Secondary button | `.trdr-btn .trdr-btn-secondary` |
1137
- | Text input / search | `.trdr-text-input` |
1138
- | Segment / tab control | `.trdr-segment-control` on wrapper + `.trdr-segment` on each item |
1139
- | Active segment item | also add `.trdr-segment-active` |
1140
- | Inactive segment item | also add `.trdr-segment-inactive` |
1141
- | Generic card | `.card` (only for non-domain-specific cards) |
1142
- | Dropdown / select | `.trdr-dropdown` |
1143
-
1144
- **Step 6c — Apply to HTML/JSX by framework:**
1145
- | stylingMode | How to add |
1146
- |---|---|
1147
- | `plain-css` | `class="custom-btn trdr-btn trdr-btn-primary"` |
1148
- | React/Next.js | `className="custom-btn trdr-btn trdr-btn-primary"` |
1149
- | Vue | `class="custom-btn trdr-btn trdr-btn-primary"` |
1150
- | JS template strings | Update the string template that generates the HTML |
1151
-
1152
- **For JS-toggled state classes** (active/inactive managed by JavaScript):
1153
- - Keep the original class for `querySelector` selectors
1154
- - Add DS classes to the element's initial HTML
1155
- - Update any `classList.toggle`, `classList.add`, `classList.remove`, `setAttribute('class', ...)` calls to also toggle the DS state classes (e.g. `trdr-segment-active` / `trdr-segment-inactive`)
1156
- - Remove base CSS from the custom class (let DS provide height, padding, font, border, border-radius, background, color, cursor, transition)
1157
- - Keep only state-specific overrides in the custom class (e.g. `.custom-btn.active { border-color: var(--teal-mid); }`)
1158
-
1159
- **Step 6d — Clean up redundant custom CSS:**
1160
- For each custom class that received DS classes, remove these properties (now provided by DS):
1161
- - `height`, `padding`, `font-family`, `font-size`, `font-weight`, `border`, `border-radius`, `background`, `color`, `cursor`, `transition`, `display`, `align-items`, `justify-content`
1162
- - Keep: `width`, `min-width`, `gap`, position-specific props, state overrides
1163
-
1164
- **Step 6e — Document in DS_PROGRESS.md:**
1447
+ 1. **Load the DS component code** from `data/components.json` look up the component by slug and read `c.code.html` (for plain-css/tailwind projects) or `c.code.react` (for React/Next.js projects) or adapt for Vue.
1448
+
1449
+ 2. **Adapt the content** — the DS component's code block has placeholder content (e.g., "Confirmar", "Badge"). Replace placeholders with the ACTUAL content from the project:
1450
+ - Button text: extract the text content from the existing `<button>` element
1451
+ - Input placeholder: extract the existing `placeholder` attribute
1452
+ - Label text: extract the existing label/text node
1453
+ - Badge text: extract the existing text content
1454
+ - Preserve `id`, `name`, `data-*`, `aria-*` attributes from the original element
1455
+
1456
+ 3. **Select the correct variant** using `suggestedDsVariant` from DS_ANALYSIS.md.
1457
+
1458
+ 4. **Replace the element in the source file** — examples by component:
1459
+
1460
+ **Buttons (slug: `button`):**
1461
+ ```html
1462
+ <!-- BEFORE -->
1463
+ <button class="btn-primary hero-cta">Get Started</button>
1464
+ <!-- AFTER -->
1465
+ <button class="trdr-btn trdr-btn-primary">Get Started</button>
1165
1466
  ```
1166
- ### Componentes DS Aplicados
1167
- - [x] .btn-enroll .trdr-btn .trdr-btn-ghost .trdr-btn-lg (index.html, cursos.js)
1168
- - [x] .lang-selector .trdr-segment-control + .trdr-segment (index.html)
1169
- - [ ] .search-bar → .trdr-text-input (estrutura incompatível com ícone — revisão manual)
1467
+ - Remove custom CSS classes that duplicate DS styles (background, padding, height, font, border, border-radius, cursor, transition)
1468
+ - Keep classes used for layout/positioning (margin, width, grid placement)
1469
+ - Keep `id`, `name`, `type`, `data-*`, `aria-*` attributes
1470
+
1471
+ **Text inputs (slug: `text-input`):**
1472
+ ```html
1473
+ <!-- BEFORE -->
1474
+ <input type="text" class="search-bar" placeholder="Search...">
1475
+ <!-- AFTER -->
1476
+ <input type="text" class="trdr-text-input" placeholder="Search...">
1170
1477
  ```
1478
+ - If the existing input has a wrapper with icon (search icon + input), restructure to match DS anatomy:
1479
+ ```html
1480
+ <div class="trdr-text-input-wrapper">
1481
+ <span class="material-icons mi-sm icon-muted">search</span>
1482
+ <input type="text" class="trdr-text-input" placeholder="Search...">
1483
+ </div>
1484
+ ```
1171
1485
 
1172
- **Do NOT replace domain-specific components** (course cards, lesson rows, trading panels, etc.) — document them as "sem equivalente DS".
1486
+ **Checkboxes (slug: `checkbox`):**
1487
+ ```html
1488
+ <!-- BEFORE -->
1489
+ <input type="checkbox" id="terms"> <label for="terms">Accept terms</label>
1490
+ <!-- AFTER -->
1491
+ <label class="trdr-checkbox">
1492
+ <input type="checkbox" id="terms" />
1493
+ <span class="trdr-checkbox-box"></span>
1494
+ <span>Accept terms</span>
1495
+ </label>
1496
+ ```
1497
+ - DS checkbox requires a specific DOM structure (label > input + box-span + text-span)
1498
+ - Preserve `id`, `name`, `checked`, `disabled` attributes from the original input
1173
1499
 
1174
- 3. **If `c.implemented === false`** (stub):
1175
- - Add this banner comment above the affected element in the source file:
1176
- ```
1177
- /* TRDR DS — <c.name> (figmaId: <c.figmaId>) */
1178
- /* Implementação canônica pendente. Consulte https://trdr.mrocontent.com.br/componentes/<c.slug> */
1179
- /* Tokens recomendados: <list c.tokens[].token> */
1180
- ```
1181
- - Append an entry to `MISSING_COMPONENTS.md`:
1182
- ```markdown
1183
- ## <c.name>
1184
- - Slug: `<c.slug>` | figmaId: `<c.figmaId>` | Category: `<c.category>`
1185
- - Found in: <list of file:line>
1186
- - Description: <c.description>
1187
- - Recommended tokens: <c.tokens[]>
1188
- - Status: ⚠️ stub — code blocks pending
1189
- ```
1500
+ **Radio buttons (slug: `radio-button`):**
1501
+ Similar to checkbox restructure to DS anatomy while preserving `name`, `value`, `checked`.
1190
1502
 
1191
- 4. **If no slug matches** the detected pattern:
1192
- - Flag the pattern in `MISSING_COMPONENTS.md` under "Unmapped patterns" with the file location and a one-line description of the UI need.
1503
+ **Switches (slug: `switch`):**
1504
+ ```html
1505
+ <!-- BEFORE -->
1506
+ <div class="toggle"><input type="checkbox"></div>
1507
+ <!-- AFTER -->
1508
+ <button class="trdr-switch" role="switch" aria-checked="false">
1509
+ <span class="trdr-switch-track"><span class="trdr-switch-knob"></span></span>
1510
+ <span>Label text</span>
1511
+ </button>
1512
+ ```
1513
+
1514
+ **Dropdowns (slug: `dropdown`):**
1515
+ ```html
1516
+ <!-- BEFORE -->
1517
+ <select class="lang-selector"><option>PT</option><option>EN</option></select>
1518
+ <!-- AFTER -->
1519
+ <select class="trdr-dropdown"><option>PT</option><option>EN</option></select>
1520
+ ```
1521
+ - Preserve all `<option>` children, `name`, `id`, `value` attributes
1522
+
1523
+ **Badges (slug: `badge`):**
1524
+ ```html
1525
+ <!-- BEFORE -->
1526
+ <span class="badge badge-success">Active</span>
1527
+ <!-- AFTER -->
1528
+ <span class="trdr-badge trdr-badge-success">Active</span>
1529
+ ```
1530
+ - Detect variant from existing color/class: green/success → `trdr-badge-success`, blue/brand → `trdr-badge-brand`, etc.
1531
+
1532
+ **Segmented controls / tabs (slug: `segmented-control`, `abas`):**
1533
+ ```html
1534
+ <!-- BEFORE -->
1535
+ <div class="tabs">
1536
+ <button class="tab active">Tab 1</button>
1537
+ <button class="tab">Tab 2</button>
1538
+ </div>
1539
+ <!-- AFTER -->
1540
+ <div class="trdr-segment-control">
1541
+ <button class="trdr-segment trdr-segment-active">Tab 1</button>
1542
+ <button class="trdr-segment trdr-segment-inactive">Tab 2</button>
1543
+ </div>
1544
+ ```
1545
+
1546
+ **Tooltips (slug: `tooltip`):**
1547
+ - If `title=""` attribute: remove `title`, add DS tooltip structure around the element
1548
+ - If `data-tooltip=""`: adapt to DS tooltip pattern
1549
+ - Preserve the tooltip content text
1550
+
1551
+ 5. **Icons inside replaced components:** When the original element contained an inline SVG icon (e.g., Button with search icon), replace that SVG immediately with a Material Icon `<span>` using the correct size class from Step 6.6c-2 rules. Do NOT leave inline SVGs inside new DS component structures — this is an exception to "SVG replacement happens in Sub-fase D."
1552
+
1553
+ 6. **Clean up redundant CSS** — for each replaced element's custom class, remove properties now provided by DS:
1554
+ - Remove: `height`, `padding`, `font-family`, `font-size`, `font-weight`, `border`, `border-radius`, `background`, `color`, `cursor`, `transition`, `display`, `align-items`, `justify-content`
1555
+ - Keep: `width`, `min-width`, `gap`, position-specific props, state overrides, layout props (margin, grid-area)
1556
+
1557
+ 7. **Document in DS_PROGRESS.md** each replacement:
1558
+ ```
1559
+ - [x] button: src/Hero.tsx:42 — "Get Started" → trdr-btn-primary (simple swap)
1560
+ ```
1561
+
1562
+ ---
1563
+
1564
+ #### Step 6 — Pass 2: Complex-preservable replacements
1565
+
1566
+ For each candidate classified as `complex-preservable` in DS_ANALYSIS.md:
1567
+
1568
+ 1. **Read the full element context** — read the file and identify all:
1569
+ - Event handlers: `onClick`, `onChange`, `onSubmit`, `onKeyDown`, `onFocus`, `onBlur`, etc.
1570
+ - Conditional rendering: ternary expressions, `&&` conditionals
1571
+ - Dynamic props: `className={...}`, `style={...}`, spread props `{...rest}`
1572
+ - Data bindings: `value={state}`, `checked={state}`, `ref={ref}`
1573
+
1574
+ 2. **Apply DS structure while preserving all logic, using one of two strategies:**
1575
+
1576
+ **Strategy A — Class addition (when existing DOM structure is compatible with DS):**
1577
+ The element's DOM structure is close enough to the DS component. Add DS classes and remove conflicting custom CSS.
1578
+ ```tsx
1579
+ // BEFORE
1580
+ <button
1581
+ className={`btn ${isActive ? 'btn-active' : ''}`}
1582
+ onClick={handleClick}
1583
+ disabled={isLoading}
1584
+ >
1585
+ {isLoading ? 'Loading...' : 'Submit'}
1586
+ </button>
1587
+
1588
+ // AFTER — DS classes added, handlers/bindings preserved
1589
+ <button
1590
+ className={`trdr-btn trdr-btn-primary ${isActive ? 'btn-active' : ''}`}
1591
+ onClick={handleClick}
1592
+ disabled={isLoading}
1593
+ >
1594
+ {isLoading ? 'Loading...' : 'Submit'}
1595
+ </button>
1596
+ ```
1597
+
1598
+ **Strategy B — Structure wrap (when DS component requires different DOM structure):**
1599
+ The element needs DS DOM structure but has logic that must stay.
1600
+ ```tsx
1601
+ // BEFORE — checkbox with complex state
1602
+ <div className="filter-option">
1603
+ <input
1604
+ type="checkbox"
1605
+ id={`filter-${id}`}
1606
+ checked={filters.includes(id)}
1607
+ onChange={() => toggleFilter(id)}
1608
+ />
1609
+ <label htmlFor={`filter-${id}`}>{label}</label>
1610
+ </div>
1611
+
1612
+ // AFTER — DS checkbox structure, ALL logic preserved
1613
+ <label className="trdr-checkbox">
1614
+ <input
1615
+ type="checkbox"
1616
+ id={`filter-${id}`}
1617
+ checked={filters.includes(id)}
1618
+ onChange={() => toggleFilter(id)}
1619
+ />
1620
+ <span className="trdr-checkbox-box"></span>
1621
+ <span>{label}</span>
1622
+ </label>
1623
+ ```
1624
+
1625
+ 3. **NEVER remove or alter any of the following** (absolute rule):
1626
+ - `onClick`, `onChange`, `onSubmit`, `onKeyDown`, `onFocus`, `onBlur` handlers
1627
+ - `ref=`, `key=` props
1628
+ - `disabled={condition}`, `checked={condition}`, `value={state}` bindings
1629
+ - Conditional rendering (`{condition && ...}`, `{condition ? ... : ...}`)
1630
+ - Spread props (`{...rest}`, `{...props}`)
1631
+ - `id`, `name`, `data-*`, `aria-*` attributes
1632
+ - Custom `className` parts used in JS selectors (`querySelector`, `classList.toggle`)
1633
+
1634
+ 4. **For dynamically-toggled classes** (e.g., `classList.toggle('active')`):
1635
+ - Map the custom state class to a DS state class
1636
+ - Update ALL `classList.toggle/add/remove` calls to also toggle the DS class
1637
+ - Example: `el.classList.toggle('active')` → also add `el.classList.toggle('trdr-segment-active')`
1638
+
1639
+ 5. **Clean up redundant CSS** — same rules as Pass 1 step 6.
1640
+
1641
+ 6. **Document in DS_PROGRESS.md:**
1642
+ ```
1643
+ - [x] checkbox: src/Filters.tsx:88 — preserved: onChange, checked binding → trdr-checkbox (complex-preservable, Strategy B)
1644
+ ```
1645
+
1646
+ ---
1647
+
1648
+ #### Step 6 — Pass 3: Manual review flagging
1649
+
1650
+ For each candidate classified as `complex-manual` in DS_ANALYSIS.md:
1651
+
1652
+ 1. **Do NOT modify** the source file's component structure.
1653
+
1654
+ 2. **Add a TODO comment** in the source file above the element:
1655
+ ```
1656
+ <!-- TODO: TRDR DS — replace with [c.name] component. See DS_MIGRATION.md for details. -->
1657
+ ```
1658
+ For React/JSX:
1659
+ ```
1660
+ {/* TODO: TRDR DS — replace with [c.name] component. See DS_MIGRATION.md for details. */}
1661
+ ```
1662
+
1663
+ 3. **Add an entry to `DS_MIGRATION.md`** under `## Manual component review`:
1664
+ ```markdown
1665
+ ### [file:line] — [c.name]
1666
+ - **Reason:** [brief description of complexity]
1667
+ - **Existing structure:** [brief DOM outline]
1668
+ - **Suggested DS component:** [slug] ([variant])
1669
+ - **Suggested approach:** Strategy A (class addition) / Strategy B (structure wrap) / custom adaptation
1670
+ - **Handlers to preserve:** [list of event handlers found]
1671
+ - **Dynamic props:** [list of dynamic bindings]
1672
+ ```
1673
+
1674
+ ---
1675
+
1676
+ #### Step 6 — Stubs and unmapped patterns
1677
+
1678
+ **If `c.implemented === false`** (stub — not yet implemented in DS):
1679
+ - Add this banner comment above the affected element in the source file:
1680
+ ```
1681
+ /* TRDR DS — <c.name> (figmaId: <c.figmaId>) */
1682
+ /* Implementação canônica pendente. Consulte https://trdr.mrocontent.com.br/componentes/<c.slug> */
1683
+ /* Tokens recomendados: <list c.tokens[].token> */
1684
+ ```
1685
+ - Append an entry to `MISSING_COMPONENTS.md`:
1686
+ ```markdown
1687
+ ## <c.name>
1688
+ - Slug: `<c.slug>` | figmaId: `<c.figmaId>` | Category: `<c.category>`
1689
+ - Found in: <list of file:line>
1690
+ - Description: <c.description>
1691
+ - Recommended tokens: <c.tokens[]>
1692
+ - Status: ⚠️ stub — code blocks pending
1693
+ ```
1694
+
1695
+ **If no slug matches** the detected pattern:
1696
+ - Flag the pattern in `MISSING_COMPONENTS.md` under "Unmapped patterns" with the file location and a one-line description of the UI need.
1697
+
1698
+ **Do NOT replace domain-specific components** (course cards, lesson rows, trading panels, etc.) — document them as "sem equivalente DS".
1699
+
1700
+ ---
1701
+
1702
+ #### Step 6 — Final: Update progress
1193
1703
 
1194
- Update `DS_PROGRESS.md`: set `Sub-fase C: Components — ✅ COMPLETE` and mark each component as done.
1704
+ Update `DS_PROGRESS.md`: set `Sub-fase C: Components — ✅ COMPLETE` and add summary:
1705
+ ```
1706
+ ### Componentes DS Aplicados
1707
+ Simple swaps: [S]
1708
+ Complex-preservable: [P]
1709
+ Manual review: [M] (see DS_MIGRATION.md)
1710
+ Stubs: [T]
1711
+ Total: [S+P+M+T] candidates processed
1712
+
1713
+ [List each replacement with its classification]
1714
+ ```
1195
1715
 
1196
1716
  Output:
1197
1717
  ```
1198
- ✅ Sub-fase C completa — [N] componentes DS aplicados, [M] stubs marcados.
1718
+ ✅ Sub-fase C completa — [N] componentes DS implementados ([S] simple, [P] complex-preservable), [M] flagged para revisão manual, [T] stubs marcados.
1199
1719
 
1200
- Próximo: Sub-fase D — Final (logos + DS_MIGRATION.md)
1720
+ Próximo: Sub-fase D — Final (logos + ícones + DS_MIGRATION.md)
1201
1721
  Responda:
1202
1722
  - "continuar" / "continue" — finalizar migração
1203
1723
  - "parar" / "stop" — salvar progresso e parar aqui
@@ -1287,10 +1807,21 @@ For plain HTML and Vue (CDN approach), add to `<head>`:
1287
1807
 
1288
1808
  Add to the project's main CSS:
1289
1809
  ```css
1290
- /* Material Icons helpers */
1291
- .material-icons { font-size: 20px; display: inline-flex; align-items: center; color: inherit; user-select: none; }
1292
- .mi-sm { font-size: 16px; }
1293
- .mi-xs { font-size: 14px; }
1810
+ /* Material Icons helpers — TRDR DS */
1811
+ .material-icons {
1812
+ font-size: 20px; /* default = mi-md */
1813
+ display: inline-flex;
1814
+ align-items: center;
1815
+ color: inherit;
1816
+ user-select: none;
1817
+ }
1818
+ .mi-2xs { font-size: 12px; } /* very small indicators */
1819
+ .mi-xs { font-size: 14px; } /* compact UI */
1820
+ .mi-sm { font-size: 16px; } /* small icons */
1821
+ /* .mi-md — 20px — default, no class needed */
1822
+ .mi-lg { font-size: 24px; } /* standard Material Design size */
1823
+ .mi-xl { font-size: 28px; } /* larger icons */
1824
+ .mi-2xl { font-size: 32px; } /* hero/feature icons */
1294
1825
  ```
1295
1826
 
1296
1827
  **Step 6.6c — Add icon color classes** (do NOT use inline style for icon color — create CSS classes instead):
@@ -1303,6 +1834,49 @@ Add to the project's main CSS:
1303
1834
  .icon-muted { color: var(--content-tertiary); }
1304
1835
  ```
1305
1836
 
1837
+ **Step 6.6c-2 — Measure original SVG dimensions before replacement:**
1838
+
1839
+ For EACH inline `<svg>` element that will be replaced, determine the original rendered size:
1840
+
1841
+ 1. **Read the SVG's explicit size** — check for `width` and `height` attributes:
1842
+ ```html
1843
+ <svg width="24" height="24" ...> → originalSize = 24
1844
+ <svg width="16" height="16" ...> → originalSize = 16
1845
+ ```
1846
+ Use the `width` attribute value (icons are typically square). If `width` and `height` differ, use the larger value.
1847
+
1848
+ 2. **If no width/height attributes** — check the `viewBox`:
1849
+ ```html
1850
+ <svg viewBox="0 0 24 24" ...> → originalSize = 24 (4th value = viewBox height)
1851
+ ```
1852
+
1853
+ 3. **If no explicit size and no viewBox** — check CSS for the SVG's container:
1854
+ - Look for the SVG's parent element class or the SVG's own class
1855
+ - Search CSS files for `width`, `height`, or `font-size` applied to that selector
1856
+ - Example: `.icon { width: 18px; height: 18px; }` → originalSize = 18
1857
+
1858
+ 4. **If still undetermined** — assume 20px (the DS default) and add a comment:
1859
+ ```html
1860
+ <!-- TODO: verify icon size — original SVG had no explicit dimensions -->
1861
+ ```
1862
+
1863
+ 5. **Map originalSize to the correct size class/style:**
1864
+
1865
+ | Original SVG size | Replacement class/style | Notes |
1866
+ |---|---|---|
1867
+ | 12px | `.mi-2xs` | Very small indicator |
1868
+ | 14px | `.mi-xs` | Compact UI |
1869
+ | 16px | `.mi-sm` | Small icons |
1870
+ | 18px | `style="font-size:18px"` | Between sm and md — no standard class |
1871
+ | 20px | *(none — default)* | No class needed |
1872
+ | 22px | `style="font-size:22px"` | Between md and lg — no standard class |
1873
+ | 24px | `.mi-lg` | Standard Material Design size |
1874
+ | 28px | `.mi-xl` | Larger icons |
1875
+ | 32px | `.mi-2xl` | Hero/feature icons |
1876
+ | Any other Npx | `style="font-size:Npx"` | Exact size preservation |
1877
+
1878
+ **Priority:** Use a size class if one matches exactly. Only use inline `font-size` for non-standard sizes. NEVER use inline `style="color:..."` — color is ALWAYS via CSS class (Rule 11).
1879
+
1306
1880
  **Step 6.6d — Map SVG content to icon names:**
1307
1881
 
1308
1882
  Analyze the SVG path/shape content to identify the icon:
@@ -1329,14 +1903,42 @@ Analyze the SVG path/shape content to identify the icon:
1329
1903
 
1330
1904
  For SVG icons that cannot be mapped automatically: leave a `<!-- TODO: replace with Material Icon: [description] -->` comment and document in DS_MIGRATION.md.
1331
1905
 
1332
- **Step 6.6e — Replace by framework:**
1906
+ **Step 6.6e — Replace by framework (with size preservation):**
1907
+
1908
+ Use the `originalSize` measured in Step 6.6c-2 to select the correct size class or inline font-size.
1333
1909
 
1334
- | Framework | Replacement |
1335
- |-----------|------------|
1336
- | Plain HTML | `<span class="material-icons mi-sm">icon_name</span>` |
1337
- | React (CDN) | `<span className="material-icons mi-sm">icon_name</span>` |
1338
- | React (@mui) | `import SearchIcon from '@mui/icons-material/Search'` + `<SearchIcon sx={{ fontSize: 16 }} />` |
1339
- | Vue (CDN) | `<span class="material-icons mi-sm">icon_name</span>` |
1910
+ | Framework | Standard size (has class) | Non-standard size (no class) |
1911
+ |-----------|--------------------------|------------------------------|
1912
+ | Plain HTML | `<span class="material-icons {sizeClass}">icon_name</span>` | `<span class="material-icons" style="font-size:{N}px">icon_name</span>` |
1913
+ | React (CDN) | `<span className="material-icons {sizeClass}">icon_name</span>` | `<span className="material-icons" style={{fontSize:{N}}}>icon_name</span>` |
1914
+ | React (@mui) | `<IconName sx={{ fontSize: {originalSize} }} />` (omit `sx` if 24px — @mui default) | Same — @mui always uses `sx.fontSize` |
1915
+ | Vue (CDN) | `<span class="material-icons {sizeClass}">icon_name</span>` | `<span class="material-icons" style="font-size:{N}px">icon_name</span>` |
1916
+
1917
+ **Examples with size + color combined:**
1918
+ ```html
1919
+ <!-- Original: 16×16 search icon with brand color -->
1920
+ <svg width="16" height="16"><path d="M..." stroke="#00A8CC"/></svg>
1921
+ <!-- Replacement: class mi-sm (16px) + class icon-brand -->
1922
+ <span class="material-icons mi-sm icon-brand">search</span>
1923
+
1924
+ <!-- Original: 24×24 close icon, neutral color (currentColor) -->
1925
+ <svg width="24" height="24"><path d="M..." stroke="currentColor"/></svg>
1926
+ <!-- Replacement: class mi-lg (24px), no color class (inherits) -->
1927
+ <span class="material-icons mi-lg">close</span>
1928
+
1929
+ <!-- Original: 20×20 icon (default size) -->
1930
+ <svg width="20" height="20" viewBox="0 0 20 20"><path d="M..."/></svg>
1931
+ <!-- Replacement: no size class needed (20px is default) -->
1932
+ <span class="material-icons">settings</span>
1933
+
1934
+ <!-- Original: 18×18 icon (non-standard size) -->
1935
+ <svg width="18" height="18" viewBox="0 0 18 18"><path d="M..."/></svg>
1936
+ <!-- Replacement: inline font-size for non-standard size -->
1937
+ <span class="material-icons" style="font-size:18px">settings</span>
1938
+
1939
+ <!-- React @mui — 16px icon with brand color -->
1940
+ <SearchIcon className="icon-brand" sx={{ fontSize: 16 }} />
1941
+ ```
1340
1942
 
1341
1943
  **Color of icon** — ALWAYS via class, NEVER inline style:
1342
1944
  ```html
@@ -1541,71 +2143,86 @@ Catalog: TRDR DS v[catalog-version] ([implemented]/[total] components)
1541
2143
  Hub: https://trdr.mrocontent.com.br
1542
2144
  → Check DS_MIGRATION.md for manual steps
1543
2145
  → Stubs not yet canonical: see MISSING_COMPONENTS.md
2146
+ → Backup branch: `trdr-ds/backup-{timestamp}` — para desfazer: `/trdr-ds rollback`
2147
+ → Para remover o backup após validar: `git branch -D trdr-ds/backup-{timestamp}`
1544
2148
  ```
1545
2149
 
1546
2150
  ---
1547
2151
 
1548
2152
  ## RESUME MODE (when invoked with `resume` argument)
1549
2153
 
1550
- 1. Look for `DS_ANALYSIS.md` and `DS_PROGRESS.md` at the project root.
1551
- - If `DS_PROGRESS.md` not found: output `❌ No previous migration found. Run /trdr-ds to start a new one.`
1552
- - If `Status: COMPLETE`: output `✅ Migration already complete (finished [date]). Run /trdr-ds to check for new violations.`
2154
+ This is the primary way to continue a migration across multiple context windows. Each `/trdr-ds resume` picks up the next pending sprint.
2155
+
2156
+ 1. Look for `SPRINT_PLAN.md` and `DS_PROGRESS.md` at the project root.
2157
+ - If neither found: output `❌ No previous migration found. Run /trdr-ds to start a new one.`
2158
+ - If `DS_PROGRESS.md` has `Status: COMPLETE`: output `✅ Migration already complete (finished [date]). Run /trdr-ds to check for new violations.`
1553
2159
 
1554
- 2. Read both `DS_ANALYSIS.md` and `DS_PROGRESS.md`. Determine the current sub-fase:
1555
- - If `Sub-fase A: Foundation PENDING` or `IN_PROGRESS` resume Sub-fase A
1556
- - If `Sub-fase A: Foundation — ✅ COMPLETE` AND `Sub-fase B: Violations — PENDING` or `IN_PROGRESS` → resume Sub-fase B from first PENDING or IN_PROGRESS batch
1557
- - If `Sub-fase B — ✅ COMPLETE` AND `Sub-fase C: Components — PENDING` or `IN_PROGRESS` → resume Sub-fase C
1558
- - If `Sub-fase C — ✅ COMPLETE` AND `Sub-fase D: Final — PENDING` or `IN_PROGRESS` → resume Sub-fase D
2160
+ 2. Read `SPRINT_PLAN.md`. Find the first sprint with `Status: PENDING` or `Status: IN_PROGRESS`.
2161
+ - If all sprints are `✅ COMPLETE`: mark migration as COMPLETE in DS_PROGRESS.md and output summary.
1559
2162
 
1560
- 3. Output a resume summary:
2163
+ 3. Read `DS_PROGRESS.md` to understand overall state.
2164
+
2165
+ 4. Read **only the relevant section** of `DS_ANALYSIS.md` for the current sprint:
2166
+ - Foundation sprint: read `§ Project` section only
2167
+ - Violation sprint: read `§ By File` entries ONLY for the files listed in that sprint's scope
2168
+ - Components sprint: read `§ Component Replacement Candidates`
2169
+ - Final sprint: read `§ Logo Audit`
2170
+
2171
+ 5. Output a resume summary:
1561
2172
  ```
1562
- Resuming TRDR DS migration — [project name]
1563
- Sub-fase A (Foundation): [✅ / 🔄 / ⏳]
1564
- Sub-fase B (Violations): [done]/[total] lotes | [N] violações corrigidas
1565
- Sub-fase C (Components): [✅ / 🔄 / ⏳]
1566
- Sub-fase D (Final): [ / 🔄 / ]
2173
+ Resumindo migração TRDR DS — [project name]
2174
+
2175
+ 📋 Sprint Plan: [done]/[total] sprints completos ([percentage]%)
2176
+
2177
+ [For each sprint in SPRINT_PLAN.md:]
2178
+ Sprint 1 — Foundation ✅
2179
+ Sprint 2 — Violations: src/components/ ✅
2180
+ Sprint 3 — Violations: src/pages/ 🔄 ← retomando aqui
2181
+ Sprint 4 — Violations: src/app/ ⏳
2182
+ Sprint 5 — Components ⏳
2183
+ Sprint 6 — Final ⏳
1567
2184
 
1568
- Resuming at: **[Sub-fase atual]**
2185
+ Retomando: **Sprint [N] — [name]**
2186
+ Escopo: [sprint scope description]
1569
2187
  ```
1570
2188
 
1571
- 4. Continue the detected sub-fase from the correct point. All context is read from `DS_ANALYSIS.md` + `DS_PROGRESS.md` not from conversation history.
2189
+ 6. Execute the current sprint following the sprint lifecycle (read execute save STOP).
2190
+ All context is read from `SPRINT_PLAN.md` + `DS_ANALYSIS.md` (relevant section only) + `DS_PROGRESS.md` — never from conversation history.
1572
2191
 
1573
2192
  ---
1574
2193
 
1575
2194
  ## STATUS MODE (when invoked with `status` argument)
1576
2195
 
1577
- 1. Look for `DS_PROGRESS.md` at the project root.
1578
- - If not found: output `No migration in progress. Run /trdr-ds to start.`
2196
+ 1. Look for `SPRINT_PLAN.md` and `DS_PROGRESS.md` at the project root.
2197
+ - If neither found: output `No migration in progress. Run /trdr-ds to start.`
1579
2198
 
1580
- 2. Read `DS_PROGRESS.md` (and `DS_ANALYSIS.md` if present) and output a progress table — do NOT modify any files:
2199
+ 2. Read `SPRINT_PLAN.md` and `DS_PROGRESS.md` — do NOT modify any files. Output:
1581
2200
 
1582
2201
  ```
1583
2202
  ## TRDR DS — Migration Status
1584
2203
 
1585
2204
  Project: [name] | Started: [date] | Status: [IN_PROGRESS/PAUSED/COMPLETE]
1586
-
1587
- ### Sub-fase A: Foundation
1588
- | Step | File | Status |
1589
- |------|------|--------|
1590
- | tokens.css | [path] | ✅ / ⏳ |
1591
- | components.css | [path] | / |
1592
- | CLAUDE.md | CLAUDE.md | / |
1593
- | @import | [global-css] | / |
1594
-
1595
- ### Sub-fase B: Violations
1596
- | Lote | Pasta | Arquivos | Violações | Status |
1597
- |------|-------|----------|-----------|--------|
1598
- | 1 | src/components/ | 5 | 12 | ✅ COMPLETE |
1599
- | 2 | src/pages/ | 4 | 8 | 🔄 IN_PROGRESS |
1600
- | 3 | src/app/ | 5 | — | ⏳ PENDING |
1601
- | 4 | src/styles/ | 3 | — | ⏳ PENDING |
1602
-
1603
- ### Sub-fase C: Components — [✅ COMPLETE / ⏳ PENDING]
1604
- ### Sub-fase D: Final — [✅ COMPLETE / ⏳ PENDING]
1605
-
1606
- Progress: [N]% ([done]/[total] batches [violations_fixed]/[total_violations] violations fixed)
1607
-
1608
- To continue: `/trdr-ds resume`
2205
+ Backup: [branch name or NONE]
2206
+
2207
+ ### Sprint Progress
2208
+ | Sprint | Scope | Files | Violations | Status |
2209
+ |--------|-------|-------|------------|--------|
2210
+ | 1 | Foundation | 4 | | ✅ |
2211
+ | 2 | Violations: src/components/ | 12 | 34 | ✅ |
2212
+ | 3 | Violations: src/pages/ | 8 | 21 | 🔄 IN_PROGRESS |
2213
+ | 4 | Violations: src/app/ | 15 | 45 | ⏳ PENDING |
2214
+ | 5 | Violations: src/styles/ | 6 | 18 | ⏳ PENDING |
2215
+ | 6 | Components | [N] candidates | | PENDING |
2216
+ | 7 | Final | logos + icons | — | ⏳ PENDING |
2217
+
2218
+ ### Summary
2219
+ Sprints completos: [done]/[total] ([percentage]%)
2220
+ Violações corrigidas: [fixed]/[total_violations]
2221
+ Componentes aplicados: [applied]/[total_candidates]
2222
+
2223
+ ### Next Action
2224
+ → Sprint [N]: [name] — `/trdr-ds resume`
2225
+ Para desfazer tudo: `/trdr-ds rollback`
1609
2226
  ```
1610
2227
 
1611
2228
  ---
@@ -1624,6 +2241,65 @@ If either fetch fails, report which one and exit. Do NOT touch the snapshot if t
1624
2241
 
1625
2242
  ---
1626
2243
 
2244
+ ## ROLLBACK MODE (when invoked as `/trdr-ds rollback`)
2245
+
2246
+ 1. Look for `DS_PROGRESS.md` at the project root.
2247
+ - If not found: output `❌ Nenhuma migração encontrada. Nada para reverter.` and STOP.
2248
+ - If `Backup branch:` line is `NONE (user opted out)`: output `❌ Nenhum backup foi criado (você optou por continuar sem backup durante a migração). Rollback manual necessário.` and STOP.
2249
+
2250
+ 2. Read the `Backup branch:` value from `DS_PROGRESS.md`. Save as `backupBranch`.
2251
+ Read the `Original branch:` value. Save as `originalBranch`.
2252
+
2253
+ 3. Verify the backup branch still exists:
2254
+ ```bash
2255
+ git rev-parse --verify {backupBranch} 2>/dev/null
2256
+ ```
2257
+ If it doesn't exist: output `❌ Branch de backup \`{backupBranch}\` não encontrado. Pode ter sido apagado manualmente.` and STOP.
2258
+
2259
+ 4. Confirm with the user:
2260
+ ```
2261
+ ⚠️ ROLLBACK: Isto vai reverter TODAS as alterações feitas pela migração TRDR DS.
2262
+
2263
+ Backup branch: {backupBranch}
2264
+ Branch atual: {currentBranch}
2265
+ Status da migração: {status from DS_PROGRESS.md}
2266
+
2267
+ Todos os arquivos modificados pela migração serão restaurados ao estado do backup.
2268
+ Arquivos DS criados (DS_ANALYSIS.md, DS_PROGRESS.md, DS_MIGRATION.md, MISSING_COMPONENTS.md, CLAUDE.md, tokens.css, components.css) serão revertidos ou removidos.
2269
+
2270
+ Responda:
2271
+ - "confirmar" — executar rollback
2272
+ - "cancelar" — abortar
2273
+ ```
2274
+ **STOP. Wait for reply.**
2275
+
2276
+ 5. If `"cancelar"`: output `Rollback cancelado.` and STOP.
2277
+
2278
+ 6. If `"confirmar"`, execute the rollback:
2279
+
2280
+ a. Ensure we're on the original branch:
2281
+ ```bash
2282
+ git checkout {originalBranch}
2283
+ ```
2284
+
2285
+ b. Reset the working tree to the backup state:
2286
+ ```bash
2287
+ git reset --hard {backupBranch}
2288
+ ```
2289
+
2290
+ 7. Output:
2291
+ ```
2292
+ ✅ Rollback completo.
2293
+
2294
+ Branch `{originalBranch}` restaurado ao estado de `{backupBranch}`.
2295
+ Todos os arquivos modificados pela migração foram revertidos.
2296
+
2297
+ O backup branch `{backupBranch}` ainda existe. Para removê-lo:
2298
+ git branch -D {backupBranch}
2299
+ ```
2300
+
2301
+ ---
2302
+
1627
2303
  ## LIVE HUB REFERENCE (canonical fallback)
1628
2304
 
1629
2305
  When the developer asks about a component, token, or rule that is not in the local snapshot, fetch from the Hub:
@@ -93,7 +93,9 @@ Para `animation-delay` calculado: converter para `style="--delay: Xs"` + CSS `an
93
93
  - ✅ `class="text-brand"` com `.text-brand { color: var(--content-brand); }` no CSS
94
94
 
95
95
  ### Regra 11 — Ícones via biblioteca, nunca SVG inline
96
- Use Material Icons (HTML/Vue) ou @mui/icons-material (React). A cor dos ícones SEMPRE via classe CSS com token — nunca inline style.
96
+ Use Material Icons (HTML/Vue) ou @mui/icons-material (React). A cor dos ícones SEMPRE via classe CSS com token — nunca inline style. O tamanho deve preservar as dimensões do ícone original.
97
+ - Escala de tamanhos: `.mi-2xs` (12px), `.mi-xs` (14px), `.mi-sm` (16px), default (20px), `.mi-lg` (24px), `.mi-xl` (28px), `.mi-2xl` (32px)
98
+ - Para tamanhos não padrão: `style="font-size:Npx"` (aceito APENAS para font-size de ícones, nunca para cor)
97
99
  - ❌ `<svg><path d="..."/></svg>` para ícones
98
100
  - ❌ `<span class="material-icons" style="color:#00D4FF">search</span>`
99
101
  - ✅ `<span class="material-icons mi-sm icon-brand">search</span>` com `.icon-brand { color: var(--content-brand); }`