You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/docs/audit/theming/range-calendar.md

226 lines
22 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# range-calendar — alcance de tema: análisis y propuesta
> Generado por `node --import tsx/esm scripts/theming-census.ts --report`.
> Lo **medido** y la **propuesta** se regeneran; el **Veredicto** (§5) se conserva.
> Vista de conjunto: [README](./README.md) · método y protocolo:
> [`PLAN-theming.md`](../../process/PLAN-theming.md) §1, §2, §7.
- **Medido**: 2026-08-24 · **Alcance**: **0%** — 0 de 13 knobs por token público
- **Knobs de apariencia**: 98 — público 0 · privado 7 · global 2 · literal 4 · sistema 85 · excepción 0 _(los dos últimos, fuera del ratio)_
- **Contrato hoy** (`lib/recipes/base.ts`): 0 pública(s) · 5 privada(s) forward — `_palette-solid`, `_palette-solid-hover`, `_palette-track`, `_palette-border`, `_palette-text`
- **Eje `size`**: no · **ficheros**: `range-calendar.css`
## 1. Knobs fuera de alcance
### 1.1 Directo a primitivo global (2)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `range-calendar.css:269` | `[data-range-calendar-day][data-range-start]` | `font-weight` | `var(--font-weight-semibold)` |
| 2 | `range-calendar.css:278` | `[data-range-calendar-day][data-range-end]` | `font-weight` | `var(--font-weight-semibold)` |
### 1.2 A través de un privado (7)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `range-calendar.css:224` | `[data-range-calendar-cell][data-in-range], [data-range-calendar-cell][data-in-preview-range]` | `background` | `var(--_range-calendar-palette-track)` |
| 2 | `range-calendar.css:317` | `[data-range-calendar-day][data-in-range]:not([data-selected])` | `color` | `var(--_range-calendar-palette-text)` |
| 3 | `range-calendar.css:323` | `[data-range-calendar-day][data-preview-start], [data-range-calendar-day][data-preview-end], [data-range-calendar-day][data-in-preview-range]:not([data-selected])` | `border-color` | `var(--_range-calendar-palette-border)` |
| 4 | `range-calendar.css:325` | `[data-range-calendar-day][data-preview-start], [data-range-calendar-day][data-preview-end], [data-range-calendar-day][data-in-preview-range]:not([data-selected])` | `color` | `var(--_range-calendar-palette-text)` |
| 5 | `range-calendar.css:329` | `[data-range-calendar-day][data-focused]:not([data-selected])` | `border-color` | `var(--_range-calendar-palette-border)` |
| 6 | `range-calendar.css:330` | `[data-range-calendar-day][data-focused]:not([data-selected])` | `background` | `var(--_range-calendar-palette-track)` |
| 7 | `range-calendar.css:331` | `[data-range-calendar-day][data-focused]:not([data-selected])` | `color` | `var(--_range-calendar-palette-text)` |
### 1.3 Literales (4)
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `range-calendar.css:51` | `[data-range-calendar]` | `inline-size` | `max-content` |
| 2 | `range-calendar.css:95` | `[data-range-calendar-header]` | `inline-size` | `100%` |
| 3 | `range-calendar.css:182` | `[data-range-calendar-month-panel]` | `min-inline-size` | `max-content` |
| 4 | `range-calendar.css:187` | `[data-range-calendar-grid]` | `inline-size` | `max-content` |
### 1.4 Excepciones firmadas (0) — fuera del ratio
Literales que llevan su anotación `/* literal: <razón> */` en la propia
declaración: la válvula de recipe-contract §3, la misma que honra
`component-audit`. **Una desviación firmada no es deuda** — se listan para que la
razón se lea, no para acuñarlas.
_Ninguno._
## 2. Sistema transversal (85) — informativo, fuera del ratio
Un tema los alcanza **a nivel de sistema**, por diseño (recipe-contract §2).
| # | fichero:línea | selector | propiedad | valor |
| ---: | --- | --- | --- | --- |
| 1 | `range-calendar.css:50` | `[data-range-calendar]` | `gap` | `var(--calendar-gap)` ⤴ prestado de `calendar` |
| 2 | `range-calendar.css:53` | `[data-range-calendar]` | `padding` | `var(--calendar-padding)` |
| 3 | `range-calendar.css:54` | `[data-range-calendar]` | `border` | `var(--calendar-border-width) solid var(--calendar-border)` ⤴ prestado de `calendar` |
| 4 | `range-calendar.css:55` | `[data-range-calendar]` | `border-radius` | `var(--calendar-radius)` ⤴ prestado de `calendar` |
| 5 | `range-calendar.css:56` | `[data-range-calendar]` | `background` | `var(--calendar-bg)` ⤴ prestado de `calendar` |
| 6 | `range-calendar.css:57` | `[data-range-calendar]` | `box-shadow` | `var(--calendar-shadow)` ⤴ prestado de `calendar` |
| 7 | `range-calendar.css:58` | `[data-range-calendar]` | `color` | `var(--calendar-fg)` ⤴ prestado de `calendar` |
| 8 | `range-calendar.css:59` | `[data-range-calendar]` | `font-family` | `var(--calendar-font-family)` ⤴ prestado de `calendar` |
| 9 | `range-calendar.css:60` | `[data-range-calendar]` | `font-size` | `var(--calendar-font-size)` |
| 10 | `range-calendar.css:61` | `[data-range-calendar]` | `line-height` | `var(--calendar-line-height)` ⤴ prestado de `calendar` |
| 11 | `range-calendar.css:65` | `[data-range-calendar][data-variant='outline']` | `background` | `var(--calendar-outline-bg)` ⤴ prestado de `calendar` |
| 12 | `range-calendar.css:66` | `[data-range-calendar][data-variant='outline']` | `box-shadow` | `var(--calendar-outline-shadow)` ⤴ prestado de `calendar` |
| 13 | `range-calendar.css:94` | `[data-range-calendar-header]` | `gap` | `var(--calendar-header-gap)` ⤴ prestado de `calendar` |
| 14 | `range-calendar.css:103` | `[data-range-calendar-header-controls]` | `gap` | `var(--calendar-header-gap)` ⤴ prestado de `calendar` |
| 15 | `range-calendar.css:110` | `[data-range-calendar-heading]` | `color` | `var(--calendar-heading-fg)` ⤴ prestado de `calendar` |
| 16 | `range-calendar.css:111` | `[data-range-calendar-heading]` | `font-weight` | `var(--calendar-heading-font-weight)` ⤴ prestado de `calendar` |
| 17 | `range-calendar.css:121` | `[data-range-calendar-day]:focus-visible` | `outline` | `var(--focus-ring-width) solid var(--focus-ring-color)` |
| 18 | `range-calendar.css:128` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `block-size` | `var(--calendar-control-size)` |
| 19 | `range-calendar.css:129` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `padding-inline` | `var(--calendar-select-padding-inline)` ⤴ prestado de `calendar` |
| 20 | `range-calendar.css:130` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `border` | `var(--calendar-control-border-width) solid var(--calendar-control-border)` ⤴ prestado de `calendar` |
| 21 | `range-calendar.css:131` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `border-radius` | `var(--calendar-control-radius)` ⤴ prestado de `calendar` |
| 22 | `range-calendar.css:132` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `background` | `var(--calendar-control-bg)` ⤴ prestado de `calendar` |
| 23 | `range-calendar.css:133` | `[data-range-calendar-month-select], [data-range-calendar-year-select]` | `color` | `var(--calendar-control-fg)` ⤴ prestado de `calendar` |
| 24 | `range-calendar.css:144` | `[data-range-calendar-month-select]` | `min-inline-size` | `var(--calendar-select-min-width)` ⤴ prestado de `calendar` |
| 25 | `range-calendar.css:145` | `[data-range-calendar-month-select]` | `inline-size` | `calc(var(--calendar-day-size) * 2.35)` |
| 26 | `range-calendar.css:149` | `[data-range-calendar-year-select]` | `min-inline-size` | `var(--calendar-select-min-width)` ⤴ prestado de `calendar` |
| 27 | `range-calendar.css:150` | `[data-range-calendar-year-select]` | `inline-size` | `calc(var(--calendar-day-size) * 2.15)` |
| 28 | `range-calendar.css:155` | `[data-range-calendar-month-select]:hover, [data-range-calendar-year-select]:hover` | `border-color` | `var(--calendar-hover-control-border)` ⤴ prestado de `calendar` |
| 29 | `range-calendar.css:156` | `[data-range-calendar-month-select]:hover, [data-range-calendar-year-select]:hover` | `background-image` | `linear-gradient(var(--state-hover), var(--state-hover))` |
| 30 | `range-calendar.css:157` | `[data-range-calendar-month-select]:hover, [data-range-calendar-year-select]:hover` | `color` | `var(--calendar-hover-control-fg)` ⤴ prestado de `calendar` |
| 31 | `range-calendar.css:170` | `[data-range-calendar-months]` | `gap` | `var(--calendar-months-gap)` ⤴ prestado de `calendar` |
| 32 | `range-calendar.css:181` | `[data-range-calendar-month-panel]` | `gap` | `var(--calendar-grid-gap)` ⤴ prestado de `calendar` |
| 33 | `range-calendar.css:196` | `[data-range-calendar-head-cell]` | `inline-size` | `var(--calendar-day-size)` |
| 34 | `range-calendar.css:197` | `[data-range-calendar-head-cell]` | `block-size` | `var(--calendar-weekday-size)` ⤴ prestado de `calendar` |
| 35 | `range-calendar.css:198` | `[data-range-calendar-head-cell]` | `color` | `var(--calendar-weekday-fg)` ⤴ prestado de `calendar` |
| 36 | `range-calendar.css:199` | `[data-range-calendar-head-cell]` | `font-size` | `var(--calendar-weekday-font-size)` ⤴ prestado de `calendar` |
| 37 | `range-calendar.css:200` | `[data-range-calendar-head-cell]` | `font-weight` | `var(--calendar-weekday-font-weight)` ⤴ prestado de `calendar` |
| 38 | `range-calendar.css:205` | `[data-range-calendar-week-number]` | `color` | `var(--calendar-weekday-fg)` ⤴ prestado de `calendar` |
| 39 | `range-calendar.css:210` | `[data-range-calendar-week-number][scope='row']` | `block-size` | `var(--calendar-day-size)` |
| 40 | `range-calendar.css:211` | `[data-range-calendar-week-number][scope='row']` | `font-size` | `var(--calendar-weekday-font-size)` ⤴ prestado de `calendar` |
| 41 | `range-calendar.css:212` | `[data-range-calendar-week-number][scope='row']` | `font-weight` | `var(--calendar-weekday-font-weight)` ⤴ prestado de `calendar` |
| 42 | `range-calendar.css:217` | `[data-range-calendar-cell]` | `border-radius` | `var(--calendar-day-radius)` ⤴ prestado de `calendar` |
| 43 | `range-calendar.css:232` | `[data-range-calendar-day]` | `inline-size` | `var(--calendar-day-size)` |
| 44 | `range-calendar.css:233` | `[data-range-calendar-day]` | `block-size` | `var(--calendar-day-size)` |
| 45 | `range-calendar.css:234` | `[data-range-calendar-day]` | `border` | `var(--calendar-day-border-width) solid var(--calendar-day-border)` ⤴ prestado de `calendar` |
| 46 | `range-calendar.css:235` | `[data-range-calendar-day]` | `border-radius` | `var(--calendar-day-radius)` ⤴ prestado de `calendar` |
| 47 | `range-calendar.css:236` | `[data-range-calendar-day]` | `background` | `var(--calendar-day-bg)` ⤴ prestado de `calendar` |
| 48 | `range-calendar.css:237` | `[data-range-calendar-day]` | `color` | `var(--calendar-day-fg)` ⤴ prestado de `calendar` |
| 49 | `range-calendar.css:239` | `[data-range-calendar-day]` | `font-weight` | `var(--calendar-day-font-weight)` ⤴ prestado de `calendar` |
| 50 | `range-calendar.css:251` | `[data-range-calendar-day]:hover` | `border-color` | `var(--calendar-hover-day-border)` ⤴ prestado de `calendar` |
| 51 | `range-calendar.css:252` | `[data-range-calendar-day]:hover` | `background-image` | `linear-gradient(var(--state-hover), var(--state-hover))` |
| 52 | `range-calendar.css:253` | `[data-range-calendar-day]:hover` | `color` | `var(--calendar-hover-day-fg)` ⤴ prestado de `calendar` |
| 53 | `range-calendar.css:257` | `[data-range-calendar-day][data-selected]` | `border-color` | `var(--calendar-range-end-border)` ⤴ prestado de `calendar` |
| 54 | `range-calendar.css:258` | `[data-range-calendar-day][data-selected]` | `background` | `var(--calendar-range-end-solid)` ⤴ prestado de `calendar` |
| 55 | `range-calendar.css:259` | `[data-range-calendar-day][data-selected]` | `color` | `var(--calendar-day-selected-fg)` ⤴ prestado de `calendar` |
| 56 | `range-calendar.css:265` | `[data-range-calendar-day][data-range-start]` | `border-color` | `var(--calendar-range-start-border)` ⤴ prestado de `calendar` |
| 57 | `range-calendar.css:266` | `[data-range-calendar-day][data-range-start]` | `background` | `var(--calendar-range-start-solid)` ⤴ prestado de `calendar` |
| 58 | `range-calendar.css:267` | `[data-range-calendar-day][data-range-start]` | `color` | `var(--calendar-range-start-text)` ⤴ prestado de `calendar` |
| 59 | `range-calendar.css:268` | `[data-range-calendar-day][data-range-start]` | `box-shadow` | `inset 2px 0 0 0 var(--calendar-range-start-border)` ⤴ prestado de `calendar` |
| 60 | `range-calendar.css:274` | `[data-range-calendar-day][data-range-end]` | `border-color` | `var(--calendar-range-end-border)` ⤴ prestado de `calendar` |
| 61 | `range-calendar.css:275` | `[data-range-calendar-day][data-range-end]` | `background` | `var(--calendar-range-end-solid)` ⤴ prestado de `calendar` |
| 62 | `range-calendar.css:276` | `[data-range-calendar-day][data-range-end]` | `color` | `var(--calendar-range-end-text)` ⤴ prestado de `calendar` |
| 63 | `range-calendar.css:277` | `[data-range-calendar-day][data-range-end]` | `box-shadow` | `inset -2px 0 0 0 var(--calendar-range-end-border)` ⤴ prestado de `calendar` |
| 64 | `range-calendar.css:282` | `[data-range-calendar-day][data-range-start][data-range-end]` | `border-color` | `var(--calendar-range-end-border)` ⤴ prestado de `calendar` |
| 65 | `range-calendar.css:283` | `[data-range-calendar-day][data-range-start][data-range-end]` | `background` | `linear-gradient( 135deg, var(--calendar-range-start-solid) 0 50%, var(--calendar-range-end-solid) 50% 100% )` ⤴ prestado de `calendar` |
| 66 | `range-calendar.css:288` | `[data-range-calendar-day][data-range-start][data-range-end]` | `color` | `var(--calendar-day-selected-fg)` ⤴ prestado de `calendar` |
| 67 | `range-calendar.css:292` | `[data-range-calendar-day][data-selected]:hover` | `border-color` | `var(--calendar-range-end-solid-hover)` ⤴ prestado de `calendar` |
| 68 | `range-calendar.css:293` | `[data-range-calendar-day][data-selected]:hover` | `background` | `var(--calendar-range-end-solid-hover)` ⤴ prestado de `calendar` |
| 69 | `range-calendar.css:297` | `[data-range-calendar-day][data-range-start]:hover` | `border-color` | `var(--calendar-range-start-solid-hover)` ⤴ prestado de `calendar` |
| 70 | `range-calendar.css:298` | `[data-range-calendar-day][data-range-start]:hover` | `background` | `var(--calendar-range-start-solid-hover)` ⤴ prestado de `calendar` |
| 71 | `range-calendar.css:302` | `[data-range-calendar-day][data-range-end]:hover` | `border-color` | `var(--calendar-range-end-solid-hover)` ⤴ prestado de `calendar` |
| 72 | `range-calendar.css:303` | `[data-range-calendar-day][data-range-end]:hover` | `background` | `var(--calendar-range-end-solid-hover)` ⤴ prestado de `calendar` |
| 73 | `range-calendar.css:307` | `[data-range-calendar-day][data-range-start][data-range-end]:hover` | `background` | `linear-gradient( 135deg, var(--calendar-range-start-solid-hover) 0 50%, var(--calendar-range-end-solid-hover) 50% 100% )` ⤴ prestado de `calendar` |
| 74 | `range-calendar.css:335` | `[data-range-calendar-day][data-today]:not([data-selected])` | `border-color` | `var(--calendar-day-today-border)` ⤴ prestado de `calendar` |
| 75 | `range-calendar.css:336` | `[data-range-calendar-day][data-today]:not([data-selected])` | `color` | `var(--calendar-day-today-fg)` ⤴ prestado de `calendar` |
| 76 | `range-calendar.css:337` | `[data-range-calendar-day][data-today]:not([data-selected])` | `font-weight` | `var(--calendar-day-today-font-weight)` ⤴ prestado de `calendar` |
| 77 | `range-calendar.css:341` | `[data-range-calendar-day][data-outside-month]` | `color` | `var(--calendar-day-outside-fg)` ⤴ prestado de `calendar` |
| 78 | `range-calendar.css:342` | `[data-range-calendar-day][data-outside-month]` | `opacity` | `var(--calendar-day-outside-opacity)` ⤴ prestado de `calendar` |
| 79 | `range-calendar.css:346` | `[data-range-calendar-day][data-weekend]:not([data-selected])` | `color` | `var(--calendar-day-weekend-fg)` ⤴ prestado de `calendar` |
| 80 | `range-calendar.css:350` | `[data-range-calendar-day][data-holiday]:not([data-selected])` | `box-shadow` | `var(--calendar-day-holiday-shadow)` |
| 81 | `range-calendar.css:355` | `[data-range-calendar-day][data-unavailable]` | `text-decoration-color` | `var(--calendar-day-unavailable-decoration)` ⤴ prestado de `calendar` |
| 82 | `range-calendar.css:361` | `[data-range-calendar-day][data-disabled], [data-range-calendar-day][data-unavailable]` | `opacity` | `var(--calendar-disabled-opacity)` ⤴ prestado de `calendar` |
| 83 | `range-calendar.css:365` | `[data-range-calendar][data-invalid]` | `border-color` | `var(--calendar-invalid-border)` ⤴ prestado de `calendar` |
| 84 | `range-calendar.css:369` | `[data-range-calendar][data-disabled]` | `opacity` | `var(--calendar-disabled-opacity)` ⤴ prestado de `calendar` |
| 85 | `range-calendar.css:385` | `[data-range-calendar-day][data-event], [data-range-calendar-prev-button][data-event], [data-range-calendar-next-button][data-event], [data-range-calendar-month-select][data-event], [data-range-calendar-year-select][data-event]` | `box-shadow` | `var(--calendar-event-shadow)` |
## 3. Privados de la receta — ¿de dónde sale su valor?
_La receta no declara privados propios en su CSS._
Consumidos y **no declarados en el CSS** (vienen de `base.ts` o de un estilo inline del wrapper): `--_range-calendar-palette-border`, `--_range-calendar-palette-solid`, `--_range-calendar-palette-solid-hover`, `--_range-calendar-palette-text`, `--_range-calendar-palette-track`.
## 4. Propuesta de corrección
- **Consume la capa compartida `calendar-surface`.** Un eje que la capa posee se consume como `var(--_x, var(--x))`; el consumidor **no acuña** `--range-calendar-{eje}` para él — sería un vocabulario paralelo (README de `eidos/components`, «Capas compartidas» regla 2).
- **Consume tokens públicos de `calendar`.** Un token prestado importa la semántica de su dueño: la corrección no es duplicarlo con prefijo propio, sino la decisión de familia que la auditoría de fase 1 dejó registrada (`theming-audit.md` §B, familia calendar).
### 4.1 Tokens a declarar en `lib/recipes/base.ts` (4)
Valor **verbatim** del CSS de hoy: el default no se mueve, sólo cambia quién
puede moverlo. Nombres derivados de recipe-contract §1 (ejes lógicos, talla
al final) y theming §6.7 (slots de color, modificador delante). Un token con
DOS valores distintos es una colisión de nombre: son dos knobs, o el nombre
no distingue lo que debería — se marca `⚠`.
| token (`--range-calendar-…`) | scope TSC | valor propuesto | usos |
| --- | --- | --- | ---: |
| `day-font-weight` | `root` | `var(--font-weight-semibold)` | 2 |
| `width` | `root` | `max-content` | 1 |
| `month-panel-width` | `root` | `max-content` | 1 |
| `grid-width` | `root` | `max-content` | 1 |
### 4.2 Sin nombre mecánico (8)
- **⚠ decisión: `100%` es un valor identidad o geometría de layout, no un knob de tema — el perímetro de «knob» es D-TH.2, sin firmar** — 1: `inline-size`.
- **⚠ decisión: el privado que alimenta este knob no se declara en el CSS (viene de `base.ts` o de un estilo inline) — hay que resolverlo antes de nombrarlo** — 7: `background`, `color`, `border-color`.
### 4.4 Lo que hay que comprobar a mano (PLAN-theming §1.3 · §7.4)
- [ ] **Privado que no deriva de un público** — §3 lo marca; el privado debe leer el público o desaparecer.
- [ ] **Velo o acento en el nodo equivocado** (`archetype: 'item'` en un envoltorio, un `background` en shorthand que mata la capa de estado) — se mide desde el píxel hacia arriba.
- [ ] **Doble animación** al mover un sello a una superficie con animación propia — registro de `animationstart`/`animationend`.
- [ ] **Diff de computed = 0** en reposo · hover · abierto · disabled · foco, por talla, antes y después.
- [ ] **Centinela por token nuevo**: valor imposible en el root → el nodo lo sigue. Si no, el token miente.
## 5. Veredicto
<!-- veredicto:start -->
**Revisión 2026-08-20 — verificación previa a implementación (Opus).**
**Análisis (§1–§3): CORRECTO.** Cifras reproducidas con `--only range-calendar`
(98 · 0 · 7 · 84 · 4 · 3); filas muestreadas contra el CSS (`:51` gap, `:54`
padding vía privado ajeno, `:55` border shorthand) — coinciden, y las marcas
«⤴ prestado de `calendar`» son reales: la receta consume ~80 tokens públicos
de `calendar` y hasta privados suyos (`--_calendar-day-size`,
`--_calendar-font-size`, `--_calendar-padding`), y a la inversa PISA públicos
de calendar con privados propios (`range-calendar.css:30`:
`--calendar-range-end-solid: var(--_range-calendar-palette-solid)`).
**Propuesta (§4.1): NO IMPLEMENTAR.** Dos defectos verificados:
1. **Acuña 59 alias de `--calendar-*`** — exactamente lo que la nota de §4
prohíbe («no duplicarlo con prefijo propio») y lo que la purga de alias
mató en §39 del changelog («no quiero alias»). Un tema que moviera
`--range-calendar-day-bg` = `var(--calendar-day-bg)` no ganaría nada: el
knob real seguiría siendo del calendar.
2. **Los nombres colisionan porque el lector de estados no conoce los del
día**: `day-fg` con 7 valores mezcla `data-range-start`, `data-range-end`,
`data-today`, `data-outside`, `data-weekend`, `data-selected` — estados de
la familia calendar que la derivación genérica no parsea. Además
`font-size`/`day-width`/`day-height` proponen valores sobre privados
AJENOS (`--_calendar-*`): un token `root` que referencia un privado es la
clase eager-freeze que G1 existe para impedir.
**Disposición**: este componente NO se tokeniza en solitario. Su corrección es
la **decisión de familia calendar** registrada en `theming-audit.md` §B
(«la familia calendar se formaliza como capa compartida/arquetipo»; los
préstamos medidos: range-calendar 79 · month/year-grid 65 · drp 38) — una capa
`calendar-surface` con contrato propio que los cinco consumidores lean, con la
misma regla que las demás capas compartidas (`var(--_x, var(--x))`, el
consumidor no acuña). Orden: va en el bloque B7 de F2 (D-TH.4), DESPUÉS de esa
decisión. Lo único accionable aquí y ahora si el autor lo firma: partir los 3
`border` shorthand en ejes lógicos y anotar los 4 literales.
**Bloqueos de firma**: decisión de familia calendar (sin firmar) · D-TH.4
(orden) · D-TH.2 (los `max-content`/`100%` de layout quedan fuera del knob).
<!-- veredicto:end -->

Powered by TurnKey Linux.