@jossuealcala/madre 1.0.2 → 1.0.3

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.
Files changed (76) hide show
  1. package/CHANGELOG.en.md +69 -1
  2. package/CHANGELOG.md +69 -1
  3. package/README.en.md +11 -15
  4. package/README.md +3 -3
  5. package/bin/madre.cjs +40 -0
  6. package/bin/madre.mjs +5 -0
  7. package/docs/REFERENCE.md +29 -3
  8. package/docs/SDK.md +4 -2
  9. package/docs/en/REFERENCE.md +29 -3
  10. package/docs/en/SDK.md +4 -2
  11. package/docs/training/README.md +28 -1
  12. package/docs/training/train.sh +5 -1
  13. package/package.json +3 -3
  14. package/public/app.js +1626 -151
  15. package/public/attribution.js +44 -1
  16. package/public/brands.js +20 -5
  17. package/public/code-tools.js +143 -0
  18. package/public/editor.js +20 -4
  19. package/public/es.js +393 -25
  20. package/public/hardware.js +50 -0
  21. package/public/index.html +5 -1
  22. package/public/macroverso.js +187 -96
  23. package/public/market-art.js +161 -0
  24. package/public/market-view.js +529 -0
  25. package/public/market.js +189 -0
  26. package/public/neural.js +110 -0
  27. package/public/nostromo-engine.js +412 -47
  28. package/public/power.js +100 -0
  29. package/public/resay.js +5 -0
  30. package/public/salas-mac.css +98 -14
  31. package/public/salas-mac.html +9 -1
  32. package/public/salas-mac.js +307 -30
  33. package/public/styles.css +838 -61
  34. package/public/tour.js +48 -6
  35. package/public/troubleshooting.js +6 -1
  36. package/public/wallpaper.js +275 -0
  37. package/src/adapters/cursor.mjs +96 -0
  38. package/src/adapters/gemini.mjs +10 -3
  39. package/src/adapters/madre.mjs +2 -1
  40. package/src/auth-probe.mjs +143 -12
  41. package/src/bridge/policy.mjs +1 -1
  42. package/src/capabilities.mjs +9 -0
  43. package/src/checkpoint.mjs +16 -1
  44. package/src/credentials.mjs +3 -0
  45. package/src/dataset.mjs +76 -4
  46. package/src/enlaces.mjs +208 -2
  47. package/src/extensions.mjs +11 -3
  48. package/src/i18n.mjs +16 -0
  49. package/src/looks.mjs +125 -2
  50. package/src/market-key.mjs +8 -0
  51. package/src/market-remote.mjs +239 -0
  52. package/src/models.mjs +4 -0
  53. package/src/module-scope.mjs +68 -0
  54. package/src/modules/ahp.mjs +102 -7
  55. package/src/modules/bishop-exam.mjs +122 -0
  56. package/src/modules/bishop.mjs +71 -12
  57. package/src/modules/enlaces.mjs +87 -6
  58. package/src/modules/image-studio.mjs +10 -1
  59. package/src/modules/intents.mjs +3 -1
  60. package/src/modules/local-models.mjs +124 -0
  61. package/src/modules/ollama.mjs +12 -3
  62. package/src/modules/playwright.mjs +73 -15
  63. package/src/modules/sdk.mjs +61 -9
  64. package/src/npm-launch.mjs +18 -0
  65. package/src/ollama.mjs +6 -5
  66. package/src/outbound.mjs +9 -1
  67. package/src/ports.mjs +4 -2
  68. package/src/room/control.mjs +1 -1
  69. package/src/room/prompt.mjs +13 -2
  70. package/src/room.mjs +14 -4
  71. package/src/router.mjs +1 -1
  72. package/src/runs.mjs +4 -1
  73. package/src/runtime-detection.mjs +9 -0
  74. package/src/salas.mjs +26 -0
  75. package/src/server.mjs +617 -48
  76. package/src/setup.mjs +1 -1
@@ -33,6 +33,7 @@ body.salas-mac {
33
33
  :root[data-wallpaper="tropical"] .sm-sky { background: var(--wp-tropical); }
34
34
  :root[data-wallpaper="tradicion"] .sm-sky { background: var(--wp-tradicion); }
35
35
  :root[data-wallpaper="urbania"] .sm-sky { background: var(--wp-urbania); }
36
+ :root[data-wallpaper="custom"] .sm-sky { background: var(--wp-custom); }
36
37
  :root[data-wallpaper] .sm-sky { inset: calc(-2 * var(--wp-blur-on, 0px)); filter: blur(var(--wp-blur-on, 0px)); }
37
38
  :root[data-wallpaper] .sm-sky::after { display: none; }
38
39
  :root:not([data-scheme="light"]) .sm-sky::after {
@@ -56,7 +57,7 @@ body.salas-mac {
56
57
  .sm-brand { display: inline-flex; align-items: center; flex: none; color: var(--text); border-radius: 8px; padding: 4px 2px; }
57
58
  .sm-brand .brand-logo { height: 15px; }
58
59
  .sm-back-room { display: inline-flex; align-items: center; gap: 3px; flex: none; height: 26px; padding: 0 9px 0 5px; border-radius: 6px; background: var(--surface, var(--panel)); box-shadow: var(--key-rest); color: var(--text-2); font-weight: 600; text-decoration: none; }
59
- .sm-back-room svg { width: 14px; height: 14px; }
60
+ .sm-back-room svg { width: var(--ico-sm); height: var(--ico-sm); }
60
61
  .sm-back-room:hover { color: var(--text); box-shadow: var(--key-over, var(--key-rest)); }
61
62
  .sm-crumb { flex: none; font-weight: 600; color: var(--text); }
62
63
  .sm-crumb::before { content: '/ '; color: var(--text-3); font-weight: 400; }
@@ -91,6 +92,7 @@ body.salas-mac {
91
92
  .sm-agent-key::after { content: ''; position: absolute; right: -2px; bottom: -2px; width: 8px; height: 8px; border-radius: 50%; background: var(--session-ok); box-shadow: 0 0 0 2px var(--surface, var(--panel)); }
92
93
  .sm-agent-key.wait::after { background: var(--session-wait); }
93
94
  .sm-agent-key.bad::after { background: var(--session-bad); }
95
+ .sm-agent-key.off > :first-child { filter: grayscale(1); opacity: .45; }
94
96
  .sm-agent-key:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
95
97
  /* What asks for the person: who waits, a newer MADRE. */
96
98
  .sm-pill { display: inline-flex; align-items: center; gap: 6px; flex: none; height: 26px; padding: 0 11px; border-radius: 999px; font-family: var(--mono); font-size: 11px; font-weight: 600; letter-spacing: .02em; text-decoration: none; white-space: nowrap; }
@@ -118,7 +120,7 @@ body.salas-mac {
118
120
  .sm-spacer { flex: 1; }
119
121
  /* The bar's keys are the room's bar keys (styles.css, .mother-button, .tree-button, .stop-all). */
120
122
  .sm-barkey, .sm-stop { display: inline-flex; align-items: center; gap: 7px; height: 26px; padding: 0 10px; border: 0; border-radius: 6px; font-family: var(--mono); font-size: 10px; font-weight: 400; letter-spacing: .18em; text-transform: uppercase; white-space: nowrap; cursor: pointer; }
121
- .sm-barkey svg, .sm-stop svg { width: 14px; height: 14px; }
123
+ .sm-barkey svg, .sm-stop svg { width: var(--ico-sm); height: var(--ico-sm); }
122
124
  .sm-stop { box-shadow: inset 0 0 0 1px var(--terror); background: color-mix(in srgb, var(--terror) 12%, transparent); color: var(--terror); }
123
125
  .sm-stop:hover, .sm-stop.armed { background: var(--terror); color: #fff; }
124
126
  /* Whatever the page hides stays hidden, whatever its class lays out. */
@@ -131,7 +133,7 @@ body.salas-mac {
131
133
  .sm-icon-key:hover { color: var(--text); box-shadow: var(--key-over, var(--key-rest)); }
132
134
  .sm-icon-key:active { box-shadow: var(--key-down); }
133
135
  .sm-icon-key:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
134
- .sm-icon-key svg { width: 16px; height: 16px; }
136
+ .sm-icon-key svg { width: var(--ico-sm); height: var(--ico-sm); }
135
137
  /* A link that cannot be followed yet (BISHOP waking) looks and acts like a disabled key. */
136
138
  .sm-btn[aria-disabled="true"], .sm-icon-key[aria-disabled="true"] { opacity: .45; box-shadow: none; pointer-events: none; }
137
139
 
@@ -416,8 +418,7 @@ body.sm-in-macro { overflow: hidden; }
416
418
  kinds of memory under them and the keys at the end. */
417
419
  .mv-head { position: absolute; left: 0; right: 0; top: 0; z-index: 2; margin: 0; }
418
420
  .mv-head .mother-title { margin: 0; text-transform: uppercase; }
419
- .mv-back { display: inline-flex; align-items: center; gap: 6px; }
420
- .mv-back svg { width: 13px; height: 13px; flex: none; }
421
+
421
422
  .mv-hint { position: absolute; left: 20px; bottom: 14px; margin: 0; font-size: 11.5px; color: rgba(242, 241, 238, .42); pointer-events: none; }
422
423
 
423
424
  .mv-card { position: absolute; right: 40px; top: 50%; translate: 0 -50%; width: min(360px, 34vw); display: grid; gap: 10px; padding: 22px 22px 18px; border-radius: 22px; background: rgba(18, 18, 22, .78); box-shadow: inset 0 1px 0 rgba(255, 255, 255, .07), 0 30px 60px -30px rgba(0, 0, 0, .9); -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); animation: mv-card-in 420ms var(--ease-out, ease-out); }
@@ -547,11 +548,20 @@ body.sm-in-macro { overflow: hidden; }
547
548
  /* The room's search (styles.css, .settings-search), not the sheet's uppercase field label. */
548
549
  .sm-picker-head > .sm-picker-search { flex: 1 1 auto; max-width: none; display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 10px; font-size: 13.5px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--text-2); }
549
550
  .sm-picker-search input::-webkit-search-cancel-button { cursor: pointer; }
551
+ /* A project from nothing (2026-10-17): the name, where it goes, one key. */
552
+ .sm-new-project { display: grid; gap: 12px; justify-items: start; padding: 18px 2px 6px; }
553
+ .sm-new-name { display: grid; gap: 6px; width: min(100%, 420px); font-size: 13px; color: var(--text-2); }
554
+ .sm-new-name input { height: 38px; min-width: 0; padding: 0 12px; border: 0; border-radius: 10px; background: transparent; color: var(--text); font: inherit; font-size: 15px; box-shadow: var(--key-track); outline: 0; }
555
+ .sm-new-name input:focus { box-shadow: var(--key-down), 0 0 0 2px color-mix(in srgb, var(--s-acc) 45%, transparent); }
556
+ .sm-new-where { margin: 0; font-size: 13px; color: var(--text-2); }
557
+ .sm-new-where code { font-family: var(--mono); font-size: 12px; color: var(--text); }
558
+ .sm-new-other { margin-left: 4px; padding: 0; border: 0; background: none; color: var(--s-acc); font: inherit; font-size: 13px; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
559
+ .sm-new-project .error:empty { display: none; }
550
560
  .sm-picker-line { display: flex; align-items: center; gap: 10px; min-width: 0; height: 28px; font-size: 13px; color: var(--text-2); }
551
561
  .sm-picker-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
552
562
  .sm-where { min-width: 0; font-family: var(--mono); font-size: 12px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
553
563
  .sm-up { flex: none; gap: 4px; padding: 0 10px 0 6px; }
554
- .sm-up svg { width: 14px; height: 14px; }
564
+ .sm-up svg { width: var(--ico-sm); height: var(--ico-sm); }
555
565
  .sm-fold-grid { display: grid; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); grid-template-rows: repeat(var(--rows, 4), 54px); gap: 8px; }
556
566
  .sm-fold-grid > .sm-fold { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 11px; min-width: 0; padding: 0 8px 0 12px; border-radius: 12px; background: var(--surface, var(--panel)); box-shadow: var(--key-rest); font-size: inherit; font-weight: inherit; letter-spacing: 0; text-transform: none; color: var(--text); cursor: pointer; transition: box-shadow calc(160ms * var(--motion-scale, 1)) var(--ease-out, ease-out), background-color calc(160ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
557
567
  .sm-fold-grid > .sm-fold:hover { box-shadow: var(--key-over, var(--key-rest)); }
@@ -571,7 +581,7 @@ body.sm-in-macro { overflow: hidden; }
571
581
  .sm-fold-words b { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
572
582
  .sm-fold-words small { font-family: var(--mono); font-size: 11px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
573
583
  .sm-into { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--text-2); cursor: pointer; }
574
- .sm-into svg { width: 14px; height: 14px; }
584
+ .sm-into svg { width: var(--ico-sm); height: var(--ico-sm); }
575
585
  .sm-into:hover, .sm-into:focus-visible { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); outline: 0; }
576
586
  .sm-fold-none { grid-column: 1 / -1; grid-row: 1 / -1; align-self: center; justify-self: center; max-width: 46ch; margin: 0; text-align: center; font-size: 13.5px; line-height: 1.5; color: var(--text-2); }
577
587
  .sm-picker-foot { display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 30px; }
@@ -623,6 +633,8 @@ body.sm-in-macro { overflow: hidden; }
623
633
  /* Everything a connection needs that does not fit on the row: the page a sign-in opened, the
624
634
  code it is waiting for, the key form. Home used to send you to a project for all of it. */
625
635
  .sm-agent-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
636
+ .sm-agent-device { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; color: var(--text-2); }
637
+ .sm-agent-device code { font-family: var(--mono); font-size: 15px; letter-spacing: .12em; color: var(--text); user-select: all; }
626
638
  .sm-agent-code { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 240px; }
627
639
  .sm-agent-code input, .sm-agent-key-form input, .sm-agent-key-form select { height: 32px; min-width: 0; padding: 0 10px; border: 0; border-radius: 9px; background: transparent; color: var(--text); font: inherit; font-size: 13px; box-shadow: var(--key-track); outline: 0; }
628
640
  .sm-agent-code input { flex: 1 1 160px; }
@@ -633,6 +645,14 @@ body.sm-in-macro { overflow: hidden; }
633
645
  .sm-agent-key-link { font-size: 12.5px; color: var(--s-acc); text-decoration: none; }
634
646
  .sm-agent-key-link:hover { text-decoration: underline; }
635
647
  .sm-agent-command { grid-column: 1 / -1; font-family: var(--mono); font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; }
648
+ /* The other way in, folded: the same install or sign-in typed in a terminal, for whoever prefers it. */
649
+ .sm-terminal-way > summary { width: max-content; font-size: 12.5px; color: var(--text-3); cursor: pointer; list-style: none; }
650
+ .sm-terminal-way > summary::-webkit-details-marker { display: none; }
651
+ .sm-terminal-way > summary::after { content: ' ›'; }
652
+ .sm-terminal-way[open] > summary::after { content: ' ⌄'; }
653
+ .sm-terminal-way > summary:hover { color: var(--text-2); }
654
+ .sm-terminal-way[open] { display: grid; gap: 8px; justify-items: start; }
655
+ .sm-terminal-lines { display: grid; gap: 4px; justify-self: stretch; padding: 10px 12px; border-radius: 10px; box-shadow: var(--key-track); }
636
656
 
637
657
  /* LINKING TWO ROOMS, step by step (salas-mac.js, openLinkSheet), in the room's settings language:
638
658
  the step and its question, what it decides; the choices on a card, a row each, the safe one
@@ -671,7 +691,7 @@ body.sm-in-macro { overflow: hidden; }
671
691
  .lw-allows li { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; line-height: 1.45; color: var(--text); }
672
692
  .lw-allows li.no { color: var(--text-2); }
673
693
  .lw-allows li i { flex: none; display: grid; place-items: center; width: 18px; height: 18px; margin-top: 0; border-radius: 50%; }
674
- .lw-allows li i svg { width: 12px; height: 12px; }
694
+ .lw-allows li i svg { width: var(--ico-xs); height: var(--ico-xs); }
675
695
  .lw-allows li.yes i { color: color-mix(in srgb, var(--s-acc) 78%, var(--text)); background: color-mix(in srgb, var(--s-acc) 16%, transparent); }
676
696
  .lw-allows li.no i { color: var(--text-2); background: color-mix(in srgb, var(--text) 7%, transparent); }
677
697
  /* Two projects already connected: how, and where to change it, in place of a new connection. */
@@ -789,14 +809,14 @@ dialog.sm-sheet.sm-settings[open] { --sm-sheet-pad: 20px; }
789
809
  /* A project's right-click: the bar card's material, a row per thing it can do. */
790
810
  .bar-card.sm-menu { width: auto; min-width: 214px; padding: 6px; display: grid; gap: 2px; }
791
811
  .sm-menu-item { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 34px; padding: 0 10px; border: 0; border-radius: 9px; background: transparent; color: var(--text); font-family: var(--read); font-size: 13px; text-align: left; cursor: pointer; }
792
- .sm-menu-item svg { flex: none; width: 16px; height: 16px; color: var(--phosphor); }
812
+ .sm-menu-item svg { flex: none; width: var(--ico-sm); height: var(--ico-sm); color: var(--phosphor); }
793
813
  .sm-menu-item:hover, .sm-menu-item:focus-visible { background: color-mix(in srgb, var(--text) 7%, transparent); outline: none; }
794
814
  .sm-menu-item.danger, .sm-menu-item.danger svg { color: var(--danger, var(--terror)); }
795
815
  .sm-menu-sep { display: block; height: 1px; margin: 4px 8px; background: var(--line); }
796
816
  /* The card's own key for that menu, for whoever does not right-click: quiet until the card is
797
817
  under the pointer. */
798
818
  .sm-card-more { flex: none; display: grid; place-items: center; width: 26px; height: 26px; margin: -4px -6px -4px 0; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--text-2); opacity: .7; cursor: pointer; transition: opacity calc(160ms * var(--motion-scale, 1)) var(--ease-out, ease-out), background-color calc(160ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
799
- .sm-card-more svg { width: 16px; height: 16px; }
819
+ .sm-card-more svg { width: var(--ico-sm); height: var(--ico-sm); }
800
820
  .sm-card:hover .sm-card-more, .sm-card-more:focus-visible { opacity: 1; }
801
821
  .sm-card-more:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
802
822
  .sm-card-more:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
@@ -840,7 +860,7 @@ dialog.sm-sheet.sm-settings[open] { --sm-sheet-pad: 20px; }
840
860
  :root[data-home-text="smaller"] .sm-main { zoom: .93; }
841
861
  /* A newer MADRE in the bar: a key now, that opens Home's Version. */
842
862
  button.sm-pill { border: 0; cursor: pointer; }
843
- .sm-pill.is-update svg { width: 14px; height: 14px; flex: none; }
863
+ .sm-pill.is-update svg { width: var(--ico-sm); height: var(--ico-sm); flex: none; }
844
864
  .sm-pill.is-update:hover { background: color-mix(in srgb, var(--session-wait) 28%, transparent); }
845
865
  .sm-pill.is-update:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
846
866
  /* A project's name inside the wizard's sentences stands out (salas-mac.js, sayBold). */
@@ -895,13 +915,13 @@ dialog.sm-sheet.sm-add-sheet { --sm-sheet-w: 560px; }
895
915
  .sm-w-foot.mono { font-family: var(--mono); font-size: 11px !important; overflow-wrap: anywhere; }
896
916
  /* What a tile is, in the accent: on its row of «Add to Home» and at the head of its menu. */
897
917
  .sm-tile-icon { flex: none; display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 10px; background: color-mix(in srgb, var(--s-acc) 14%, transparent); color: color-mix(in srgb, var(--s-acc) 82%, var(--text)); }
898
- .sm-tile-icon svg { width: 20px; height: 20px; }
918
+ .sm-tile-icon svg { width: var(--ico-md); height: var(--ico-md); }
899
919
  .sm-add-row { justify-content: flex-start; }
900
920
  .sm-add-row .sm-add-words { flex: 1; }
901
921
  .sm-add-sheet .sm-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
902
922
  .sm-menu-head { display: flex; align-items: center; gap: 8px; }
903
923
  .sm-menu-head .sm-tile-icon { width: 22px; height: 22px; border-radius: 6px; }
904
- .sm-menu-head .sm-tile-icon svg { width: 14px; height: 14px; }
924
+ .sm-menu-head .sm-tile-icon svg { width: var(--ico-xs); height: var(--ico-xs); }
905
925
  .salas-mac .sm-menu-item svg { color: var(--s-acc); }
906
926
 
907
927
  /* THE MAP, INTERACTIVE (2026-10-13): a project under the pointer, or chosen, lights its own lines
@@ -943,7 +963,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
943
963
  .sm-graph-quiet { font-size: 12.5px; line-height: 1.5; color: var(--text-3); }
944
964
  /* The order of the projects, beside the filter that chooses which of them show. */
945
965
  .sm-order { flex: none; gap: 6px; height: 36px; padding: 0 12px; }
946
- .sm-order svg { width: 16px; height: 16px; color: var(--s-acc); }
966
+ .sm-order svg { width: var(--ico-sm); height: var(--ico-sm); color: var(--s-acc); }
947
967
  .sm-menu-head + .sm-menu-item { margin-top: 2px; }
948
968
  .sm-menu .sm-menu-head:last-child { max-width: 240px; padding-bottom: 8px; font-size: 11.5px; font-weight: 450; letter-spacing: 0; text-transform: none; line-height: 1.4; }
949
969
 
@@ -1074,6 +1094,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1074
1094
  :root[data-wallpaper="urbania"] { --wp-now: var(--wp-urbania); }
1075
1095
  :root[data-wallpaper="ventura"] { --wp-now: var(--wp-ventura); }
1076
1096
  :root[data-wallpaper="xico"] { --wp-now: var(--wp-xico); }
1097
+ :root[data-wallpaper="custom"] { --wp-now: var(--wp-custom); }
1077
1098
  .sm-drawer .sm-projects > .sm-card { isolation: isolate; overflow: hidden; }
1078
1099
  .sm-drawer .sm-projects > .sm-card:is([data-wp], :root[data-wallpaper] .sm-card)::before {
1079
1100
  content: ''; position: absolute; inset: -24px; z-index: -2; pointer-events: none;
@@ -1129,6 +1150,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1129
1150
  .sm-card[data-wp="jarrito"] { --wp-card: var(--wp-jarrito); --wp-size: cover; }
1130
1151
  .sm-card[data-wp="magna"] { --wp-card: var(--wp-magna); --wp-size: cover; }
1131
1152
  .sm-card[data-wp="oceano"] { --wp-card: var(--wp-oceano); --wp-size: cover; }
1153
+ .sm-card[data-wp="custom"] { --wp-card: var(--wp-custom); --wp-size: cover; }
1132
1154
  .sm-card[data-wp="paradise"] { --wp-card: var(--wp-paradise); --wp-size: cover; }
1133
1155
  .sm-card[data-wp="quila"] { --wp-card: var(--wp-quila); --wp-size: cover; }
1134
1156
  .sm-card[data-wp="tradicion"] { --wp-card: var(--wp-tradicion); --wp-size: cover; }
@@ -1296,3 +1318,65 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1296
1318
  modal is when it opens), the browser drew its ring around the whole page. Focus moves to what is
1297
1319
  inside it; the dialog itself draws no ring. */
1298
1320
  dialog.sm-sheet:focus, dialog.sm-sheet:focus-visible { outline: none; }
1321
+
1322
+ /* 1.0.3 (2026-10-17) · Connections and the Project map lift less under the pointer, as Modules and
1323
+ Diagnostics do in a project. The widgets key pulses once under the pointer, and its squares fill
1324
+ while the sheet it opens is there. */
1325
+ .salas-mac :is(#sm-tb-links, #sm-macro):is(:hover, :focus-visible) { box-shadow: var(--key-rest), 0 3px 8px -5px var(--key-lift, rgba(22, 30, 22, .16)); }
1326
+ #sm-add-widgets:is(:hover, :focus-visible) svg { animation: icon-pulse calc(520ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
1327
+ #sm-add-widgets svg rect { fill: currentColor; fill-opacity: 0; transition: fill-opacity calc(200ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
1328
+ #sm-add-widgets:active svg rect, #sm-add-widgets.filled svg rect { fill-opacity: 1; }
1329
+ @keyframes icon-pulse { 0% { transform: scale(1); } 40% { transform: scale(1.16); } 70% { transform: scale(.95); } 100% { transform: scale(1); } }
1330
+ @media (prefers-reduced-motion: reduce) { #sm-add-widgets:is(:hover, :focus-visible) svg { animation: none; } }
1331
+
1332
+ /* While the Project map is open, a first-time hint that points at Home steps aside, with its ring:
1333
+ what it speaks of is under the map. It is not read yet, so it comes back when the map closes.
1334
+ The map's own hint stays (tour.js, data-under). */
1335
+ body.sm-in-macro > :is(.tour-hint, .tour-hint-away, .hint-spot)[data-under="page"] { display: none !important; }
1336
+
1337
+ /* ==========================================================================================
1338
+ MADRE, IN THE AIR (2026-10-17)
1339
+ ------------------------------------------------------------------------------------------
1340
+ Home only, on a sky with no wallpaper: MADRE is there as a gas, two slow clouds in her palette,
1341
+ a breath under everything and never a shape you can point at. Light: her green over the pale
1342
+ ground. Dark: her phosphor with a trace of the Coordinator's plum and of the sky's cyan, kept
1343
+ lower, since on black a colour carries further. Gradients only (no blur filter) that fall off
1344
+ on an eased curve so no ring shows, moved by transform; still for whoever asks for less motion.
1345
+ ========================================================================================== */
1346
+ .sm-gas { display: none; }
1347
+ :root:not([data-wallpaper]) .sm-gas {
1348
+ display: block; position: absolute; inset: -18vmax; pointer-events: none; will-change: transform, opacity;
1349
+ }
1350
+ :root:not([data-wallpaper]) .sm-gas.a { animation: madre-gas-a calc(52s * var(--motion-scale, 1)) ease-in-out infinite alternate; }
1351
+ :root:not([data-wallpaper]) .sm-gas.b { animation: madre-gas-b calc(68s * var(--motion-scale, 1)) ease-in-out infinite alternate; }
1352
+ :root[data-scheme="light"]:not([data-wallpaper]) .sm-gas.a {
1353
+ background:
1354
+ radial-gradient(40vmax 30vmax at 34% 64%, rgb(47 138 28 / .15), rgb(47 138 28 / .12) 18%, rgb(47 138 28 / .075) 38%, rgb(47 138 28 / .035) 58%, rgb(47 138 28 / .01) 78%, transparent),
1355
+ radial-gradient(32vmax 24vmax at 70% 34%, rgb(94 196 120 / .14), rgb(94 196 120 / .1) 20%, rgb(94 196 120 / .055) 42%, rgb(94 196 120 / .02) 66%, transparent);
1356
+ }
1357
+ :root[data-scheme="light"]:not([data-wallpaper]) .sm-gas.b {
1358
+ background:
1359
+ radial-gradient(34vmax 22vmax at 58% 82%, rgb(140 214 86 / .12), rgb(140 214 86 / .085) 22%, rgb(140 214 86 / .045) 46%, rgb(140 214 86 / .015) 70%, transparent),
1360
+ radial-gradient(26vmax 20vmax at 20% 22%, rgb(47 138 28 / .09), rgb(47 138 28 / .06) 24%, rgb(47 138 28 / .025) 52%, transparent 80%);
1361
+ }
1362
+ :root[data-scheme="dark"]:not([data-wallpaper]) .sm-gas.a {
1363
+ background:
1364
+ radial-gradient(40vmax 30vmax at 32% 66%, rgb(155 255 102 / .075), rgb(155 255 102 / .055) 18%, rgb(155 255 102 / .032) 38%, rgb(155 255 102 / .014) 60%, transparent 82%),
1365
+ radial-gradient(30vmax 22vmax at 74% 30%, rgb(61 198 255 / .05), rgb(61 198 255 / .034) 22%, rgb(61 198 255 / .016) 48%, transparent 76%);
1366
+ }
1367
+ :root[data-scheme="dark"]:not([data-wallpaper]) .sm-gas.b {
1368
+ background:
1369
+ radial-gradient(34vmax 22vmax at 60% 84%, rgb(140 70 150 / .07), rgb(140 70 150 / .05) 22%, rgb(140 70 150 / .025) 48%, transparent 76%),
1370
+ radial-gradient(26vmax 20vmax at 18% 20%, rgb(155 255 102 / .05), rgb(155 255 102 / .03) 26%, rgb(155 255 102 / .012) 54%, transparent 80%);
1371
+ }
1372
+ @keyframes madre-gas-a {
1373
+ 0% { transform: translate3d(-3vmax, 2vmax, 0) rotate(0deg) scale(1); opacity: .85; }
1374
+ 50% { transform: translate3d(2vmax, -1vmax, 0) rotate(6deg) scale(1.08); opacity: 1; }
1375
+ 100% { transform: translate3d(5vmax, -3vmax, 0) rotate(11deg) scale(1.02); opacity: .9; }
1376
+ }
1377
+ @keyframes madre-gas-b {
1378
+ 0% { transform: translate3d(3vmax, -2vmax, 0) rotate(0deg) scale(1.06); opacity: 1; }
1379
+ 50% { transform: translate3d(-2vmax, 1vmax, 0) rotate(-7deg) scale(1); opacity: .8; }
1380
+ 100% { transform: translate3d(-5vmax, 3vmax, 0) rotate(-12deg) scale(1.1); opacity: .95; }
1381
+ }
1382
+ @media (prefers-reduced-motion: reduce) { .sm-gas { animation: none !important; } }
@@ -17,7 +17,7 @@
17
17
  same markup as loader.js) at the share the page that left had reached; salas-mac.js fills
18
18
  the bar once Home has read its projects, and lifts it. -->
19
19
  <script>try { var kept = sessionStorage.getItem('madre.curtain'); if (kept) { sessionStorage.removeItem('madre.curtain'); var p = parseFloat(kept); if (!(p > 0 && p < 1)) p = 0.3; var curtain = document.createElement('div'); curtain.className = 'reload-curtain arrived'; curtain.id = 'reload-curtain'; curtain.innerHTML = '<div class="madre-loader" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="' + Math.round(p * 100) + '" data-p="' + p + '" style="--p: ' + p + '"><span class="madre-loader-mark"><svg viewBox="-2 -1 66 22" aria-hidden="true"><path class="madre-loader-trace" d="M1 10H16L20 10L23.5 2L28 18L32 10L35 10L37 6L39 10H52" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path class="madre-loader-beat" d="M1 10H16L20 10L23.5 2L28 18L32 10L35 10L37 6L39 10H52" pathLength="100" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle class="madre-loader-dot" cx="60" cy="10" r="3" fill="currentColor"/></svg></span><span class="madre-loader-bar"><i></i></span><span class="madre-loader-pct"></span><span class="madre-loader-said"></span></div>'; curtain.querySelector('.madre-loader-pct').textContent = Math.round(p * 100) + ' %'; if (curtain.showPopover) curtain.popover = 'manual'; document.body.appendChild(curtain); try { if (curtain.showPopover) curtain.showPopover(); } catch (e) {} setTimeout(function () { var still = document.getElementById('reload-curtain'); if (still && !still.classList.contains('leaving')) still.remove(); }, 15000); } } catch (e) {}</script>
20
- <div class="sm-sky" aria-hidden="true"></div>
20
+ <div class="sm-sky" aria-hidden="true"><i class="sm-gas a"></i><i class="sm-gas b"></i></div>
21
21
  <!-- The lobby's bar, as a room's (index.html, #bar and #bar-home): the logo and where you are;
22
22
  what is going on — the projects open, the agents and their sessions, who waits for you, a
23
23
  newer MADRE, what is running —; and the keys. Filled by salas-mac.js (drawTopbar). -->
@@ -46,6 +46,14 @@
46
46
  <svg viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path class="ic-mid" d="M8.2 11.8 11.8 8.2"/><path class="ic-a" d="M9 5.6 10.6 4a3.2 3.2 0 0 1 4.5 4.5L13.5 10"/><path class="ic-b" d="M11 14.4 9.4 16a3.2 3.2 0 0 1-4.5-4.5L6.5 10"/></svg>
47
47
  <span>Connections</span><b id="sm-tb-links-count" class="sm-badge" hidden></b>
48
48
  </button>
49
+ <button id="sm-tb-market" class="sm-barkey" type="button">
50
+ <svg viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><path d="M3.6 7.6 4.8 4h10.4l1.2 3.6"/><path class="ic-f" d="M3.6 7.6h12.8a2.1 2.1 0 0 1-4.2 0 2.1 2.1 0 0 1-4.2 0 2.1 2.1 0 0 1-4.4 0z"/><path d="M4.6 10.4V16h10.8v-5.6"/><path d="M8.4 16v-3.2h3.2V16"/></svg>
51
+ <span>Market</span>
52
+ </button>
53
+ <button id="sm-tb-modules" class="sm-barkey" type="button">
54
+ <svg viewBox="0 0 20 20" aria-hidden="true" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="6" height="6" rx="1.8"/><rect class="ic-f" x="11" y="3" width="6" height="6" rx="1.8"/><rect x="3" y="11" width="6" height="6" rx="1.8"/><path d="M12 14l1.6 1.6L17 12.2"/></svg>
55
+ <span>Modules</span>
56
+ </button>
49
57
  <button id="sm-macro" class="sm-barkey sm-macro" type="button" hidden>
50
58
  <svg viewBox="0 0 20 20" aria-hidden="true"><ellipse cx="10" cy="10" rx="8.2" ry="3.6" fill="none" stroke="currentColor" stroke-width="1.4" opacity=".6"/><circle cx="10" cy="10" r="2.2" fill="currentColor"/><circle class="ic-planet" cx="18.2" cy="10" r="1.5" fill="currentColor"><animateMotion begin="indefinite" dur="2.4s" repeatCount="indefinite" path="M0 0a8.2 3.6 0 1 1-16.4 0a8.2 3.6 0 1 1 16.4 0"/></circle><circle class="ic-planet" cx="1.8" cy="10" r="1.1" fill="currentColor" opacity=".7"><animateMotion begin="indefinite" dur="2.4s" repeatCount="indefinite" path="M0 0a8.2 3.6 0 1 1 16.4 0a8.2 3.6 0 1 1-16.4 0"/></circle></svg>
51
59
  <span>Project map</span>