@higinio/design-mcp 0.1.1 → 0.2.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/LICENSE +4 -4
- package/README.md +5 -5
- package/assets/bruma/design-doc.md +1083 -0
- package/assets/bruma/framework.css +1374 -0
- package/assets/bruma/styleguide.html +4687 -0
- package/assets/bruma/tailwind.css +121 -0
- package/assets/bruma/tokens.css +147 -0
- package/assets/bruma/tokens.json +995 -0
- package/assets/celeste/design-doc.md +56 -5
- package/assets/celeste/framework.css +93 -4
- package/assets/celeste/styleguide.html +252 -19
- package/assets/nocturna/design-doc.md +63 -12
- package/assets/nocturna/framework.css +102 -7
- package/assets/nocturna/styleguide.html +341 -118
- package/assets/nocturna/tokens.css +8 -3
- package/assets/salvia/design-doc.md +1067 -0
- package/assets/salvia/framework.css +1370 -0
- package/assets/salvia/styleguide.html +4670 -0
- package/assets/salvia/tailwind.css +121 -0
- package/assets/salvia/tokens.css +143 -0
- package/assets/salvia/tokens.json +1023 -0
- package/dist/cli.js +7 -5
- package/dist/doc.js +18 -4
- package/dist/preflight.js +2 -1
- package/dist/server.js +7 -7
- package/dist/systems.js +27 -1
- package/dist/validate.js +13 -5
- package/package.json +9 -31
|
@@ -322,7 +322,7 @@ html, body { overflow-x: clip; }
|
|
|
322
322
|
.input-icon .input { padding-left: 40px; }
|
|
323
323
|
|
|
324
324
|
.textarea { min-height: 96px; padding: 12px 14px; resize: vertical; line-height: var(--leading-base); }
|
|
325
|
-
.textarea-counter { font-size: var(--text-xs); color: var(--text-
|
|
325
|
+
.textarea-counter { font-size: var(--text-xs); color: var(--text-muted); text-align: right; }
|
|
326
326
|
|
|
327
327
|
.select-wrap { position: relative; }
|
|
328
328
|
.select { appearance: none; padding-right: 38px; cursor: pointer; }
|
|
@@ -608,7 +608,7 @@ html, body { overflow-x: clip; }
|
|
|
608
608
|
}
|
|
609
609
|
.alert > svg { width: 20px; height: 20px; flex: none; margin-top: 1px; }
|
|
610
610
|
.alert__title { font-weight: var(--weight-semibold); margin: 0 0 2px; }
|
|
611
|
-
.alert__body {
|
|
611
|
+
.alert__body { margin: 0; }
|
|
612
612
|
.alert__close {
|
|
613
613
|
margin-left: auto; flex: none; display: grid; place-items: center;
|
|
614
614
|
width: 36px; height: 36px; border: 0; border-radius: var(--radius-sm);
|
|
@@ -823,6 +823,32 @@ html, body { overflow-x: clip; }
|
|
|
823
823
|
.stat__delta--up { color: var(--success-text); }
|
|
824
824
|
.stat__delta--down { color: var(--danger-text); }
|
|
825
825
|
|
|
826
|
+
/* Chip de métrica (§10.22): rótulo y valor en una pastilla de una línea */
|
|
827
|
+
.metric-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); }
|
|
828
|
+
.metric-chip {
|
|
829
|
+
display: inline-flex; align-items: center; gap: var(--space-2);
|
|
830
|
+
padding: var(--space-1) var(--space-3);
|
|
831
|
+
border: var(--border-width) solid var(--border); border-radius: var(--radius-full);
|
|
832
|
+
background: var(--surface);
|
|
833
|
+
font-family: var(--font-body); font-size: var(--text-sm); line-height: 1.5;
|
|
834
|
+
color: var(--text-secondary); white-space: nowrap;
|
|
835
|
+
}
|
|
836
|
+
.metric-chip svg { width: 16px; height: 16px; flex: none; color: var(--text-muted); }
|
|
837
|
+
.metric-chip__value {
|
|
838
|
+
font-weight: var(--weight-semibold); color: var(--link);
|
|
839
|
+
font-variant-numeric: tabular-nums;
|
|
840
|
+
}
|
|
841
|
+
button.metric-chip {
|
|
842
|
+
min-height: var(--control-height-md); padding-inline: var(--space-4);
|
|
843
|
+
cursor: pointer; text-align: left;
|
|
844
|
+
transition: background-color var(--duration-fast) var(--ease-out),
|
|
845
|
+
border-color var(--duration-fast) var(--ease-out),
|
|
846
|
+
transform var(--duration-instant) var(--ease-out);
|
|
847
|
+
}
|
|
848
|
+
button.metric-chip:hover { background: var(--accent-soft); border-color: var(--accent); }
|
|
849
|
+
button.metric-chip:active { background: var(--accent-soft-strong); transform: scale(.98); }
|
|
850
|
+
button.metric-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
851
|
+
|
|
826
852
|
.pagination { display: flex; align-items: center; gap: 4px; list-style: none; padding: 0; margin: 0; }
|
|
827
853
|
.pagination__btn {
|
|
828
854
|
display: inline-grid; place-items: center;
|
|
@@ -868,7 +894,7 @@ html, body { overflow-x: clip; }
|
|
|
868
894
|
.sidebar__item {
|
|
869
895
|
display: flex; align-items: center; gap: 10px;
|
|
870
896
|
padding: 10px 12px; border-radius: var(--radius-md);
|
|
871
|
-
font-size: var(--text-sm); font-weight: var(--weight-medium);
|
|
897
|
+
font-family: var(--font-body); font-size: var(--text-sm); font-weight: var(--weight-medium);
|
|
872
898
|
color: var(--text-secondary); text-decoration: none; border: 0; background: transparent;
|
|
873
899
|
cursor: pointer; text-align: left; width: 100%;
|
|
874
900
|
transition: background-color var(--duration-fast) var(--ease-out), color var(--duration-fast) var(--ease-out);
|
|
@@ -878,6 +904,68 @@ html, body { overflow-x: clip; }
|
|
|
878
904
|
.sidebar__item.is-active { background: var(--accent-soft-strong); color: var(--link); }
|
|
879
905
|
.sidebar__item.is-active svg { color: var(--accent); }
|
|
880
906
|
|
|
907
|
+
/* Grupos con rótulo dentro del sidebar */
|
|
908
|
+
.sidebar__group { display: flex; flex-direction: column; gap: 2px; }
|
|
909
|
+
.sidebar__group + .sidebar__group { margin-top: var(--space-4); }
|
|
910
|
+
.sidebar__group-label {
|
|
911
|
+
padding: 0 12px var(--space-1);
|
|
912
|
+
font-size: var(--text-xs); font-weight: var(--weight-semibold);
|
|
913
|
+
text-transform: uppercase; letter-spacing: var(--tracking-label);
|
|
914
|
+
color: var(--text-muted); white-space: nowrap;
|
|
915
|
+
}
|
|
916
|
+
.sidebar__label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
917
|
+
|
|
918
|
+
/* Sidebar contraíble (§10.24): expandido 260 px, riel de iconos de 64 px.
|
|
919
|
+
El ancho cambia sin transición; solo los rótulos se funden con opacity y transform. */
|
|
920
|
+
.sidebar--collapsible .sidebar__label {
|
|
921
|
+
transition: opacity var(--duration-fast) var(--ease-out),
|
|
922
|
+
transform var(--duration-fast) var(--ease-out);
|
|
923
|
+
}
|
|
924
|
+
.sidebar__toggle { margin-top: auto; }
|
|
925
|
+
.sidebar.is-collapsed { width: 64px; padding-inline: var(--space-3); }
|
|
926
|
+
.sidebar.is-collapsed .sidebar__item { position: relative; justify-content: center; padding-inline: 0; }
|
|
927
|
+
.sidebar.is-collapsed .sidebar__toggle svg { transform: rotate(180deg); }
|
|
928
|
+
.sidebar.is-collapsed .sidebar__group + .sidebar__group { margin-top: var(--space-2); }
|
|
929
|
+
/* En el riel, el rótulo de grupo es un separador de 1 px; su texto sigue en el árbol de accesibilidad */
|
|
930
|
+
.sidebar.is-collapsed .sidebar__group-label {
|
|
931
|
+
height: 1px; padding: 0; margin: 0 var(--space-2) var(--space-2);
|
|
932
|
+
overflow: hidden; color: transparent; background: var(--border);
|
|
933
|
+
}
|
|
934
|
+
/* Oculto a la vista pero accesible (patrón de .u-visually-hidden) */
|
|
935
|
+
.sidebar.is-collapsed .sidebar__label,
|
|
936
|
+
.sidebar.is-collapsed .sidebar__group:first-child > .sidebar__group-label {
|
|
937
|
+
position: absolute; width: 1px; height: 1px; margin: -1px;
|
|
938
|
+
clip-path: inset(50%); overflow: hidden; white-space: nowrap;
|
|
939
|
+
}
|
|
940
|
+
.sidebar.is-collapsed .sidebar__label {
|
|
941
|
+
border-radius: var(--radius-sm); background: var(--tooltip-bg); color: var(--tooltip-text);
|
|
942
|
+
font-size: var(--text-xs); line-height: 16px;
|
|
943
|
+
pointer-events: none; z-index: 70;
|
|
944
|
+
opacity: 0; transform: translateX(-4px);
|
|
945
|
+
}
|
|
946
|
+
/* Tooltip del riel: el propio rótulo aparece a la derecha del ítem, también con teclado */
|
|
947
|
+
.sidebar.is-collapsed .sidebar__item:focus-visible .sidebar__label {
|
|
948
|
+
left: calc(100% + 8px); top: calc(50% - 14px); width: auto; height: auto;
|
|
949
|
+
margin: 0; padding: 6px 10px; clip-path: none; overflow: visible;
|
|
950
|
+
opacity: 1; transform: none; transition-delay: 400ms;
|
|
951
|
+
}
|
|
952
|
+
/* Por hover solo con puntero real — en touch quedaría pegado tras el tap */
|
|
953
|
+
@media (hover: hover) and (pointer: fine) {
|
|
954
|
+
.sidebar.is-collapsed .sidebar__item:hover .sidebar__label {
|
|
955
|
+
left: calc(100% + 8px); top: calc(50% - 14px); width: auto; height: auto;
|
|
956
|
+
margin: 0; padding: 6px 10px; clip-path: none; overflow: visible;
|
|
957
|
+
opacity: 1; transform: none; transition-delay: 400ms;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
/* Por debajo de 768 px la navegación vive en un Drawer --left (§10.29), que abre el botón ☰
|
|
961
|
+
.sidebar-trigger (combinado con .icon-btn); desde 768 px el sidebar es fijo y el botón sobra */
|
|
962
|
+
@media (max-width: 767px) {
|
|
963
|
+
.sidebar--collapsible { display: none; }
|
|
964
|
+
}
|
|
965
|
+
@media (min-width: 768px) {
|
|
966
|
+
.sidebar-trigger { display: none; }
|
|
967
|
+
}
|
|
968
|
+
|
|
881
969
|
.tabs { display: flex; gap: var(--space-6); border-bottom: var(--border-width) solid var(--border); }
|
|
882
970
|
.tabs__tab {
|
|
883
971
|
padding: 12px 4px; margin-bottom: -1px;
|
|
@@ -1082,6 +1170,7 @@ html, body { overflow-x: clip; }
|
|
|
1082
1170
|
.calendar__weekdays,
|
|
1083
1171
|
.calendar__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
|
|
1084
1172
|
.calendar__weekdays { margin-bottom: 4px; }
|
|
1173
|
+
.calendar__week { display: contents; }
|
|
1085
1174
|
.calendar__weekday {
|
|
1086
1175
|
display: flex; align-items: center; justify-content: center; height: 28px;
|
|
1087
1176
|
font-size: var(--text-xs); font-weight: var(--weight-medium); color: var(--text-muted);
|
|
@@ -1096,7 +1185,7 @@ html, body { overflow-x: clip; }
|
|
|
1096
1185
|
color var(--duration-fast) var(--ease-out);
|
|
1097
1186
|
}
|
|
1098
1187
|
.calendar__day:hover:not(:disabled):not(.calendar__day--selected) { background: var(--accent-soft); }
|
|
1099
|
-
.calendar__day--outside { color: var(--text-
|
|
1188
|
+
.calendar__day--outside { color: var(--text-muted); }
|
|
1100
1189
|
.calendar__day--today { font-weight: var(--weight-semibold); box-shadow: inset 0 0 0 1px var(--border-strong); }
|
|
1101
1190
|
.calendar__day--selected { background: var(--accent); color: var(--text-on-primary); font-weight: var(--weight-semibold); }
|
|
1102
1191
|
.calendar__day:disabled { color: var(--text-disabled); cursor: not-allowed; }
|
|
@@ -1287,6 +1376,14 @@ html, body { overflow-x: clip; }
|
|
|
1287
1376
|
.ds-demo--grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); align-items: stretch; }
|
|
1288
1377
|
.ds-demo:has(table) { overflow-x: auto; }
|
|
1289
1378
|
|
|
1379
|
+
/* Demo del sidebar contraíble: rejilla auto 1fr, el contenido sigue al riel sin animar el ancho */
|
|
1380
|
+
.ds-app-demo { display: grid; grid-template-columns: auto 1fr; align-items: stretch; gap: 0; min-height: 400px; padding: 0; }
|
|
1381
|
+
.ds-app-demo > .sidebar { border-radius: var(--radius-lg) 0 0 var(--radius-lg); }
|
|
1382
|
+
.ds-app-demo__main { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); min-width: 0; padding: var(--space-6); }
|
|
1383
|
+
@media (max-width: 767px) {
|
|
1384
|
+
.ds-app-demo { grid-template-columns: 1fr; min-height: 0; }
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1290
1387
|
.ds-code { margin: var(--space-2) 0 0; }
|
|
1291
1388
|
.ds-code summary {
|
|
1292
1389
|
cursor: pointer; user-select: none; font-size: var(--text-sm);
|
|
@@ -1824,7 +1921,7 @@ html, body { overflow-x: clip; }
|
|
|
1824
1921
|
<svg>…icono 18px…</svg>
|
|
1825
1922
|
</button>
|
|
1826
1923
|
<!-- Variantes: --ghost (default) · --secondary · --primary
|
|
1827
|
-
Tamaños: --sm
|
|
1924
|
+
Tamaños: --sm 36px · (md 44px) · --lg 48px --></code></pre>
|
|
1828
1925
|
</div>
|
|
1829
1926
|
</details>
|
|
1830
1927
|
</div>
|
|
@@ -2297,11 +2394,11 @@ html, body { overflow-x: clip; }
|
|
|
2297
2394
|
<div class="ds-demo ds-demo--col" style="max-width:420px">
|
|
2298
2395
|
<div>
|
|
2299
2396
|
<div class="progress-row"><span class="progress-label">Almacenamiento</span><span class="progress-value js-progress-value">68%</span></div>
|
|
2300
|
-
<div class="progress"><div class="progress__bar js-progress-bar" style="width:68%" role="progressbar" aria-valuenow="68" aria-valuemin="0" aria-valuemax="100"></div></div>
|
|
2397
|
+
<div class="progress"><div class="progress__bar js-progress-bar" style="width:68%" role="progressbar" aria-label="Almacenamiento" aria-valuenow="68" aria-valuemin="0" aria-valuemax="100"></div></div>
|
|
2301
2398
|
</div>
|
|
2302
2399
|
<div>
|
|
2303
2400
|
<div class="progress-row"><span class="progress-label">Tareas completadas</span><span class="progress-value">24/30</span></div>
|
|
2304
|
-
<div class="progress"><div class="progress__bar progress__bar--success" style="width:80%" role="progressbar" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div></div>
|
|
2401
|
+
<div class="progress"><div class="progress__bar progress__bar--success" style="width:80%" role="progressbar" aria-label="Tareas completadas" aria-valuenow="80" aria-valuemin="0" aria-valuemax="100"></div></div>
|
|
2305
2402
|
</div>
|
|
2306
2403
|
<div style="display:flex;align-items:center;gap:24px">
|
|
2307
2404
|
<div class="progress-ring js-ring" data-value="68">
|
|
@@ -2516,6 +2613,30 @@ html, body { overflow-x: clip; }
|
|
|
2516
2613
|
<!-- Delta: --up (success-text) · --down (danger-text) · neutro (text-muted) --></code></pre>
|
|
2517
2614
|
</div>
|
|
2518
2615
|
</details>
|
|
2616
|
+
|
|
2617
|
+
<h4 style="margin-top:var(--space-10)">Chip de métrica</h4>
|
|
2618
|
+
<p class="ds-spec">Pastilla de una línea con rótulo y valor en <span class="u-mono">--link</span> · fila con <span class="u-mono">gap</span> que salta de línea en móvil · el chip interactivo es un <span class="u-mono"><button></span> de 44 px con nombre accesible completo.</p>
|
|
2619
|
+
<div class="ds-demo">
|
|
2620
|
+
<div class="metric-chips">
|
|
2621
|
+
<span class="metric-chip"><span class="metric-chip__label">Pasos</span> <span class="metric-chip__value">6,240</span></span>
|
|
2622
|
+
<span class="metric-chip"><span class="metric-chip__label">Sueño</span> <span class="metric-chip__value">7 h 20 min</span></span>
|
|
2623
|
+
<button class="metric-chip" type="button" id="dsWaterChip" aria-label="Agua: 3 de 8 vasos. Sumar un vaso"><svg aria-hidden="true"><use href="#i-plus"/></svg><span class="metric-chip__label">Agua</span> <span class="metric-chip__value">3 de 8</span></button>
|
|
2624
|
+
</div>
|
|
2625
|
+
</div>
|
|
2626
|
+
<details class="ds-code"><summary>Ver código</summary>
|
|
2627
|
+
<div class="ds-code-box"><button class="ds-copy">Copiar</button>
|
|
2628
|
+
<pre class="ds-pre"><code><div class="metric-chips">
|
|
2629
|
+
<span class="metric-chip">
|
|
2630
|
+
<span class="metric-chip__label">Pasos</span> <span class="metric-chip__value">6,240</span>
|
|
2631
|
+
</span>
|
|
2632
|
+
<button class="metric-chip" type="button" aria-label="Agua: 3 de 8 vasos. Sumar un vaso">
|
|
2633
|
+
<svg aria-hidden="true">…plus…</svg>
|
|
2634
|
+
<span class="metric-chip__label">Agua</span> <span class="metric-chip__value">3 de 8</span>
|
|
2635
|
+
</button>
|
|
2636
|
+
</div>
|
|
2637
|
+
<!-- El aria-label se actualiza con el valor; empieza por el texto visible --></code></pre>
|
|
2638
|
+
</div>
|
|
2639
|
+
</details>
|
|
2519
2640
|
</div>
|
|
2520
2641
|
|
|
2521
2642
|
<!-- Pagination -->
|
|
@@ -2603,6 +2724,51 @@ html, body { overflow-x: clip; }
|
|
|
2603
2724
|
</nav></code></pre>
|
|
2604
2725
|
</div>
|
|
2605
2726
|
</details>
|
|
2727
|
+
|
|
2728
|
+
<h4 style="margin-top:var(--space-10)">Sidebar contraíble</h4>
|
|
2729
|
+
<p class="ds-spec">Expandido 260 px · riel de iconos de 64 px con grupos separados por una línea · en el riel, el nombre aparece como tooltip al pasar el cursor o al enfocar con teclado · el ancho cambia sin transición y solo los rótulos se funden · por debajo de 768 px lo sustituye un Drawer <span class="u-mono">--left</span>.</p>
|
|
2730
|
+
<div class="ds-demo ds-app-demo">
|
|
2731
|
+
<nav class="sidebar sidebar--collapsible" id="demoAppNav" aria-label="Navegación de ejemplo">
|
|
2732
|
+
<div class="sidebar__group" role="group" aria-labelledby="demoAppNavG1">
|
|
2733
|
+
<span class="sidebar__group-label" id="demoAppNavG1">Trabajo</span>
|
|
2734
|
+
<a class="sidebar__item is-active" href="#comp-navegacion" aria-current="page"><svg aria-hidden="true"><use href="#i-home"/></svg><span class="sidebar__label">Inicio</span></a>
|
|
2735
|
+
<a class="sidebar__item" href="#comp-navegacion"><svg aria-hidden="true"><use href="#i-folder"/></svg><span class="sidebar__label">Proyectos</span></a>
|
|
2736
|
+
<a class="sidebar__item" href="#comp-navegacion"><svg aria-hidden="true"><use href="#i-calendar"/></svg><span class="sidebar__label">Calendario</span></a>
|
|
2737
|
+
</div>
|
|
2738
|
+
<div class="sidebar__group" role="group" aria-labelledby="demoAppNavG2">
|
|
2739
|
+
<span class="sidebar__group-label" id="demoAppNavG2">Equipo</span>
|
|
2740
|
+
<a class="sidebar__item" href="#comp-navegacion"><svg aria-hidden="true"><use href="#i-chart"/></svg><span class="sidebar__label">Informes</span></a>
|
|
2741
|
+
<a class="sidebar__item" href="#comp-navegacion"><svg aria-hidden="true"><use href="#i-user"/></svg><span class="sidebar__label">Personas</span></a>
|
|
2742
|
+
<a class="sidebar__item" href="#comp-navegacion"><svg aria-hidden="true"><use href="#i-inbox"/></svg><span class="sidebar__label">Bandeja</span></a>
|
|
2743
|
+
</div>
|
|
2744
|
+
<button class="sidebar__item sidebar__toggle" type="button" aria-expanded="true" aria-controls="demoAppNav"><svg aria-hidden="true"><use href="#i-chevron-left"/></svg><span class="sidebar__label">Contraer</span></button>
|
|
2745
|
+
</nav>
|
|
2746
|
+
<div class="ds-app-demo__main">
|
|
2747
|
+
<button class="icon-btn icon-btn--secondary sidebar-trigger" type="button" data-drawer-open="demoNavDrawer" aria-label="Abrir navegación" aria-expanded="false" aria-controls="demoNavDrawer"><svg aria-hidden="true"><use href="#i-menu"/></svg></button>
|
|
2748
|
+
<h5 style="margin:0">Inicio</h5>
|
|
2749
|
+
<p class="ds-spec" style="margin:0">El contenido ocupa el ancho que deja el sidebar: la rejilla <span class="u-mono">auto 1fr</span> sigue al riel al instante, sin animar el ancho.</p>
|
|
2750
|
+
</div>
|
|
2751
|
+
</div>
|
|
2752
|
+
<details class="ds-code"><summary>Ver código</summary>
|
|
2753
|
+
<div class="ds-code-box"><button class="ds-copy">Copiar</button>
|
|
2754
|
+
<pre class="ds-pre"><code><nav class="sidebar sidebar--collapsible" id="appNav" aria-label="Principal">
|
|
2755
|
+
<div class="sidebar__group" role="group" aria-labelledby="navTrabajo">
|
|
2756
|
+
<span class="sidebar__group-label" id="navTrabajo">Trabajo</span>
|
|
2757
|
+
<a class="sidebar__item is-active" href="/" aria-current="page">
|
|
2758
|
+
<svg aria-hidden="true">…</svg><span class="sidebar__label">Inicio</span>
|
|
2759
|
+
</a>
|
|
2760
|
+
</div>
|
|
2761
|
+
<button class="sidebar__item sidebar__toggle" type="button"
|
|
2762
|
+
aria-expanded="true" aria-controls="appNav">
|
|
2763
|
+
<svg aria-hidden="true">…chevron-left…</svg><span class="sidebar__label">Contraer</span>
|
|
2764
|
+
</button>
|
|
2765
|
+
</nav>
|
|
2766
|
+
<!-- Contraído: .is-collapsed en el nav, aria-expanded="false" y texto «Expandir».
|
|
2767
|
+
Por debajo de 768 px: botón ☰ .sidebar-trigger que abre un .drawer.drawer--left con los mismos ítems. -->
|
|
2768
|
+
<button class="icon-btn sidebar-trigger" type="button" aria-label="Abrir navegación"
|
|
2769
|
+
aria-expanded="false" aria-controls="navDrawer">…menu…</button></code></pre>
|
|
2770
|
+
</div>
|
|
2771
|
+
</details>
|
|
2606
2772
|
</div>
|
|
2607
2773
|
|
|
2608
2774
|
<!-- Skeleton y EmptyState -->
|
|
@@ -2804,7 +2970,7 @@ html, body { overflow-x: clip; }
|
|
|
2804
2970
|
<label class="field__label" for="dpInput">Fecha de entrega</label>
|
|
2805
2971
|
<div class="datepicker" id="demoDatepicker">
|
|
2806
2972
|
<input class="datepicker__input" id="dpInput" type="text" readonly autocomplete="off"
|
|
2807
|
-
aria-haspopup="dialog" aria-
|
|
2973
|
+
aria-haspopup="dialog" aria-controls="dpCal" placeholder="Elige una fecha">
|
|
2808
2974
|
<svg class="datepicker__icon" aria-hidden="true"><use href="#i-calendar"/></svg>
|
|
2809
2975
|
<div class="datepicker__calendar" id="dpCal" role="dialog" aria-label="Elegir fecha" tabindex="-1">
|
|
2810
2976
|
<div class="calendar">
|
|
@@ -2813,6 +2979,7 @@ html, body { overflow-x: clip; }
|
|
|
2813
2979
|
<span class="calendar__title" aria-live="polite">—</span>
|
|
2814
2980
|
<button class="icon-btn icon-btn--ghost icon-btn--sm" type="button" data-cal-next aria-label="Mes siguiente"><svg><use href="#i-chevron-right"/></svg></button>
|
|
2815
2981
|
</div>
|
|
2982
|
+
<div class="calendar__table" role="grid" aria-label="Calendario">
|
|
2816
2983
|
<div class="calendar__weekdays" role="row">
|
|
2817
2984
|
<span class="calendar__weekday" role="columnheader" aria-label="lunes">lu</span>
|
|
2818
2985
|
<span class="calendar__weekday" role="columnheader" aria-label="martes">ma</span>
|
|
@@ -2822,7 +2989,8 @@ html, body { overflow-x: clip; }
|
|
|
2822
2989
|
<span class="calendar__weekday" role="columnheader" aria-label="sábado">sá</span>
|
|
2823
2990
|
<span class="calendar__weekday" role="columnheader" aria-label="domingo">do</span>
|
|
2824
2991
|
</div>
|
|
2825
|
-
<div class="calendar__grid" id="dpGrid" role="
|
|
2992
|
+
<div class="calendar__grid" id="dpGrid" role="rowgroup"></div>
|
|
2993
|
+
</div>
|
|
2826
2994
|
</div>
|
|
2827
2995
|
</div>
|
|
2828
2996
|
</div>
|
|
@@ -2832,7 +3000,7 @@ html, body { overflow-x: clip; }
|
|
|
2832
3000
|
<div class="ds-code-box"><button class="ds-copy">Copiar</button>
|
|
2833
3001
|
<pre class="ds-pre"><code><div class="datepicker">
|
|
2834
3002
|
<input class="datepicker__input" type="text" readonly
|
|
2835
|
-
aria-haspopup="dialog" aria-
|
|
3003
|
+
aria-haspopup="dialog" aria-controls="cal">
|
|
2836
3004
|
<svg class="datepicker__icon" aria-hidden="true">…calendario…</svg>
|
|
2837
3005
|
<div class="datepicker__calendar" id="cal" role="dialog"
|
|
2838
3006
|
aria-label="Elegir fecha" tabindex="-1">
|
|
@@ -2842,17 +3010,21 @@ html, body { overflow-x: clip; }
|
|
|
2842
3010
|
<span class="calendar__title">julio 2026</span>
|
|
2843
3011
|
<button aria-label="Mes siguiente">…</button>
|
|
2844
3012
|
</div>
|
|
3013
|
+
<div class="calendar__table" role="grid" aria-label="julio 2026">
|
|
2845
3014
|
<div class="calendar__weekdays" role="row">
|
|
2846
3015
|
<span class="calendar__weekday" role="columnheader"
|
|
2847
3016
|
aria-label="lunes">lu</span> …
|
|
2848
3017
|
</div>
|
|
2849
|
-
<div class="calendar__grid" role="
|
|
3018
|
+
<div class="calendar__grid" role="rowgroup">
|
|
3019
|
+
<div class="calendar__week" role="row">
|
|
2850
3020
|
<button class="calendar__day calendar__day--today" role="gridcell"
|
|
2851
3021
|
aria-label="viernes, 10 de julio de 2026"
|
|
2852
3022
|
aria-selected="false">10</button>
|
|
2853
3023
|
<button class="calendar__day calendar__day--selected" role="gridcell"
|
|
2854
3024
|
aria-label="viernes, 17 de julio de 2026"
|
|
2855
3025
|
aria-selected="true">17</button> …
|
|
3026
|
+
</div>
|
|
3027
|
+
</div>
|
|
2856
3028
|
</div>
|
|
2857
3029
|
</div>
|
|
2858
3030
|
</div>
|
|
@@ -3221,7 +3393,7 @@ html, body { overflow-x: clip; }
|
|
|
3221
3393
|
<p class="ds-lead">El sistema se distribuye como paquete npm (<span class="u-mono">@higinio/design-css</span>) y también como archivos sueltos en <span class="u-mono">dist/celeste-clasica/</span>. Instálalo o cópialos, y elige qué importar según tu stack (A/B/C). En todas: <strong>light por defecto</strong>; <span class="u-mono"><html data-theme="dark"></span> activa el modo oscuro, y los componentes consumen <strong>solo aliases semánticos</strong>, nunca hex.</p>
|
|
3222
3394
|
|
|
3223
3395
|
<h3>Instalar desde npm (recomendado)</h3>
|
|
3224
|
-
<p>Un solo paquete con los
|
|
3396
|
+
<p>Un solo paquete con todos los sistemas, cada uno en su subruta; Celeste Clásica vive en <span class="u-mono">/celeste/</span>. Instálalo y usa las vías A/B/C apuntando a la subruta, en vez de a un archivo copiado.</p>
|
|
3225
3397
|
<div class="ds-code-box"><button class="ds-copy">Copiar</button>
|
|
3226
3398
|
<pre class="ds-pre"><code>npm i @higinio/design-css
|
|
3227
3399
|
|
|
@@ -3283,20 +3455,23 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
3283
3455
|
<section id="mcp">
|
|
3284
3456
|
<p class="ds-eyebrow">Sistema</p>
|
|
3285
3457
|
<h2>MCP</h2>
|
|
3286
|
-
<p class="ds-lead">El paquete <span class="code">@higinio/design-mcp</span> expone
|
|
3458
|
+
<p class="ds-lead">El paquete <span class="code">@higinio/design-mcp</span> expone los sistemas de diseño de Higinio Sosa, entre ellos Celeste Clásica (<span class="u-mono">system="celeste"</span>), a cualquier IDE o cliente compatible con Model Context Protocol: tokens, componentes, reglas duras y validación de código. Complementa a las skills de Claude, no las reemplaza: misma fuente de verdad, accesible también fuera del entorno de Claude.</p>
|
|
3287
3459
|
|
|
3288
|
-
<h3>Las
|
|
3460
|
+
<h3>Las 11 tools</h3>
|
|
3289
3461
|
<div class="ds-demo ds-demo--col" style="padding:0;overflow-x:auto">
|
|
3290
3462
|
<table class="table">
|
|
3291
3463
|
<thead><tr><th>Tool</th><th>Qué hace</th></tr></thead>
|
|
3292
3464
|
<tbody>
|
|
3293
3465
|
<tr><td class="u-mono">list_design_systems</td><td>Lista los sistemas de diseño disponibles.</td></tr>
|
|
3294
|
-
<tr><td class="u-mono">get_token</td><td>
|
|
3466
|
+
<tr><td class="u-mono">get_token</td><td>Resuelve un alias semántico o un token DTCG por path a su valor.</td></tr>
|
|
3295
3467
|
<tr><td class="u-mono">search_tokens</td><td>Busca tokens por nombre, categoría o valor.</td></tr>
|
|
3296
3468
|
<tr><td class="u-mono">list_components</td><td>Lista los componentes documentados de un sistema.</td></tr>
|
|
3297
3469
|
<tr><td class="u-mono">get_component_spec</td><td>Devuelve la especificación completa de un componente: estados, medidas, variantes.</td></tr>
|
|
3298
3470
|
<tr><td class="u-mono">get_rules</td><td>Devuelve las reglas duras (no negociables) del sistema.</td></tr>
|
|
3299
3471
|
<tr><td class="u-mono">validate_code</td><td>Audita CSS/HTML contra las reglas del sistema — hex directos, contraste, aliases.</td></tr>
|
|
3472
|
+
<tr><td class="u-mono">validate_motion</td><td>Audita el motion contra las reglas del sistema: <span class="u-mono">transition</span> sobre todas las propiedades, ease-in en entradas, propiedades de layout, duraciones por encima de <span class="u-mono">--duration-page</span>.</td></tr>
|
|
3473
|
+
<tr><td class="u-mono">check_slop</td><td>Detecta clichés de diseño generado por IA: gradientes, glassmorphism, sombras de negro puro, fuentes genéricas y copy de marketing.</td></tr>
|
|
3474
|
+
<tr><td class="u-mono">checklist_preflight</td><td>Checklist estático de pre-producción sobre HTML/CSS: metadatos, headings, imágenes y accesibilidad de controles.</td></tr>
|
|
3300
3475
|
<tr><td class="u-mono">generate_snippet</td><td>Genera un snippet de componente listo para usar, con los aliases correctos.</td></tr>
|
|
3301
3476
|
</tbody>
|
|
3302
3477
|
</table>
|
|
@@ -3390,6 +3565,31 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
3390
3565
|
</div>
|
|
3391
3566
|
</div>
|
|
3392
3567
|
|
|
3568
|
+
<!-- Navegación móvil del Sidebar contraíble (§10.24): Drawer --left -->
|
|
3569
|
+
<div class="drawer drawer--left" id="demoNavDrawer" role="dialog" aria-modal="true" aria-labelledby="demoNavDrawerTitle">
|
|
3570
|
+
<div class="drawer__overlay" data-drawer-close></div>
|
|
3571
|
+
<div class="drawer__panel" tabindex="-1">
|
|
3572
|
+
<div class="drawer__header">
|
|
3573
|
+
<h4 class="drawer__title" id="demoNavDrawerTitle">Navegación</h4>
|
|
3574
|
+
<button class="icon-btn icon-btn--ghost" data-drawer-close aria-label="Cerrar"><svg><use href="#i-x"/></svg></button>
|
|
3575
|
+
</div>
|
|
3576
|
+
<nav class="drawer__body" aria-label="Navegación de ejemplo">
|
|
3577
|
+
<div class="sidebar__group" role="group" aria-labelledby="demoNavDrawerG1">
|
|
3578
|
+
<span class="sidebar__group-label" id="demoNavDrawerG1">Trabajo</span>
|
|
3579
|
+
<a class="sidebar__item is-active" href="#comp-navegacion" aria-current="page" data-drawer-close><svg aria-hidden="true"><use href="#i-home"/></svg><span class="sidebar__label">Inicio</span></a>
|
|
3580
|
+
<a class="sidebar__item" href="#comp-navegacion" data-drawer-close><svg aria-hidden="true"><use href="#i-folder"/></svg><span class="sidebar__label">Proyectos</span></a>
|
|
3581
|
+
<a class="sidebar__item" href="#comp-navegacion" data-drawer-close><svg aria-hidden="true"><use href="#i-calendar"/></svg><span class="sidebar__label">Calendario</span></a>
|
|
3582
|
+
</div>
|
|
3583
|
+
<div class="sidebar__group" role="group" aria-labelledby="demoNavDrawerG2">
|
|
3584
|
+
<span class="sidebar__group-label" id="demoNavDrawerG2">Equipo</span>
|
|
3585
|
+
<a class="sidebar__item" href="#comp-navegacion" data-drawer-close><svg aria-hidden="true"><use href="#i-chart"/></svg><span class="sidebar__label">Informes</span></a>
|
|
3586
|
+
<a class="sidebar__item" href="#comp-navegacion" data-drawer-close><svg aria-hidden="true"><use href="#i-user"/></svg><span class="sidebar__label">Personas</span></a>
|
|
3587
|
+
<a class="sidebar__item" href="#comp-navegacion" data-drawer-close><svg aria-hidden="true"><use href="#i-inbox"/></svg><span class="sidebar__label">Bandeja</span></a>
|
|
3588
|
+
</div>
|
|
3589
|
+
</nav>
|
|
3590
|
+
</div>
|
|
3591
|
+
</div>
|
|
3592
|
+
|
|
3393
3593
|
<!-- Drawer de demostración (§10.29) -->
|
|
3394
3594
|
<div class="drawer drawer--right" id="demoDrawer" role="dialog" aria-modal="true" aria-labelledby="demoDrawerTitle">
|
|
3395
3595
|
<div class="drawer__overlay" data-drawer-close></div>
|
|
@@ -3843,6 +4043,31 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
3843
4043
|
});
|
|
3844
4044
|
});
|
|
3845
4045
|
|
|
4046
|
+
/* ---------- Sidebar contraíble (§10.24): riel de iconos ---------- */
|
|
4047
|
+
Array.prototype.forEach.call(d.querySelectorAll(".sidebar__toggle"), function (btn) {
|
|
4048
|
+
var nav = d.getElementById(btn.getAttribute("aria-controls"));
|
|
4049
|
+
var label = btn.querySelector(".sidebar__label");
|
|
4050
|
+
if (!nav) return;
|
|
4051
|
+
btn.addEventListener("click", function () {
|
|
4052
|
+
var collapsed = nav.classList.toggle("is-collapsed");
|
|
4053
|
+
btn.setAttribute("aria-expanded", collapsed ? "false" : "true");
|
|
4054
|
+
if (label) label.textContent = collapsed ? "Expandir" : "Contraer";
|
|
4055
|
+
});
|
|
4056
|
+
});
|
|
4057
|
+
|
|
4058
|
+
/* ---------- Chip de métrica (§10.22): sumar un vaso ---------- */
|
|
4059
|
+
var waterChip = d.getElementById("dsWaterChip");
|
|
4060
|
+
if (waterChip) {
|
|
4061
|
+
var waterValue = waterChip.querySelector(".metric-chip__value");
|
|
4062
|
+
var waterMax = 8, water = 3;
|
|
4063
|
+
waterChip.addEventListener("click", function () {
|
|
4064
|
+
water = water >= waterMax ? 0 : water + 1;
|
|
4065
|
+
waterValue.textContent = water + " de " + waterMax;
|
|
4066
|
+
waterChip.setAttribute("aria-label", "Agua: " + water + " de " + waterMax + " vasos. " +
|
|
4067
|
+
(water < waterMax ? "Sumar un vaso" : "Empezar de nuevo"));
|
|
4068
|
+
});
|
|
4069
|
+
}
|
|
4070
|
+
|
|
3846
4071
|
/* ---------- Toast ---------- */
|
|
3847
4072
|
var TOAST_DATA = {
|
|
3848
4073
|
success: ["i-circle-check", "Cambios guardados", "El proyecto se actualizó correctamente."],
|
|
@@ -3988,6 +4213,7 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
3988
4213
|
if (!dr) return;
|
|
3989
4214
|
drawerTrigger = trigger || d.activeElement;
|
|
3990
4215
|
dr.classList.add("is-open");
|
|
4216
|
+
if (drawerTrigger.hasAttribute("aria-expanded")) drawerTrigger.setAttribute("aria-expanded", "true");
|
|
3991
4217
|
var f = modalFocusables(dr);
|
|
3992
4218
|
var panel = dr.querySelector(".drawer__panel");
|
|
3993
4219
|
window.setTimeout(function () { (f[0] || panel).focus(); }, 0);
|
|
@@ -3995,6 +4221,7 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
3995
4221
|
function closeDrawer(dr) {
|
|
3996
4222
|
if (!dr || !dr.classList.contains("is-open")) return;
|
|
3997
4223
|
dr.classList.remove("is-open");
|
|
4224
|
+
if (drawerTrigger && drawerTrigger.hasAttribute("aria-expanded")) drawerTrigger.setAttribute("aria-expanded", "false");
|
|
3998
4225
|
if (drawerTrigger && typeof drawerTrigger.focus === "function") drawerTrigger.focus();
|
|
3999
4226
|
drawerTrigger = null;
|
|
4000
4227
|
}
|
|
@@ -4152,6 +4379,7 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
4152
4379
|
var dpInput = d.getElementById("dpInput");
|
|
4153
4380
|
var dpCal = d.getElementById("dpCal");
|
|
4154
4381
|
var dpGrid = d.getElementById("dpGrid");
|
|
4382
|
+
var dpTable = dpGrid.parentNode;
|
|
4155
4383
|
var dpTitle = dp.querySelector(".calendar__title");
|
|
4156
4384
|
var MONTHS = ["enero", "febrero", "marzo", "abril", "mayo", "junio",
|
|
4157
4385
|
"julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];
|
|
@@ -4168,13 +4396,20 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
4168
4396
|
function dpRender() {
|
|
4169
4397
|
var y = view.getFullYear(), m = view.getMonth();
|
|
4170
4398
|
dpTitle.textContent = MONTHS[m] + " " + y;
|
|
4171
|
-
|
|
4399
|
+
dpTable.setAttribute("aria-label", MONTHS[m] + " " + y);
|
|
4172
4400
|
dpGrid.innerHTML = "";
|
|
4173
4401
|
var startDow = (new Date(y, m, 1).getDay() + 6) % 7; // lunes = 0
|
|
4174
4402
|
var daysInMonth = new Date(y, m + 1, 0).getDate();
|
|
4175
4403
|
var weeks = Math.ceil((startDow + daysInMonth) / 7);
|
|
4176
4404
|
var start = new Date(y, m, 1 - startDow);
|
|
4405
|
+
var week = null;
|
|
4177
4406
|
for (var i = 0; i < weeks * 7; i++) {
|
|
4407
|
+
if (i % 7 === 0) {
|
|
4408
|
+
week = d.createElement("div");
|
|
4409
|
+
week.className = "calendar__week";
|
|
4410
|
+
week.setAttribute("role", "row");
|
|
4411
|
+
dpGrid.appendChild(week);
|
|
4412
|
+
}
|
|
4178
4413
|
var cell = new Date(start.getFullYear(), start.getMonth(), start.getDate() + i);
|
|
4179
4414
|
var btn = d.createElement("button");
|
|
4180
4415
|
btn.type = "button";
|
|
@@ -4189,7 +4424,7 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
4189
4424
|
btn.setAttribute("aria-label", fmtLong.format(cell));
|
|
4190
4425
|
btn.tabIndex = sameDay(cell, focusDate) ? 0 : -1;
|
|
4191
4426
|
btn.setAttribute("data-ts", String(cell.getTime()));
|
|
4192
|
-
|
|
4427
|
+
week.appendChild(btn);
|
|
4193
4428
|
}
|
|
4194
4429
|
}
|
|
4195
4430
|
function dpButtonFor(dt) { return dpGrid.querySelector('[data-ts="' + atMidnight(dt).getTime() + '"]'); }
|
|
@@ -4208,7 +4443,6 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
4208
4443
|
}
|
|
4209
4444
|
function dpOpen() {
|
|
4210
4445
|
dp.classList.add("is-open");
|
|
4211
|
-
dpInput.setAttribute("aria-expanded", "true");
|
|
4212
4446
|
focusDate = new Date(selected);
|
|
4213
4447
|
view = new Date(focusDate.getFullYear(), focusDate.getMonth(), 1);
|
|
4214
4448
|
dpRender();
|
|
@@ -4217,7 +4451,6 @@ npm i tailwindcss @tailwindcss/postcss
|
|
|
4217
4451
|
function dpClose(returnFocus) {
|
|
4218
4452
|
if (!dp.classList.contains("is-open")) return;
|
|
4219
4453
|
dp.classList.remove("is-open");
|
|
4220
|
-
dpInput.setAttribute("aria-expanded", "false");
|
|
4221
4454
|
if (returnFocus) dpInput.focus();
|
|
4222
4455
|
}
|
|
4223
4456
|
function dpSelect(dt) {
|