paneltir 0.11.0 → 0.12.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/dist/style.css CHANGED
@@ -308,6 +308,133 @@
308
308
  font-weight: 700;
309
309
  }
310
310
 
311
+ /* src/components/Situation/Situation.css */
312
+ .pt-situation {
313
+ display: grid;
314
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
315
+ gap: var(--pt-space-page);
316
+ align-items: start;
317
+ padding: var(--pt-space-lg);
318
+ border: 1px solid var(--pt-color-line-faint);
319
+ border-radius: var(--pt-radius-panel);
320
+ background: var(--pt-color-panel);
321
+ }
322
+ .pt-situation__half {
323
+ display: flex;
324
+ flex-direction: column;
325
+ gap: var(--pt-space-sm);
326
+ min-width: 0;
327
+ }
328
+ .pt-situation__clear {
329
+ margin: 0;
330
+ color: var(--pt-color-ink-dim);
331
+ font-size: 13px;
332
+ }
333
+ .pt-situation__items {
334
+ display: flex;
335
+ flex-wrap: wrap;
336
+ gap: var(--pt-space-md);
337
+ }
338
+ .pt-situation__item {
339
+ display: grid;
340
+ grid-template-columns: auto minmax(0, 1fr);
341
+ grid-template-rows: auto auto;
342
+ column-gap: var(--pt-space-sm);
343
+ align-items: center;
344
+ min-width: 0;
345
+ margin: 0;
346
+ padding: var(--pt-space-sm) var(--pt-space-md);
347
+ border: 1px solid var(--pt-color-line-faint);
348
+ border-left: 3px solid var(--pt-color-neutral);
349
+ border-radius: var(--pt-radius-control);
350
+ background: var(--pt-color-raised);
351
+ color: inherit;
352
+ font: inherit;
353
+ text-align: left;
354
+ }
355
+ button.pt-situation__item {
356
+ cursor: pointer;
357
+ }
358
+ button.pt-situation__item:hover,
359
+ button.pt-situation__item:focus-visible {
360
+ border-color: var(--pt-color-line);
361
+ }
362
+ .pt-situation__count {
363
+ grid-row: 1 / span 2;
364
+ font-family: var(--pt-font-mono);
365
+ font-size: 26px;
366
+ line-height: 1;
367
+ font-weight: 700;
368
+ font-variant-numeric: tabular-nums;
369
+ }
370
+ .pt-situation__label {
371
+ font-size: 12px;
372
+ font-weight: 700;
373
+ letter-spacing: 0.02em;
374
+ }
375
+ .pt-situation__hint {
376
+ font-size: 11px;
377
+ color: var(--pt-color-ink-faint);
378
+ }
379
+ .pt-situation__item--clear {
380
+ border-left-color: var(--pt-color-line);
381
+ }
382
+ .pt-situation__item--clear .pt-situation__count {
383
+ color: var(--pt-color-ink-faint);
384
+ }
385
+ .pt-situation__item--attention {
386
+ border-left-color: var(--pt-color-warning);
387
+ }
388
+ .pt-situation__item--attention .pt-situation__count {
389
+ color: var(--pt-color-warning);
390
+ }
391
+ .pt-situation__item--alarm {
392
+ border-left-color: var(--pt-color-danger);
393
+ }
394
+ .pt-situation__item--alarm .pt-situation__count {
395
+ color: var(--pt-color-danger);
396
+ }
397
+ [data-pt-form=warRoom] .pt-situation {
398
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
399
+ border-color: var(--pt-color-line);
400
+ border-radius: var(--pt-radius-panel);
401
+ background: var(--pt-color-ground-raised);
402
+ }
403
+ [data-pt-form=warRoom] .pt-situation__item {
404
+ border-radius: 0;
405
+ border-left-width: 4px;
406
+ background: var(--pt-color-panel);
407
+ }
408
+ [data-pt-form=warRoom] .pt-situation__count {
409
+ font-size: 30px;
410
+ }
411
+ [data-pt-form=warRoom] .pt-situation__label {
412
+ text-transform: uppercase;
413
+ letter-spacing: var(--pt-label-tracking);
414
+ }
415
+ [data-pt-form=warRoom] .pt-health-pill {
416
+ border-radius: 0;
417
+ border-color: var(--pt-color-line);
418
+ }
419
+ [data-pt-form=warRoom] .pt-health-pill::before {
420
+ width: 3px;
421
+ height: 12px;
422
+ border-radius: 0;
423
+ }
424
+ [data-pt-form=warRoom] .pt-health-pill__value {
425
+ font-family: var(--pt-font-mono);
426
+ font-variant-numeric: tabular-nums;
427
+ }
428
+ @media (max-width: 860px) {
429
+ .pt-situation,
430
+ [data-pt-form] .pt-situation {
431
+ grid-template-columns: minmax(0, 1fr);
432
+ }
433
+ .pt-situation__items {
434
+ flex-direction: column;
435
+ }
436
+ }
437
+
311
438
  /* src/components/FilterChips/FilterChips.css */
312
439
  .pt-filter-row {
313
440
  display: flex;
@@ -616,6 +743,74 @@
616
743
  .pt-column__list > * {
617
744
  flex-shrink: 0;
618
745
  }
746
+ [data-pt-form=warRoom] .pt-board {
747
+ gap: var(--pt-space-md);
748
+ }
749
+ [data-pt-form=warRoom] .pt-column {
750
+ background: var(--pt-color-ground-raised, var(--pt-color-panel));
751
+ border: var(--pt-border-width) solid var(--pt-color-line);
752
+ border-top: 2px solid var(--pt-color-line);
753
+ }
754
+ [data-pt-form=warRoom] .pt-column__header {
755
+ padding: var(--pt-space-sm) var(--pt-space-sm);
756
+ border-bottom: var(--pt-border-width) solid var(--pt-color-line);
757
+ background: var(--pt-color-panel);
758
+ }
759
+ [data-pt-form=warRoom] .pt-column__title {
760
+ font-size: 10.5px;
761
+ font-weight: 700;
762
+ }
763
+ [data-pt-form=warRoom] .pt-column__count {
764
+ font-family: var(--pt-font-mono);
765
+ font-size: 11px;
766
+ padding: 1px 5px;
767
+ border: var(--pt-border-width) solid var(--pt-color-line-faint);
768
+ color: var(--pt-color-ink-dim);
769
+ }
770
+ [data-pt-form=warRoom] .pt-column__add {
771
+ border-radius: 0;
772
+ background: none;
773
+ }
774
+ [data-pt-form=warRoom] .pt-column__list {
775
+ padding: 0;
776
+ gap: 0;
777
+ }
778
+ [data-pt-form=warRoom] .pt-card {
779
+ background: none;
780
+ border-radius: 0;
781
+ border-bottom: var(--pt-border-width) solid var(--pt-color-line-faint);
782
+ padding: var(--pt-space-sm) var(--pt-space-sm) var(--pt-space-sm) calc(var(--pt-space-sm) + 5px);
783
+ }
784
+ [data-pt-form=warRoom] .pt-card:hover {
785
+ background: var(--pt-color-raised);
786
+ }
787
+ [data-pt-form=warRoom] .pt-card::before {
788
+ width: 3px;
789
+ border-radius: 0;
790
+ }
791
+ [data-pt-form=warRoom] .pt-card__title {
792
+ font-weight: 500;
793
+ font-size: 13px;
794
+ }
795
+ [data-pt-form=warRoom] .pt-card__progress {
796
+ font-family: var(--pt-font-mono);
797
+ }
798
+ [data-pt-form=warRoom] .pt-card-placeholder {
799
+ border: none;
800
+ border-bottom: 2px dashed var(--pt-color-accent);
801
+ border-radius: 0;
802
+ min-height: 28px;
803
+ }
804
+ [data-pt-form=warRoom] .pt-tag {
805
+ border-radius: 0;
806
+ font-size: 10px;
807
+ letter-spacing: var(--pt-label-tracking);
808
+ text-transform: uppercase;
809
+ }
810
+ [data-pt-form=warRoom] .pt-column__footer {
811
+ font-family: var(--pt-font-mono);
812
+ padding: var(--pt-space-sm);
813
+ }
619
814
 
620
815
  /* src/components/DetailSheet/DetailSheet.css */
621
816
  .pt-sheet-backdrop {
@@ -2113,5 +2308,44 @@
2113
2308
  margin-top: auto;
2114
2309
  padding-top: 4px;
2115
2310
  }
2311
+ .pt-archive {
2312
+ margin: 0;
2313
+ padding: 0;
2314
+ list-style: none;
2315
+ display: grid;
2316
+ border-top: 1px solid var(--pt-color-line-faint);
2317
+ }
2318
+ .pt-archive__row {
2319
+ display: flex;
2320
+ align-items: baseline;
2321
+ justify-content: space-between;
2322
+ gap: var(--pt-space-md);
2323
+ width: 100%;
2324
+ margin: 0;
2325
+ padding: 9px var(--pt-space-sm);
2326
+ border: 0;
2327
+ border-bottom: 1px solid var(--pt-color-line-faint);
2328
+ background: transparent;
2329
+ color: inherit;
2330
+ font: inherit;
2331
+ text-align: left;
2332
+ cursor: pointer;
2333
+ }
2334
+ .pt-archive__row:hover,
2335
+ .pt-archive__row:focus-visible {
2336
+ background: var(--pt-color-raised);
2337
+ }
2338
+ .pt-archive__title {
2339
+ color: var(--pt-color-ink-dim);
2340
+ font-size: 13px;
2341
+ min-width: 0;
2342
+ }
2343
+ .pt-archive__meta {
2344
+ flex: 0 0 auto;
2345
+ font-family: var(--pt-font-mono);
2346
+ font-size: 11px;
2347
+ color: var(--pt-color-ink-faint);
2348
+ font-variant-numeric: tabular-nums;
2349
+ }
2116
2350
 
2117
2351
  /* src/style.css */
package/fingerprint.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "paneltir",
3
- "version": "0.11.0",
4
- "hash": "sha256:2739462e763939de1d1aeb8ab97779149c2ddb0ec2d2fb45644c4c45ef9dc9fa",
5
- "fileCount": 163,
6
- "templateHash": "sha256:034ba27266408af4f2ba5793d9cefbe448b168570d6a0b87dfe698dfe639feb1",
7
- "generatedAt": "2026-09-13T08:39:02.027Z"
3
+ "version": "0.12.0",
4
+ "hash": "sha256:ea981bdb1de721f4d2afd279244a7298b025773fb4a5abf8ffa33868c0d73f7d",
5
+ "fileCount": 166,
6
+ "templateHash": "sha256:c0c1a1678d860212ff82d55c7e7c0ee3eaf8be623621cadbb6ca5bf51b31e2ba",
7
+ "generatedAt": "2026-09-14T04:42:15.291Z"
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paneltir",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "A React UI kit for admin panels: page frame, a board with touch-ready drag and drop, detail sheets, and a whole panel in one component. Structure and behaviour are fixed; colour and brand belong to each project.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "DFKlabs (https://DFKlabs.com)",
@@ -99,28 +99,49 @@
99
99
  "node": ">=20"
100
100
  },
101
101
  "paneltirRelease": {
102
- "version": "0.11.0",
103
- "date": "2026-09-13",
102
+ "version": "0.12.0",
103
+ "date": "2026-09-14",
104
104
  "entries": [
105
105
  {
106
106
  "kind": "feature",
107
107
  "text": {
108
- "en": "A card finished more than a week ago stops being drawn in its column. The column says how many it is holding and one tap shows them — nothing is hidden without being accounted for.",
109
- "es": "Una tarjeta terminada hace más de una semana deja de dibujarse en su columna. La columna dice cuántas guarda y un toque las enseña — nada se esconde sin quedar contado."
108
+ "en": "Archived cards leave the board and get a place of their own. A card finished more than a week ago is no longer drawn in its column at all — it is listed in the record view, under what each pass did, with the date it was finished. The count in its column was still the board carrying it: one tap put fifteen finished cards back in the way.",
109
+ "es": "Las tarjetas archivadas salen del tablero y tienen su propio sitio. Una tarjeta terminada hace más de una semana ya no se dibuja en su columna: aparece en la vista de revisiones, debajo de lo que hizo cada pasada, con la fecha en que se terminó. El contador en la columna seguía siendo el tablero cargando con ellas: un toque devolvía quince tarjetas terminadas a en medio."
110
110
  }
111
111
  },
112
112
  {
113
113
  "kind": "feature",
114
114
  "text": {
115
- "en": "A board column can carry a footer, drawn inside its own scroll so it takes no height from the cards.",
116
- "es": "Una columna del tablero puede llevar un pie, dibujado dentro de su propio scroll para que no le quite alto a las tarjetas."
115
+ "en": "A new strip at the top of the board says what is waiting on you and whether the system is working. The two questions a board is opened to answer were on the screen and neither was prominent — three of six identical tiles, and a line of small grey pills under them. The counts are now large and are controls: tapping one filters the board or opens the question.",
116
+ "es": "Una franja nueva encima del tablero dice qué te está esperando y si el sistema funciona. Las dos preguntas por las que se abre un tablero estaban en pantalla y ninguna destacaba: tres de seis casillas iguales, y una línea de pastillas grises debajo. Ahora los números son grandes y son controles: tocar uno filtra el tablero o abre la pregunta."
117
+ }
118
+ },
119
+ {
120
+ "kind": "feature",
121
+ "text": {
122
+ "en": "A third board shape, `warRoom`: square, hairline-ruled, tight, priority carried as a full-height bar down the left edge of every row and counts set in the monospace face. It is the only form that tightens rather than loosens the spacing — a board somebody is watching wants as many rows on the screen as will fit. Ask for it with `THEME_FORMS.warRoom` on a theme's `form`.",
123
+ "es": "Una tercera forma de tablero, `warRoom`: cuadrada, reglada a un pelo, apretada, con la prioridad como una barra de alto completo en el borde izquierdo de cada fila y los números en la tipografía monoespaciada. Es la única forma que aprieta el espaciado en vez de soltarlo: un tablero que se vigila quiere tantas filas en pantalla como quepan. Se pide con `THEME_FORMS.warRoom` en el `form` de un tema."
124
+ }
125
+ },
126
+ {
127
+ "kind": "feature",
128
+ "text": {
129
+ "en": "`SituationRow` is exported, so a project building its own screen out of the components can draw the same strip.",
130
+ "es": "`SituationRow` se exporta, así que un proyecto que construye su propia pantalla con los componentes puede dibujar la misma franja."
131
+ }
132
+ },
133
+ {
134
+ "kind": "fix",
135
+ "text": {
136
+ "en": "The open decisions counter counts questions nobody has answered, not cards about deciding. Those are different numbers and the one that holds work up is the first.",
137
+ "es": "El contador de decisiones abiertas cuenta preguntas que nadie ha contestado, no tarjetas sobre decidir. Son números distintos y el que frena el trabajo es el primero."
117
138
  }
118
139
  },
119
140
  {
120
141
  "kind": "chore",
121
142
  "text": {
122
- "en": "A card in a scrolling column can never shrink below its own content, so a title can never be cut in half.",
123
- "es": "Una tarjeta en una columna con scroll no puede encogerse por debajo de su contenido, así que un título no puede quedar cortado por la mitad."
143
+ "en": "A shape declared with no drawing now fails the checks. A form whose CSS is missing renders exactly as the default, which does not look like a missing stylesheet — it looks like the `form` prop being ignored.",
144
+ "es": "Una forma declarada sin dibujo ahora falla las comprobaciones. Una forma a la que le falta el CSS se dibuja igual que la de por defecto, y eso no parece una hoja de estilos que falta: parece que la prop `form` se está ignorando."
124
145
  }
125
146
  }
126
147
  ]
@@ -96,6 +96,19 @@ becomes a card in the owner's column, when only they can do it.
96
96
  A card carrying `completedAt` with no `startedAt` was declared finished
97
97
  without ever being picked up, and the panel marks it. Never create that shape.
98
98
 
99
+ **A card finished more than a week ago leaves the board.** It is not deleted
100
+ and it is still in the file: the panel simply stops drawing it in its column
101
+ and lists it in the record view instead, under what each pass did, with the
102
+ date it was finished. So a done column that looks short is not a done column
103
+ that lost anything — read the file, not the screen, when counting what has been
104
+ finished.
105
+
106
+ This is derived from `completedAt` on every render and never written, so
107
+ nothing marks it and nothing ages. The one card it never applies to is a card
108
+ in a done column with **no `completedAt` at all**: its age is unknown, so it
109
+ stays on the board. That is another reason to stamp the date when you move a
110
+ card to done.
111
+
99
112
  ## Writing back
100
113
 
101
114
  The board is a conversation. Leave it saying what happened:
@@ -139,6 +152,16 @@ every preset and the settings sheet shows a single row. Two projects were
139
152
  installed that way before the distinction existed, and the symptom reads as the
140
153
  kit having no themes rather than as a prop being wrong.
141
154
 
155
+ A theme also carries a **form**, which is the shape it is drawn in rather than
156
+ its colours. `THEME_FORMS.panel` is the default — raised cards floating in a
157
+ rounded column. `THEME_FORMS.ledger` is a book: squared, hairline-ruled, set in
158
+ a serif. `THEME_FORMS.warRoom` is an operations console: square, tight, with
159
+ priority as a bar down the left edge of every row and counts in the monospace
160
+ face, and it is the only one that tightens the spacing rather than loosening
161
+ it — so it fits more rows on a screen, which is what a board somebody watches
162
+ wants. Pick one by putting it on the theme's `form`; leaving it out draws the
163
+ board the way it did before forms existed.
164
+
142
165
  ## When the panel behaves oddly for no visible reason
143
166
 
144
167
  The gate — `middleware.ts`, `lib/session.ts`, `api/*.ts` — was copied into this