@jossuealcala/madre 1.0.2 → 1.0.4

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 (77) hide show
  1. package/CHANGELOG.en.md +76 -1
  2. package/CHANGELOG.md +76 -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 +1635 -159
  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 +395 -26
  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 +105 -14
  31. package/public/salas-mac.html +9 -1
  32. package/public/salas-mac.js +350 -31
  33. package/public/styles.css +844 -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 +8 -8
  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-sentinel.mjs +7 -3
  76. package/src/server.mjs +617 -48
  77. 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; }
@@ -116,9 +118,16 @@ body.salas-mac {
116
118
  @media (max-width: 560px) { #sm-reload { display: none; } }
117
119
  .sm-brand:focus-visible { outline: 2px solid var(--s-acc); outline-offset: 3px; }
118
120
  .sm-spacer { flex: 1; }
121
+ /* A bar that does not fit (salas-mac.js, fitBar): the computer's name steps out, then the keys keep
122
+ their icons, then the agents step out. */
123
+ .sm-topbar.is-tight { gap: 10px; }
124
+ .sm-topbar.is-tight .sm-live > span { display: none; }
125
+ .sm-topbar.is-tighter .sm-barkey > span { display: none; }
126
+ .sm-topbar.is-tighter .sm-barkey { padding: 0 8px; }
127
+ .sm-topbar.is-tightest .sm-tb-agents { display: none; }
119
128
  /* The bar's keys are the room's bar keys (styles.css, .mother-button, .tree-button, .stop-all). */
120
129
  .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; }
130
+ .sm-barkey svg, .sm-stop svg { width: var(--ico-sm); height: var(--ico-sm); }
122
131
  .sm-stop { box-shadow: inset 0 0 0 1px var(--terror); background: color-mix(in srgb, var(--terror) 12%, transparent); color: var(--terror); }
123
132
  .sm-stop:hover, .sm-stop.armed { background: var(--terror); color: #fff; }
124
133
  /* Whatever the page hides stays hidden, whatever its class lays out. */
@@ -131,7 +140,7 @@ body.salas-mac {
131
140
  .sm-icon-key:hover { color: var(--text); box-shadow: var(--key-over, var(--key-rest)); }
132
141
  .sm-icon-key:active { box-shadow: var(--key-down); }
133
142
  .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; }
143
+ .sm-icon-key svg { width: var(--ico-sm); height: var(--ico-sm); }
135
144
  /* A link that cannot be followed yet (BISHOP waking) looks and acts like a disabled key. */
136
145
  .sm-btn[aria-disabled="true"], .sm-icon-key[aria-disabled="true"] { opacity: .45; box-shadow: none; pointer-events: none; }
137
146
 
@@ -416,8 +425,7 @@ body.sm-in-macro { overflow: hidden; }
416
425
  kinds of memory under them and the keys at the end. */
417
426
  .mv-head { position: absolute; left: 0; right: 0; top: 0; z-index: 2; margin: 0; }
418
427
  .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; }
428
+
421
429
  .mv-hint { position: absolute; left: 20px; bottom: 14px; margin: 0; font-size: 11.5px; color: rgba(242, 241, 238, .42); pointer-events: none; }
422
430
 
423
431
  .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 +555,20 @@ body.sm-in-macro { overflow: hidden; }
547
555
  /* The room's search (styles.css, .settings-search), not the sheet's uppercase field label. */
548
556
  .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
557
  .sm-picker-search input::-webkit-search-cancel-button { cursor: pointer; }
558
+ /* A project from nothing (2026-10-17): the name, where it goes, one key. */
559
+ .sm-new-project { display: grid; gap: 12px; justify-items: start; padding: 18px 2px 6px; }
560
+ .sm-new-name { display: grid; gap: 6px; width: min(100%, 420px); font-size: 13px; color: var(--text-2); }
561
+ .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; }
562
+ .sm-new-name input:focus { box-shadow: var(--key-down), 0 0 0 2px color-mix(in srgb, var(--s-acc) 45%, transparent); }
563
+ .sm-new-where { margin: 0; font-size: 13px; color: var(--text-2); }
564
+ .sm-new-where code { font-family: var(--mono); font-size: 12px; color: var(--text); }
565
+ .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; }
566
+ .sm-new-project .error:empty { display: none; }
550
567
  .sm-picker-line { display: flex; align-items: center; gap: 10px; min-width: 0; height: 28px; font-size: 13px; color: var(--text-2); }
551
568
  .sm-picker-note { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
552
569
  .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
570
  .sm-up { flex: none; gap: 4px; padding: 0 10px 0 6px; }
554
- .sm-up svg { width: 14px; height: 14px; }
571
+ .sm-up svg { width: var(--ico-sm); height: var(--ico-sm); }
555
572
  .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
573
  .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
574
  .sm-fold-grid > .sm-fold:hover { box-shadow: var(--key-over, var(--key-rest)); }
@@ -571,7 +588,7 @@ body.sm-in-macro { overflow: hidden; }
571
588
  .sm-fold-words b { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
572
589
  .sm-fold-words small { font-family: var(--mono); font-size: 11px; color: var(--text-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
573
590
  .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; }
591
+ .sm-into svg { width: var(--ico-sm); height: var(--ico-sm); }
575
592
  .sm-into:hover, .sm-into:focus-visible { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); outline: 0; }
576
593
  .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
594
  .sm-picker-foot { display: flex; align-items: center; justify-content: flex-end; gap: 12px; min-height: 30px; }
@@ -623,6 +640,8 @@ body.sm-in-macro { overflow: hidden; }
623
640
  /* Everything a connection needs that does not fit on the row: the page a sign-in opened, the
624
641
  code it is waiting for, the key form. Home used to send you to a project for all of it. */
625
642
  .sm-agent-ask { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
643
+ .sm-agent-device { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 13px; color: var(--text-2); }
644
+ .sm-agent-device code { font-family: var(--mono); font-size: 15px; letter-spacing: .12em; color: var(--text); user-select: all; }
626
645
  .sm-agent-code { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; flex: 1 1 240px; }
627
646
  .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
647
  .sm-agent-code input { flex: 1 1 160px; }
@@ -633,6 +652,14 @@ body.sm-in-macro { overflow: hidden; }
633
652
  .sm-agent-key-link { font-size: 12.5px; color: var(--s-acc); text-decoration: none; }
634
653
  .sm-agent-key-link:hover { text-decoration: underline; }
635
654
  .sm-agent-command { grid-column: 1 / -1; font-family: var(--mono); font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; }
655
+ /* The other way in, folded: the same install or sign-in typed in a terminal, for whoever prefers it. */
656
+ .sm-terminal-way > summary { width: max-content; font-size: 12.5px; color: var(--text-3); cursor: pointer; list-style: none; }
657
+ .sm-terminal-way > summary::-webkit-details-marker { display: none; }
658
+ .sm-terminal-way > summary::after { content: ' ›'; }
659
+ .sm-terminal-way[open] > summary::after { content: ' ⌄'; }
660
+ .sm-terminal-way > summary:hover { color: var(--text-2); }
661
+ .sm-terminal-way[open] { display: grid; gap: 8px; justify-items: start; }
662
+ .sm-terminal-lines { display: grid; gap: 4px; justify-self: stretch; padding: 10px 12px; border-radius: 10px; box-shadow: var(--key-track); }
636
663
 
637
664
  /* LINKING TWO ROOMS, step by step (salas-mac.js, openLinkSheet), in the room's settings language:
638
665
  the step and its question, what it decides; the choices on a card, a row each, the safe one
@@ -671,7 +698,7 @@ body.sm-in-macro { overflow: hidden; }
671
698
  .lw-allows li { display: flex; align-items: flex-start; gap: 10px; font-size: 13px; line-height: 1.45; color: var(--text); }
672
699
  .lw-allows li.no { color: var(--text-2); }
673
700
  .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; }
701
+ .lw-allows li i svg { width: var(--ico-xs); height: var(--ico-xs); }
675
702
  .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
703
  .lw-allows li.no i { color: var(--text-2); background: color-mix(in srgb, var(--text) 7%, transparent); }
677
704
  /* Two projects already connected: how, and where to change it, in place of a new connection. */
@@ -789,14 +816,14 @@ dialog.sm-sheet.sm-settings[open] { --sm-sheet-pad: 20px; }
789
816
  /* A project's right-click: the bar card's material, a row per thing it can do. */
790
817
  .bar-card.sm-menu { width: auto; min-width: 214px; padding: 6px; display: grid; gap: 2px; }
791
818
  .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); }
819
+ .sm-menu-item svg { flex: none; width: var(--ico-sm); height: var(--ico-sm); color: var(--phosphor); }
793
820
  .sm-menu-item:hover, .sm-menu-item:focus-visible { background: color-mix(in srgb, var(--text) 7%, transparent); outline: none; }
794
821
  .sm-menu-item.danger, .sm-menu-item.danger svg { color: var(--danger, var(--terror)); }
795
822
  .sm-menu-sep { display: block; height: 1px; margin: 4px 8px; background: var(--line); }
796
823
  /* The card's own key for that menu, for whoever does not right-click: quiet until the card is
797
824
  under the pointer. */
798
825
  .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; }
826
+ .sm-card-more svg { width: var(--ico-sm); height: var(--ico-sm); }
800
827
  .sm-card:hover .sm-card-more, .sm-card-more:focus-visible { opacity: 1; }
801
828
  .sm-card-more:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
802
829
  .sm-card-more:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
@@ -840,7 +867,7 @@ dialog.sm-sheet.sm-settings[open] { --sm-sheet-pad: 20px; }
840
867
  :root[data-home-text="smaller"] .sm-main { zoom: .93; }
841
868
  /* A newer MADRE in the bar: a key now, that opens Home's Version. */
842
869
  button.sm-pill { border: 0; cursor: pointer; }
843
- .sm-pill.is-update svg { width: 14px; height: 14px; flex: none; }
870
+ .sm-pill.is-update svg { width: var(--ico-sm); height: var(--ico-sm); flex: none; }
844
871
  .sm-pill.is-update:hover { background: color-mix(in srgb, var(--session-wait) 28%, transparent); }
845
872
  .sm-pill.is-update:focus-visible { outline: 2px solid color-mix(in srgb, var(--s-acc) 70%, transparent); outline-offset: 2px; }
846
873
  /* A project's name inside the wizard's sentences stands out (salas-mac.js, sayBold). */
@@ -895,13 +922,13 @@ dialog.sm-sheet.sm-add-sheet { --sm-sheet-w: 560px; }
895
922
  .sm-w-foot.mono { font-family: var(--mono); font-size: 11px !important; overflow-wrap: anywhere; }
896
923
  /* What a tile is, in the accent: on its row of «Add to Home» and at the head of its menu. */
897
924
  .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; }
925
+ .sm-tile-icon svg { width: var(--ico-md); height: var(--ico-md); }
899
926
  .sm-add-row { justify-content: flex-start; }
900
927
  .sm-add-row .sm-add-words { flex: 1; }
901
928
  .sm-add-sheet .sm-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
902
929
  .sm-menu-head { display: flex; align-items: center; gap: 8px; }
903
930
  .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; }
931
+ .sm-menu-head .sm-tile-icon svg { width: var(--ico-xs); height: var(--ico-xs); }
905
932
  .salas-mac .sm-menu-item svg { color: var(--s-acc); }
906
933
 
907
934
  /* THE MAP, INTERACTIVE (2026-10-13): a project under the pointer, or chosen, lights its own lines
@@ -943,7 +970,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
943
970
  .sm-graph-quiet { font-size: 12.5px; line-height: 1.5; color: var(--text-3); }
944
971
  /* The order of the projects, beside the filter that chooses which of them show. */
945
972
  .sm-order { flex: none; gap: 6px; height: 36px; padding: 0 12px; }
946
- .sm-order svg { width: 16px; height: 16px; color: var(--s-acc); }
973
+ .sm-order svg { width: var(--ico-sm); height: var(--ico-sm); color: var(--s-acc); }
947
974
  .sm-menu-head + .sm-menu-item { margin-top: 2px; }
948
975
  .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
976
 
@@ -1074,6 +1101,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1074
1101
  :root[data-wallpaper="urbania"] { --wp-now: var(--wp-urbania); }
1075
1102
  :root[data-wallpaper="ventura"] { --wp-now: var(--wp-ventura); }
1076
1103
  :root[data-wallpaper="xico"] { --wp-now: var(--wp-xico); }
1104
+ :root[data-wallpaper="custom"] { --wp-now: var(--wp-custom); }
1077
1105
  .sm-drawer .sm-projects > .sm-card { isolation: isolate; overflow: hidden; }
1078
1106
  .sm-drawer .sm-projects > .sm-card:is([data-wp], :root[data-wallpaper] .sm-card)::before {
1079
1107
  content: ''; position: absolute; inset: -24px; z-index: -2; pointer-events: none;
@@ -1129,6 +1157,7 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1129
1157
  .sm-card[data-wp="jarrito"] { --wp-card: var(--wp-jarrito); --wp-size: cover; }
1130
1158
  .sm-card[data-wp="magna"] { --wp-card: var(--wp-magna); --wp-size: cover; }
1131
1159
  .sm-card[data-wp="oceano"] { --wp-card: var(--wp-oceano); --wp-size: cover; }
1160
+ .sm-card[data-wp="custom"] { --wp-card: var(--wp-custom); --wp-size: cover; }
1132
1161
  .sm-card[data-wp="paradise"] { --wp-card: var(--wp-paradise); --wp-size: cover; }
1133
1162
  .sm-card[data-wp="quila"] { --wp-card: var(--wp-quila); --wp-size: cover; }
1134
1163
  .sm-card[data-wp="tradicion"] { --wp-card: var(--wp-tradicion); --wp-size: cover; }
@@ -1296,3 +1325,65 @@ dialog.sm-sheet.sm-graph { --sm-sheet-w: min(1120px, 94vw); }
1296
1325
  modal is when it opens), the browser drew its ring around the whole page. Focus moves to what is
1297
1326
  inside it; the dialog itself draws no ring. */
1298
1327
  dialog.sm-sheet:focus, dialog.sm-sheet:focus-visible { outline: none; }
1328
+
1329
+ /* 1.0.3 (2026-10-17) · Connections and the Project map lift less under the pointer, as Modules and
1330
+ Diagnostics do in a project. The widgets key pulses once under the pointer, and its squares fill
1331
+ while the sheet it opens is there. */
1332
+ .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)); }
1333
+ #sm-add-widgets:is(:hover, :focus-visible) svg { animation: icon-pulse calc(520ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
1334
+ #sm-add-widgets svg rect { fill: currentColor; fill-opacity: 0; transition: fill-opacity calc(200ms * var(--motion-scale, 1)) var(--ease-out, ease-out); }
1335
+ #sm-add-widgets:active svg rect, #sm-add-widgets.filled svg rect { fill-opacity: 1; }
1336
+ @keyframes icon-pulse { 0% { transform: scale(1); } 40% { transform: scale(1.16); } 70% { transform: scale(.95); } 100% { transform: scale(1); } }
1337
+ @media (prefers-reduced-motion: reduce) { #sm-add-widgets:is(:hover, :focus-visible) svg { animation: none; } }
1338
+
1339
+ /* While the Project map is open, a first-time hint that points at Home steps aside, with its ring:
1340
+ what it speaks of is under the map. It is not read yet, so it comes back when the map closes.
1341
+ The map's own hint stays (tour.js, data-under). */
1342
+ body.sm-in-macro > :is(.tour-hint, .tour-hint-away, .hint-spot)[data-under="page"] { display: none !important; }
1343
+
1344
+ /* ==========================================================================================
1345
+ MADRE, IN THE AIR (2026-10-17)
1346
+ ------------------------------------------------------------------------------------------
1347
+ Home only, on a sky with no wallpaper: MADRE is there as a gas, two slow clouds in her palette,
1348
+ a breath under everything and never a shape you can point at. Light: her green over the pale
1349
+ ground. Dark: her phosphor with a trace of the Coordinator's plum and of the sky's cyan, kept
1350
+ lower, since on black a colour carries further. Gradients only (no blur filter) that fall off
1351
+ on an eased curve so no ring shows, moved by transform; still for whoever asks for less motion.
1352
+ ========================================================================================== */
1353
+ .sm-gas { display: none; }
1354
+ :root:not([data-wallpaper]) .sm-gas {
1355
+ display: block; position: absolute; inset: -18vmax; pointer-events: none; will-change: transform, opacity;
1356
+ }
1357
+ :root:not([data-wallpaper]) .sm-gas.a { animation: madre-gas-a calc(52s * var(--motion-scale, 1)) ease-in-out infinite alternate; }
1358
+ :root:not([data-wallpaper]) .sm-gas.b { animation: madre-gas-b calc(68s * var(--motion-scale, 1)) ease-in-out infinite alternate; }
1359
+ :root[data-scheme="light"]:not([data-wallpaper]) .sm-gas.a {
1360
+ background:
1361
+ 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),
1362
+ 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);
1363
+ }
1364
+ :root[data-scheme="light"]:not([data-wallpaper]) .sm-gas.b {
1365
+ background:
1366
+ 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),
1367
+ 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%);
1368
+ }
1369
+ :root[data-scheme="dark"]:not([data-wallpaper]) .sm-gas.a {
1370
+ background:
1371
+ 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%),
1372
+ 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%);
1373
+ }
1374
+ :root[data-scheme="dark"]:not([data-wallpaper]) .sm-gas.b {
1375
+ background:
1376
+ 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%),
1377
+ 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%);
1378
+ }
1379
+ @keyframes madre-gas-a {
1380
+ 0% { transform: translate3d(-3vmax, 2vmax, 0) rotate(0deg) scale(1); opacity: .85; }
1381
+ 50% { transform: translate3d(2vmax, -1vmax, 0) rotate(6deg) scale(1.08); opacity: 1; }
1382
+ 100% { transform: translate3d(5vmax, -3vmax, 0) rotate(11deg) scale(1.02); opacity: .9; }
1383
+ }
1384
+ @keyframes madre-gas-b {
1385
+ 0% { transform: translate3d(3vmax, -2vmax, 0) rotate(0deg) scale(1.06); opacity: 1; }
1386
+ 50% { transform: translate3d(-2vmax, 1vmax, 0) rotate(-7deg) scale(1); opacity: .8; }
1387
+ 100% { transform: translate3d(-5vmax, 3vmax, 0) rotate(-12deg) scale(1.1); opacity: .95; }
1388
+ }
1389
+ @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>