/* DUAT · estils de les pàgines de mòdul amb dades reals (KPIs + taules).
   Auto-carregat per Dash des de /assets. Usa les variables --pt-* del tema. */

/* Fila de KPIs */
.pt-kpi-row { display:flex; flex-wrap:wrap; gap:14px; margin:18px 0 26px;
  overscroll-behavior-x: contain; }   /* veure «El lliscament d'un carril» */
.pt-kpi { flex:1 1 160px; background:var(--pt-surface); border:1px solid var(--pt-line);
  border-top:3px solid var(--pt-verd); border-radius:var(--pt-radius); padding:14px 16px; }
.pt-kpi-label { color:var(--pt-muted); font-size:.85rem; margin:0 0 4px; }
.pt-kpi-val { color:var(--pt-text); font-size:1.5rem; font-weight:600; line-height:1.1; }
.pt-kpi-sub { color:var(--pt-muted); font-size:.82rem; margin-top:3px; }
.pt-kpi.warn { border-top-color:var(--pt-warn); }
.pt-kpi.warn .pt-kpi-val { color:var(--pt-warn-dark); }
.pt-kpi.ok   { border-top-color:var(--pt-verd); }
.pt-kpi.gold { border-top-color:var(--pt-blau); }

/* Blocs de secció */
.pt-sec { background:var(--pt-surface); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); padding:18px 20px; margin-bottom:22px; }
.pt-sec h3 { color:var(--pt-text); font-size:1.05rem; font-weight:600;
  margin:0 0 4px; }
.pt-sec-sub { color:var(--pt-muted); font-size:.875rem; margin:0 0 14px; line-height:1.5; }

/* Taules */
.pt-table { width:100%; border-collapse:collapse; font-size:.86rem; }
.pt-table th { text-align:left; color:var(--pt-muted); font-weight:600;
  border-bottom:2px solid var(--pt-line); padding:9px 10px; white-space:nowrap; }
.pt-table td { border-bottom:1px solid var(--pt-line); padding:7px 10px;
  color:var(--pt-text); }
.pt-table td.num { text-align:right; font-variant-numeric:tabular-nums; }
.pt-table tr:hover td, .pt-table tbody tr:hover td { background:var(--pt-soft); }

/* «La fila és l'acció» (mb.table fila_extra, /gasoil 20-09-2026): un <tr>
   role="button" es comporta com l'enllaç del seu nom, però en TOTA la fila.
   El clic el porta `keys.js`; aquí només l'afordança visual i el focus. */
.pt-table tr[role="button"] { cursor:pointer; }
.pt-table tr[role="button"]:hover td { background:var(--pt-verd-pastel); }
.pt-table tr[role="button"]:focus-visible { outline:2px solid var(--pt-verd);
  outline-offset:-2px; }

/* Qualsevol altra ACCIÓ del mateix patró («la fila és l'acció») que no és
   una fila de taula — p. ex. el bloc «El que NO s'atribueix» de /gasoil,
   que porta a /casaments. */
.pt-fila-accio[role="button"] { cursor:pointer; }
.pt-fila-accio[role="button"]:focus-visible { outline:2px solid var(--pt-verd);
  outline-offset:2px; border-radius:var(--pt-radius); }

/* La icona de l'afordança (IDUN, cp2c 22-09-2026): «cursor:pointer» i
   l'outline de focus de dalt només es veuen passant-hi per sobre o
   tabulant-hi; sense senyal permanent, ningú sap que la fila/targeta
   respon. `.pt-fila-accio-icona` la posa `_modbase.py::table()` a l'última
   cel·la NOMÉS quan `fila_extra` ha tornat un `role="button"` real. */
.pt-fila-accio-icona { color:var(--pt-muted); font-weight:400; }

/* La targeta de decisió (01-08) NO és una fila de taula: `::after` de CSS,
   escopat a `pt-decisio-card` perquè el link «Casar-los a /casaments →»
   (també `pt-fila-accio`) ja porta la seva pròpia fletxa escrita i no en
   necessita una segona. */
.pt-decisio-card.pt-fila-accio[role="button"]::after {
  content:"↗"; color:var(--pt-muted); margin-left:auto; align-self:flex-start;
  font-size:.9rem;
}

/* Secció plegable (mb.section_plegable, /gasoil 20-09-2026): el disparador
   és `role="button"` i ha de semblar-ho — un `<summary>` sense estil es llegeix
   com un títol mut. 44px d'alçada mínima: objectiu tàctil de la casa. */
.pt-plec > summary.pt-plec-sum { list-style:none; cursor:pointer;
  min-height:44px; display:flex; align-items:center; font-weight:600;
  color:var(--pt-text); touch-action:manipulation; }
.pt-plec > summary.pt-plec-sum::-webkit-details-marker { display:none; }
/* El TRIANGLE DE VORES de la casa (`.ses-parc-summary::before`), no un
   caràcter de text: un «▸» es pinta amb la tipografia del sistema i no fa
   la mateixa mida ni el mateix gris a dues màquines (agent-santi, 19-09). */
.pt-plec > summary.pt-plec-sum::before { content:""; display:inline-block;
  width:0; height:0; flex-shrink:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:4px solid var(--pt-muted); margin-right:8px;
  transition:transform .15s ease; }
.pt-plec[open] > summary.pt-plec-sum::before { transform:rotate(90deg); }
/* I AQUÍ s'ha d'amagar EXPLÍCITAMENT (mateix motiu que `.ses-categoria-plec`,
   línia ~933): un `<details>` tancat hauria d'amagar els fills amb el full
   del navegador, però mesurat amb Playwright/Chromium el 20-09-2026 no ho
   fa NI AMB UN `<details>` completament nu, sense cap CSS d'autor — no és
   nomes que «qualsevol display: d'autor hi guanya», aquí sembla que la
   regla nativa no s'aplica. No es pot confiar en el full del navegador:
   s'escriu la regla, com ja fa `.ses-categoria-plec`. */
/* `.pt-sec-sub` en queda FORA de la regla... I NO N'HI HA PROU.
   ⚠️ AQUEST COMENTARI DEIA QUE L'AVÍS ES VEU AMB LA SECCIÓ TANCADA I ÉS FALS.
   Mesurat al banc el 21-09-2026 sobre `/gasoil`: dels 7 plecs tancats amb
   `sub`, **es veuen 0**. `innerText` torna buit mentre `textContent` té la
   frase sencera — el navegador amaga el contingut d'un `<details>` tancat a
   nivell d'AGENT D'USUARI, i excloure una classe de la regla d'autor no el
   desamaga. Provat i descartat sobre la pàgina viva:
     · `display:block` (el que fa aquesta regla)  → 0 de 7
     · `content-visibility:visible`               → 0 de 7
   Entre els set invisibles hi havia «⚠️ Cal demanar: Gasóleo A» i
   «2.268.235 L (59,7 %) encara no arriben a cap fitxa».

   **No posis un avís que ha de veure's dins del `sub` d'un plec que neix
   tancat.** O la secció neix oberta, o l'avís va al títol del `<summary>`,
   que sí que es pinta sempre. L'arreglament de debò és estructural (moure el
   `sub` DINS del `<summary>`) i toca `section_plegable`, que fan servir totes
   les pantalles: va al backlog, no s'improvisa. Guió de mesura:
   `enfoca-sala/.../entrades/prova_subtitol_plec.py`. */
.pt-plec:not([open]) > *:not(summary):not(.pt-sec-sub) { display:none; }
.pt-plec > summary.pt-plec-sum:focus-visible { outline:2px solid var(--pt-verd);
  outline-offset:2px; border-radius:var(--pt-radius); }
/* Una secció TANCADA és, de fet, una línia: el `sub` és tota la seva
   informació visible. El seu propi marge inferior (14px, de `.pt-sec-sub`
   general) i el marge entre seccions (22px, de `.pt-sec`) sumaven un buit
   pensat per a una CAIXA amb taula a dins, no per a una línia — objectiu de
   finestres de /gasoil, 20-09-2026, porta CONTROL: en obrir «El cost del
   gasoil» per defecte calia recuperar espai en algun lloc, i cap taula
   desapareix per això. Oberta, la secció torna als marges normals. */
.pt-plec:not([open]) { margin-bottom:2px; }
.pt-plec:not([open]) > .pt-sec-sub { margin-bottom:0; }

/* Semàfor de risc (colors amb contrast >=3:1 sobre surface/soft/bg) */
.pt-dot { display:inline-block; width:9px; height:9px; border-radius:50%;
  margin-right:6px; vertical-align:middle; }
.pt-dot.r { background:var(--pt-warn); } .pt-dot.a { background:var(--pt-ambre-fosc); }
.pt-dot.g { background:var(--pt-verd); }
.pt-dot.n { background:var(--pt-muted); }   /* neutre: sense font de seguiment */

/* Panell de casaments (formularis de vincle) */
.pt-cas-form { display:flex; flex-wrap:wrap; gap:12px; align-items:flex-end; }
.pt-cas-col { flex:1 1 260px; min-width:220px; }
.pt-cas-form .pt-btn { flex:0 0 auto; height:38px; }
.pt-cas-fb { margin-top:10px; }
.pt-cas-ok { display:inline-block; background:var(--pt-verd-pastel);
  color:var(--pt-verd-dark); border:1px solid var(--pt-verd); border-radius:var(--pt-radius-sm);
  padding:8px 12px; font-weight:500; }
.pt-cas-err { display:inline-block; background:var(--pt-blau-pastel);
  color:var(--pt-warn-dark); border:1px solid var(--pt-warn); border-radius:var(--pt-radius-sm);
  padding:8px 12px; font-weight:500; }
.pt-cas-mgmt-link { display:inline-block; margin:4px 0 8px; color:var(--pt-verd);
  font-weight:500; text-decoration:none; }
.pt-cas-mgmt-link:hover { text-decoration:underline; color:var(--pt-verd-dark); }

/* Nota de qualitat de dada / peu.
   DUES classes, UN sol aspecte, i el mateix bloc a posta: es diferencien pel
   SIGNIFICAT, no per com es veuen. Partir-les en dues regles convidava que una
   es quedes sense `max-width:78ch` i el peu honest —que es una frase llarga—
   s'estires de banda a banda sense que cap prova ho veies. */
.pt-datanote, .pt-procedencia {
  color:var(--pt-muted); font-size:.875rem; margin-top:6px;
  font-style:italic; line-height:1.5; max-width:78ch; }

/* Un gràfic i la nota que diu de quin període parla, com una sola peça.
   `mb.figura()` va néixer sense el seu full i la classe no era definida
   enlloc: el gràfic i el seu període quedaven com dos blocs solts amb el
   marge de sota del `dcc.Graph` entremig. Ho va caçar el guard de classes
   inventades. El marge de sota és el mateix que separa dos blocs d'una
   secció; el de dins, zero, perquè la nota pertany al dibuix. */
.pt-figura { margin:0 0 14px; }
.pt-figura .pt-procedencia { margin-top:2px; }
/* `pt-procedencia` = que NO es aquesta xifra. Hi viuen el periode de cada
   grafic, el peu que diu que la taula esta retallada (amb l'unic enllaç cap a
   la resta) i l'avis de que la dada no es d'avui. Mai s'amaga: si s'amaga, el
   numero menteix mentre no es veu. `pt-datanote` es queda per a la prosa de
   com s'ha de llegir, que si que es pot amagar. */

/* Enllaç de retorn a l'inici (capçalera de tots els mòduls) */
.pt-back-link { display:inline-block; color:var(--pt-verd); text-decoration:none;
  font-size:.85rem; font-weight:500; margin-bottom:10px; }
.pt-back-link:hover { text-decoration:underline; color:var(--pt-verd-dark); }

/* ══════════════════════════════════════════════════════════════════════════
   SISTEMA DE DISSENY (línia MIDGARD) — profunditat, radius i jerarquia.
   Aquest fitxer es carrega DESPRÉS del _THEME_CSS injectat a app.py, així que
   a igual especificitat aquestes regles manen.
   ══════════════════════════════════════════════════════════════════════════ */
:root {
  /* ── ELEVACIÓ: una escala de QUATRE nivells, i prou (PLA 17-09-2026, CP5).
     Inventari abans de crear-la: 28 `box-shadow` al fitxer, 12 valors
     diferents, 2 tokenitzats. L'efecte de flotar d'una cel·la havia de ser un
     nivell d'aquí, no la 29a ombra solta. Cada nivell vol dir UNA cosa:
       0 · pla: dins d'una superfície, res no flota
       1 · en repòs: una targeta/secció sobre el fons (bi-capa MIDGARD)
       2 · flota: sota el punter, o l'element obert que mana a la pantalla
       3 · agafat: s'està arrossegant (SortableJS `.sortable-drag`)
     Els anells de focus/selecció (`0 0 0 3px …`) NO són elevació: són
     `--pt-focus`. Ho vigila `tests/test_elevacio_tokens.py`. */
  --pt-elev-0: none;
  --pt-elev-1: 0 1px 2px rgba(38,36,32,0.04), 0 4px 16px rgba(38,36,32,0.06);
  --pt-elev-2: 0 2px 6px rgba(38,36,32,0.07), 0 12px 30px rgba(38,36,32,0.10);
  --pt-elev-3: 0 10px 28px rgba(28,26,23,0.30);
  /* Els dos noms vells són ÀLIES de l'escala (un sistema, no dos). */
  --pt-shadow:     var(--pt-elev-1);
  --pt-shadow-hov: var(--pt-elev-2);
  /* ── ESPAIAT: 4 · 8 · 12 · 16 · 24 (múltiples de 4, com el terra de 44px).
     Fins al 17-09 no n'hi havia cap token i els espais de la graella estaven
     escrits a mà. Regla de densitat a DESIGN.md («Densitat i graella»). */
  --pt-space-1:  4px;
  --pt-space-2:  8px;
  --pt-space-3: 12px;
  --pt-space-4: 16px;
  --pt-space-5: 24px;
  /* Dos nivells de radius (cards grans / elements inline), com MIDGARD */
  --pt-radius:    14px;
  --pt-radius-sm:  9px;
}

/* Profunditat: totes les superfícies-targeta floten sobre el fons */
.pt-kpi, .pt-sec, .pt-home-tile, .pt-home-card,
.pt-mod-card, .pt-form-card, .pt-login-card { box-shadow: var(--pt-shadow); }
.pt-home-tile:hover { box-shadow: var(--pt-shadow-hov); transform: translateY(-2px);
  border-left-color: var(--pt-verd-dark); }

/* Radius sistematitzat: 14px cards · 9px inline */
.pt-kpi, .pt-sec, .pt-home-card, .pt-login-card,
.pt-mod-card, .pt-form-card, .pt-home-tile { border-radius: var(--pt-radius); }
.pt-nav-link, .pt-role-badge, .pt-mod-soon { border-radius: var(--pt-radius-sm); }

/* KPI: contrast tipogràfic label petit en caps / valor gran (patró MIDGARD) */
.pt-kpi-label { font-size:.72rem; font-weight:600; text-transform:uppercase;
  letter-spacing:.6px; margin:0 0 6px; }
.pt-kpi-val { font-size:1.75rem; letter-spacing:-.5px; line-height:1.05; }

/* Capçalera de mòdul: ancoratge amb línia + filet verd (com .page-header) */
.pt-mod-head { padding-bottom:14px; margin-bottom:14px;
  border-bottom:1px solid var(--pt-line); position:relative; }
.pt-mod-head::after { content:""; position:absolute; left:0; bottom:-1px;
  width:44px; height:3px; background:var(--pt-verd); border-radius:3px; }
.pt-mod-title { font-size:1.4rem; letter-spacing:-.2px; line-height:1.2; }
.pt-mod-glyph { font-size:2rem; }

/* Nom del déu a les targetes de la home: to fosc (AA) i pes contingut */
.pt-home-tile-deu { color:var(--pt-verd-dark); font-weight:600; }

/* Taules: capçalera diferenciada + zebra (llegibilitat horitzontal) */
.pt-table th { background:var(--pt-soft); color:var(--pt-text); font-size:.78rem;
  text-transform:uppercase; letter-spacing:.5px; }
.pt-table tbody tr:nth-child(even) td { background:var(--pt-soft); }
.pt-table tr:hover td, .pt-table tbody tr:hover td { background:var(--pt-verd-pastel); }

/* Embolcall de taula: scroll horitzontal propi (el genera _modbase.table) */
.pt-table-wrap { overflow-x:auto; -webkit-overflow-scrolling:touch; }

/* Enllaç de mapa (KHEPRI): target de toc que omple la cel·la */
.pt-map-link { display:block; padding:10px 0; min-height:44px; line-height:24px;
  color:var(--pt-verd); font-weight:500; text-decoration:none; white-space:nowrap; }
.pt-map-link:hover { text-decoration:underline; color:var(--pt-verd-dark); }

/* Header (topbar + NAV) enganxat: la navegació no es perd en scroll llarg */
.pt-header { position:sticky; top:0; z-index:100; background:var(--pt-surface); }

/* El scroll s'atura PER SOTA de la capçalera enganxada.
   Defecte mesurat el 22-09-2026, i cap captura ni cap de les 3.955 proves el
   veia — només un GEST: pujant la gràfica «En quin mes puja el consum?» a dalt
   de tot (el gest de qui la vol clicar), la capçalera la tapava SENCERA (209 px
   sobre una gràfica de 200) i cada clic anava a `SPAN.pt-nav-label`. La
   interacció que el gerent havia demanat era inabastable just on la busques.
   No es toca la capçalera: els seus 209 px són backlog global de les dotze
   pantalles, amb la condició d'IDUN del 21-09 (209 → acostar-se a 58). Això
   només fa que el navegador s'aturi abans, i val per a tota la casa.
   Alçades mesurades al banc: 209 px a 1366 d'ample, 118 px a 390.
   `test_el_scroll_satura_per_sota_de_la_capcalera_enganxada` compara contra
   aquestes alçades, no contra la presència de la regla: si algú fa créixer la
   capçalera, cau. */
html { scroll-padding-top: 220px; }
@media (max-width:768px) { html { scroll-padding-top: 130px; } }

/* ══════════════════════════════════════════════════════════════════════════
   RESPONSIVE — breakpoints MIDGARD: 992 tauleta · 768 mòbil · 480 petit
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Tauleta (≤ 992px): graelles compactes ── */
@media (max-width: 992px) {
  .pt-kpi-row { gap:10px; }
  .pt-home-grid { grid-template-columns:repeat(2,1fr); }
  .pt-mod, .pt-home { max-width:100%; }
}

/* ── Mòbil (≤ 768px): topbar condensat + NAV amb scroll horitzontal ── */
@media (max-width: 768px) {
  .pt-topbar { padding:8px 14px; flex-wrap:wrap; gap:4px; }
  .pt-logo { height:24px; }
  .pt-hello-lead { display:none; }
  /* Terra de 44px al capçal (revisió de mòbil, 19-09-2026). Mesurat a 390px:
     «Banc gerent» feia 77×20 i «Sortir» 35×20 — els dos tocables de sortir de
     la sessió i d'identitat eren els més petits de tota la pantalla. El
     `display:inline-flex` + `align-items:center` fa que el `min-height`
     valgui de debò sobre un `<a>` en línia, que és el parany que la casa ja
     té escrit ([[mitja-regla-del-sistema-de-disseny]]): sobre un `<a>`
     inline el `min-height` no fa res. */
  .pt-hello-name { font-size:.82rem; display:inline-flex; align-items:center;
    min-height:44px; padding:0 4px; }
  .pt-role-badge { display:none; }
  .pt-logout { font-size:.82rem; display:inline-flex; align-items:center;
    min-height:44px; min-width:44px; justify-content:center; padding:0 8px; }

  /* NAV: una sola fila amb scroll (el retall a la dreta indica que hi ha més);
     els títols de grup s'amaguen i un filet vertical separa els grups. */
  .pt-nav { flex-wrap:nowrap; overflow-x:auto; -webkit-overflow-scrolling:touch;
    scrollbar-width:none; gap:6px; padding:8px 14px; align-items:center; }
  .pt-nav::-webkit-scrollbar { display:none; }
  .pt-nav-group { flex-direction:row; flex-shrink:0; gap:4px; align-items:center; }
  .pt-nav-group-title { display:none; }
  .pt-nav-group-links { flex-wrap:nowrap; gap:4px; }
  .pt-nav-group + .pt-nav-group::before { content:""; display:block; width:1px;
    height:20px; background:var(--pt-line); flex-shrink:0; margin-right:2px; }
  /* Touch target ≥44px (caps de producció amb guants) */
  .pt-nav-link { padding:10px 14px; font-size:.82rem; white-space:nowrap;
    flex-shrink:0; min-height:44px; }

  .pt-main { padding:18px 14px; }

  /* Al telèfon, el paràgraf d'entrada i la descripció del mòdul no es
     dibuixen. Qui obre una pàgina ja sap què fa: hi entra cada dia des de la
     barra de dalt. No es perden —segueixen al DOM i senceres al «?»—, però
     deixen de costar pantalla abans de la primera dada.

     Mesurat el 05-09-2026 a 390 px sobre /flota: `pt-mod-que-fa` (40 px) i
     `pt-mod-lead` (72 px) eren 112 dels 576 que hi havia per damunt de la
     taula de màquines. El barem de mòbil de la casa
     (`docs/baremoteca/tauler-kpis-mobil-grafana.png`) posa la primera dada a
     ~310.

     Es fa per a TOTS els mòduls i no només per a /flota a posta: la mateixa
     regla ja existia tres vegades escrita a mà per al quadre de planificació
     (`.ses-pagina`), i seguir afegint-ne una còpia per pàgina és com aquest
     full va arribar a tenir la mateixa classe definida dues vegades dins de
     la mateixa consulta de mitjans. */
  .pt-mod-lead { display:none; }
  .pt-mod-que-fa { display:none; }

  /* KPIs: 2 per fila en mòbil normal */
  .pt-kpi { flex:1 1 140px; padding:12px 14px; }
  .pt-kpi-val { font-size:1.3rem; }

  .pt-home-grid { grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:10px; }
  .pt-home-tile { padding:12px 14px; }
  .pt-home-tile-glyph { font-size:1.4rem; }

  .pt-sec { padding:14px 14px; }
  /* Taules: llisquen dins la targeta; columnes mai impossiblement estretes */
  .pt-table { min-width:480px; font-size:.82rem; }
  .pt-table th, .pt-table td { padding:8px 8px; }

  /* Formularis: targets còmodes */
  .pt-form-card { max-width:100%; padding:16px 14px; }
  .pt-btn { min-height:44px; font-size:1rem; }
  /* `min-width` també: feia 43×44 i el terra val per als DOS costats. */
  .pt-back-link { padding:10px 6px; min-height:44px; min-width:44px;
    line-height:24px; }

  /* «← Inici» AL COSTAT del títol, no en una fila per a ell sol. Ocupava 54 px
     dels 477 que hi havia per damunt de la primera dada de /flota (mesurat el
     05-09-2026 a 390 px).

     NO s'amaga, i el motiu val la pena escriure'l: la barra de dalt porta els
     dotze mòduls però NO porta cap enllaç a l'inici —comprovat—, o sigui que
     aquest és l'única porta de tornada. Amagar-lo al telèfon seria treure una
     capacitat de navegació sencera per guanyar píxels, que és el patró «motor
     sense porta» al revés. Es fa més barat, no desapareix, i conserva els
     44 px de zona de toc. */
  .pt-mod > div:has(> .pt-back-link) {
    display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; }
  .pt-mod > div:has(> .pt-back-link) > .pt-mod-head {
    flex:1 1 220px; min-width:0; }
}

/* ══════════════════════════════════════════════════════════════════════════
   COMPONENTS D'INTERACCIÓ I ESTAT (pàgina /entitat; reutilitzables)
   Cercador, resultats, cross-links de taula, taula clau-valor i estats
   "pendent de dades" (calm) vs "acció pendent" (ambre). Additiu — no trenca res.
   ══════════════════════════════════════════════════════════════════════════ */

/* Cercador */
.pt-cerca-wrap { margin:20px 0 24px; }
.pt-cerca-cap { color:var(--pt-muted); font-size:.82rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.5px; }
.pt-input { width:100%; max-width:520px; padding:9px 14px;
  border-radius:var(--pt-radius-sm); border:1.5px solid var(--pt-line);
  font-size:.95rem; font-family:inherit; background:var(--pt-surface);
  color:var(--pt-text); transition:border-color .15s ease, box-shadow .15s ease; }
.pt-input:focus, .pt-input:focus-visible { outline:none; border-color:var(--pt-verd);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); }
.pt-input::placeholder { color:var(--pt-muted); }
.pt-cerca-hint { display:block; color:var(--pt-muted); font-size:.8rem; margin-top:6px; }
.pt-cerca-res { background:var(--pt-surface); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); box-shadow:var(--pt-shadow); overflow:hidden;
  margin-top:10px; max-width:640px; }
.pt-cerca-fila { display:flex; align-items:center; gap:8px; padding:10px 14px;
  border-bottom:1px solid var(--pt-line); min-height:44px; }
.pt-cerca-fila:last-child { border-bottom:none; }
.pt-cerca-fila:hover { background:var(--pt-verd-pastel); }
.pt-cerca-fila a { color:var(--pt-verd); text-decoration:none; font-weight:500; }
.pt-cerca-fila a:hover { text-decoration:underline; color:var(--pt-verd-dark); }
.pt-cerca-fila .pt-cerca-cap { text-transform:none; font-weight:400; letter-spacing:0; }

/* Breadcrumb de la fitxa */
.pt-breadcrumb { margin-bottom:12px; font-size:.85rem; }
.pt-breadcrumb .pt-crumb-sep { color:var(--pt-muted); margin:0 6px; }
.pt-breadcrumb .pt-crumb-cur { color:var(--pt-muted); }

/* Enllaços dins de taula → verd de marca (no el blau Bootstrap per defecte) */
.pt-table td a, .pt-table td a:visited { color:var(--pt-verd);
  text-decoration:none; font-weight:500; }
.pt-table td a:hover { color:var(--pt-verd-dark); text-decoration:underline; }

/* Taula clau-valor (registre de la fitxa): 1a col = etiqueta, 2a = valor */
.pt-table-kv .pt-table td:first-child { color:var(--pt-muted); font-weight:400;
  width:38%; white-space:nowrap; }
.pt-table-kv .pt-table td:nth-child(2) { color:var(--pt-text); font-weight:500; }

/* Estat "pendent de dades" (P4): to CALM (argila), no urgència */
.pt-mod-pendent { display:inline-block; background:var(--pt-blau-pastel);
  color:var(--pt-blau); font-size:.72rem; font-weight:600; padding:2px 9px;
  border-radius:var(--pt-radius-sm); margin-left:8px; vertical-align:middle; }
.pt-pendent-text { color:var(--pt-text); font-size:.9rem; line-height:1.55;
  margin:4px 0 0; max-width:78ch; }

/* Avís d'ACCIÓ de l'usuari (p.ex. màquina sense vincle) — ambre, diferenciat del P4 */
.pt-avis-card { background:#FBF3E4; border:1px solid var(--pt-ambre);
  border-left:4px solid var(--pt-ambre); border-radius:var(--pt-radius);
  padding:16px 18px; margin-top:16px; box-shadow:var(--pt-shadow); }
.pt-avis-card h3 { font-size:1rem; font-weight:600; color:var(--pt-text); margin:0 0 4px; }
/* Text FOSC, no blanc (IDUN, cp2c 22-09-2026, recalculat): #FFFFFF sobre
   `--pt-ambre-fosc` (#A66A00) dona 4,484:1 i l'AA de text normal en demana
   4,5 — no passa per 0,016. #000000 hi dona 4,683:1. `--pt-ambre-fosc` es fa
   servir a 5 llocs més de la casa: es toca el TEXT de la pastilla, no el
   color de marca. Cobert per `tests/test_contrast_text.py::
   test_cap_parell_fons_color_declarat_junts_baixa_del_minim_AA`. */
.pt-avis-badge { display:inline-block; background:var(--pt-ambre-fosc); color:#000;
  font-size:.72rem; font-weight:600; padding:2px 9px; border-radius:var(--pt-radius-sm);
  margin-left:8px; vertical-align:middle; }
.pt-avis-text { color:var(--pt-text); font-size:.9rem; line-height:1.55; margin:4px 0 0; }

/* Graella de targetes per producte (assessor de compra de gasoil): 2 columnes
   que es despleguen a 1 sola a mòbil. */
.pt-mod-cards { display:grid; grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
  gap:14px; margin-top:10px; }

/* ── /gasoil, tanda 2b (CP2c) — perímetre obert 22-09-2026 ──────────────────
   Tres graelles PRÒPIES, escopades a aquesta pantalla, perquè cap de les
   dues no reutilitzi `pt-mod-cards`: aquella és auto-fit amb minmax(260px),
   pensada per a les 2 targetes de producte de dalt. Amb 8 entrades de text
   llarg («Què falta per poder decidir?») en donava 4 d'estretes; CSS Grid
   estira per defecte totes les cel·les d'una fila a l'alçada de la més
   llarga (mesurat: la targeta 03 en sola s'enduia les altres tres a la
   seva alçada). Mesurat contra producció: 4.132 px de pàgina, maqueta 2.101.
   Amb columnes amples el text embolica menys línies i la fila deixa de
   créixer per l'outlier. */
.pt-decisions-graella { display:grid; grid-template-columns:1fr 1fr;
  gap:12px 20px; margin-top:10px; align-items:start; }
@media (max-width:768px) {
  .pt-decisions-graella { grid-template-columns:1fr; }
}

/* Targeta de la graella 01-08: NO `pt-mod-card` (vora discontínua, pensada
   per a «Properament» — dada que encara no existeix). Aquí la dada és real
   i decidida; una vora de placeholder + fons gairebé del mateix to que el
   cos de la pàgina (`--pt-soft` sobre `--pt-bg`) és el que feia la graella
   semblar plana i densa. Superfície blanca + vora sòlida, com `.pt-sec`. */
.pt-decisio-card { display:flex; gap:10px; align-items:flex-start;
  background:var(--pt-surface); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); box-shadow:var(--pt-shadow);
  padding:14px 16px; }

/* Els sis blocs de peu (R9 visual): 2 columnes reals, com `.lower` de la
   maqueta. `pt-mod-cards` en donava 3 per fila a 1366 px. Cada bloc ja porta
   la seva pròpia capsa (`section_plegable` → `.pt-sec.pt-plec`); aquí només
   es distribueix la graella. */
/* `align-items:start` (IDUN, cp2c 22-09-2026): sense això, CSS Grid estira
   TOTES les cel·les d'una fila a l'alçada de la més llarga i deixa blanc buit
   sota els blocs curts — el mateix patró que `.pt-decisions-graella` (línia
   ~408) ja va necessitar aquest mateix motiu. */
.pt-blocs-peu { display:grid; grid-template-columns:1fr 1fr; gap:12px 20px;
  align-items:start; }
@media (max-width:768px) {
  .pt-blocs-peu { grid-template-columns:1fr; }
}

/* Franja de frescor: capsa diferenciada com `.freshness` de la maqueta
   (fons propi + aire), no una línia de text amb marge inline. El badge
   (`pt-avis-badge`, ja existent) es queda tal qual. */
.pt-frescor-franja { display:flex; flex-wrap:wrap; align-items:center;
  gap:8px; background:var(--pt-soft); border-radius:var(--pt-radius-sm);
  padding:8px 14px; margin:4px 0 16px; font-size:.85rem; color:var(--pt-muted); }

/* ── Telèfon petit (≤ 480px): densitat mínima ── */
@media (max-width: 480px) {
  .pt-topbar { padding:7px 10px; }
  .pt-nav { gap:5px; padding:6px 10px; }
  .pt-main { padding:14px 10px; }
  .pt-kpi { padding:11px 13px; }
  .pt-kpi-val { font-size:1.25rem; }
  .pt-kpi-label { letter-spacing:.3px; }
  .pt-sec { padding:12px 12px; margin-bottom:14px; }
  .pt-sec h3 { font-size:.95rem; }
  .pt-home-grid { grid-template-columns:1fr 1fr; }
  .pt-home-title { font-size:1.2rem; }
  .pt-table { font-size:.8rem; }
  .pt-table th, .pt-table td { padding:6px 8px; }
  .pt-mod-glyph { font-size:1.6rem; }
  .pt-mod-title { font-size:1.2rem; }
}

/* ══ SESHAT · planificació diària (kanban modular) ══════════════════════ */
.ses-controls { overscroll-behavior-x: contain;   /* «El lliscament d'un carril» */
  display:flex; flex-wrap:wrap; gap:14px; align-items:center;
  justify-content:space-between; margin-bottom:16px; }
/* Navegació de dia = pill segmentat cohesionat [‹ | data | ›] + Avui a part */
.ses-dianav { display:flex; align-items:center; gap:8px; }
.ses-nav-btn { min-width:44px; min-height:44px; border:1px solid var(--pt-line);
  background: var(--pt-surface); border-radius:var(--pt-radius); font-size:1.15rem;
  cursor:pointer; color: var(--pt-verd-dark); font-weight:600; }
.ses-nav-btn:hover { background: var(--pt-verd-pastel);
  border-color: var(--pt-verd); }
.ses-nav-avui { font-size:.85rem; padding:0 16px; }
.ses-dia-label { font-weight:700; min-width:180px; text-align:center;
  font-size:1.02rem; padding:0 8px; border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); min-height:44px; display:inline-flex;
  align-items:center; justify-content:center; background: var(--pt-surface); }
.ses-dia-off { color: var(--pt-muted); }             /* dia ≠ avui, més apagat */
.ses-dia-label:not(.ses-dia-off) { color: var(--pt-verd-dark);
  border-color: var(--pt-verd); background: var(--pt-verd-pastel); }
/* Vistes = desplegable: el resum deixa només la vista activa a la barra i
   obre les set opcions quan cal. */
.ses-vistes-plec { margin:0; min-width:0; background:var(--pt-surface);
  position:relative; }
/* La barra és l'àncora dels panells que volen (`position:relative` aquí i
   `absolute` a sota). Ancorar-los al DISPARADOR era el primer intent i no
   aguanta: amb `left:0` la llegenda sortia per la dreta a 1000px d'ample
   (x=440→1057 contra 1000), i ancorant-los a la dreta el de vistes sortia
   per l'ESQUERRA (x=-192). Cap dels dos costats és bo perquè el disparador
   es mou; la barra, no. Mesurat a 1920, 1366, 1100 i 1000. */
.ses-controls { position:relative; }
/* ELS DESPLEGABLES VOLEN PER DAMUNT DE LA TAULA (encàrrec del gerent,
   19-09-2026). Un `<details>` obert, en flux, empeny tot el que té a sota:
   mesurat aquí mateix, la llegenda apilada tirava la primera fitxa del
   tauler de y=424 a y=748 —fora de pantalla a 768px— i en fila encara la
   deixava a y=556. Posant el contingut FORA DEL FLUX, el quadre no es mou
   ni un píxel i el desplegable se li posa a sobre.
   `> *:not(summary)`: el que vola és el contingut, mai el disparador, i
   així val per als dos desplegables de la barra sense haver de repetir la
   regla cada cop que en neixi un de nou.
   El `z-index` va per sota de la capçalera apegalosa (100) i per sobre de
   tot el que és tauler, que no en té cap de propi. */
.ses-vistes-plec[open] > *:not(summary) {
  position:absolute; top:100%; left:0; z-index:90;
  width:max-content; max-width:min(92vw, 420px); max-height:60vh;
  overflow:auto; background:var(--pt-surface);
  border:1px solid var(--pt-line); border-radius:var(--pt-radius);
  box-shadow:var(--pt-shadow-hov); }
.ses-vistes-sum { min-height:44px; display:flex; align-items:center; gap:8px;
  padding:6px 12px; color:var(--pt-verd-dark); }
/* Especificitat, no ordre. `.ses-vistes-sum::before{display:none}` tenia el
   mateix pes que `.ses-config-sum::before` de la línia ~847 i perdia per
   ordre de fitxer: els dos desplegables de la barra pintaven el triangle
   CSS *i* la fletxa de text, dues fletxes per control. Mesurat el 19-09 al
   navegador (`::before` amb `display:block` i 4px de vora als dos). Amb la
   doble classe guanya sempre, visqui on visqui la regla germana. */
.ses-config-sum.ses-vistes-sum::before { display:none; }
.ses-vistes-fletxa { font-size:.78rem; transition:transform .15s ease-out; }
.ses-vistes-plec[open] .ses-vistes-fletxa { transform:rotate(180deg); }
/* En FILA, no en columna. Amb les cinc categories apilades el plec obert
   feia 324px i empenyia la primera fitxa del tauler de y=424 a y=748 —fora
   de pantalla sencera a 768px d'alçada, mesurat el 19-09—. Els rètols són
   curts («01 · Noves»), o sigui que en fila hi caben tots amb un sol salt i
   el gerent segueix veient el quadre mentre consulta la llegenda. El
   `flex-wrap` és qui ho fa aguantar quan algú n'afegeixi amb la rodeta. */
/* CAP AVALL, no en horitzontal (gerent, 19-09-2026). La fila va ser un
   pedaç d'una altra època: mentre el plec era EN FLUX calia estalviar
   alçada perquè empenyia el quadre pantalla avall. Ara que el panell vola
   (`.ses-vistes-plec[open] > *:not(summary)`, aquí a sobre) l'alçada no
   costa res, i una llista vertical es llegeix com el que és: un menú. */
.ses-llegenda-llista { display:flex; flex-direction:column; gap:4px;
  padding:6px; border-top:1px solid var(--pt-line); }
.ses-llegenda-fila { display:flex; align-items:center; gap:8px; min-height:44px;
  padding:0 10px; border-radius:var(--pt-radius-sm); color:var(--pt-text); }
.ses-llegenda-fila.ses-obra-to-0 { background:var(--pt-obra-1); }
.ses-llegenda-fila.ses-obra-to-1 { background:var(--pt-obra-2); }
.ses-llegenda-fila.ses-obra-to-2 { background:var(--pt-obra-3); }
.ses-llegenda-fila.ses-obra-to-3 { background:var(--pt-obra-4); }
.ses-llegenda-fila.ses-obra-to-4 { background:var(--pt-obra-5); }
.ses-llegenda-fila.ses-obra-to-5 { background:var(--pt-obra-6); }
.ses-cat-codi-vinyeta { display:inline-flex; align-items:center; justify-content:center;
  min-width:28px; min-height:24px; padding:0 5px; border:1px solid currentColor;
  border-radius:5px; font-size:.76rem; font-weight:700; font-variant-numeric:tabular-nums; }
/* La categoria DEDUÏDA pel sistema (CP3: `01 · Noves` mentre l'obra és
   nova) no es pot veure igual que la que ha triat una persona: la vora a
   ratlles diu «això encara no ho ha decidit ningú» sense treure-li el to.
   El color no informa tot sol —regla de la casa—: el `title` del `<span>`
   ho diu amb paraules i el codi hi és igualment. */
.ses-cat-codi-vinyeta.ses-cat-auto { border-style:dashed; opacity:.85; }
/* CP7 · els grups de la vista «Per categoria». La capçalera del grup porta
   el to de la categoria, però el codi i el NOM hi són sempre escrits: el
   color no informa tot sol. El grup «Sense categoria» no en porta cap, que
   és exactament el que vol dir. */
.ses-catgrups { display:flex; flex-direction:column; gap:18px; }
.ses-catgrup-cap { display:flex; align-items:center; gap:8px; padding:8px 12px;
  border-radius:var(--pt-radius-sm); margin-bottom:8px; color:var(--pt-text); }
.ses-catgrup-cap.ses-obra-to-0 { background:var(--pt-obra-1); }
.ses-catgrup-cap.ses-obra-to-1 { background:var(--pt-obra-2); }
.ses-catgrup-cap.ses-obra-to-2 { background:var(--pt-obra-3); }
.ses-catgrup-cap.ses-obra-to-3 { background:var(--pt-obra-4); }
.ses-catgrup-cap.ses-obra-to-4 { background:var(--pt-obra-5); }
.ses-catgrup-cap.ses-obra-to-5 { background:var(--pt-obra-6); }
.ses-catgrup-sense { background:var(--pt-soft);
  border:1px dashed var(--pt-line); }
.ses-cat-auto-nota { font-size:.76rem; color:var(--pt-muted);
  font-style:italic; }
/* Les dues notes de la llegenda (què vol dir la vora a ratlles i el `—`) i
   les pistes escrites. Van a la llegenda i no a un `title`, que a la tauleta
   —com es fa servir aquesta pantalla a l'obra— no existeix. */
.ses-llegenda-notes { display:flex; flex-direction:column; gap:6px;
  padding:6px 6px 2px; border-top:1px solid var(--pt-line); }
.ses-llegenda-nota { display:flex; align-items:center; gap:8px;
  font-size:.82rem; color:var(--pt-muted); }
.ses-llegenda-nota > .ses-cat-codi-vinyeta { flex:0 0 auto; }
.ses-llegenda-pista, .ses-cat-pista { font-size:.8rem; margin:4px 6px 8px; }
.ses-categories-rodeta { margin:6px; }
.ses-categories-config { display:flex; flex-direction:column; gap:6px; padding:6px 0; }
.ses-cat-fila { display:grid; grid-template-columns:48px minmax(100px,1fr) 86px 82px 68px;
  gap:6px; align-items:center; }
.ses-cat-codi { min-height:44px; width:100%; box-sizing:border-box; text-align:center; }
.ses-cat-nom { min-width:0; }
.ses-cat-to .dash-dropdown { min-height:44px; }
.ses-cat-actiu { min-height:44px; display:flex; align-items:center; }
.ses-cat-actiu label { min-height:44px; display:flex; align-items:center; }
.ses-categoria-tria { display:flex; flex-wrap:wrap; gap:4px; }
.ses-categoria-chip { min-height:44px; gap:5px; }
.ses-categoria-radio { position:absolute; opacity:0; pointer-events:none; }
/* La mostra de color per opció del selector de categoria va morir el
   19-09-2026: `dcc.RadioItems` de Dash 4.1 només accepta CADENES a
   `options[].label` i un component hi feia petar el renderitzador (280
   errors de consola, mesurats al banc). L'etiqueta és ara « CODI · Nom »
   i el color viu on informa: les columnes del tauler i la llegenda. */
@media (max-width:768px) {
  .ses-cat-fila { grid-template-columns:48px 1fr 86px; }
  .ses-cat-actiu, .ses-cat-fila .ses-btn-mini { grid-column:auto; }
}
.ses-vistes { overscroll-behavior-x: contain;   /* «El lliscament d'un carril» */
  /* `position:relative` és el que tanca el SEGON camí del desbordament, el que
     `overscroll-behavior-x:contain` i `overflow-x:clip` no van poder aturar el
     07-09 («un comportament que no sé explicar», línia 410). L'explicació és
     aquesta: Dash pinta el radio de cada pastella dins d'un
     `span.dash-options-list-option-wrapper` que porta `position:absolute` al
     CSS del propi component (`dash/dcc/dash_core_components.js`, no editable
     des d'aquí). Sense cap avantpassat posicionat, el seu bloc contenidor és
     el ICB, i un element absolut NOMÉS el retalla l'avantpassat que li fa de
     bloc contenidor: per això l'`overflow-x:auto` d'aquesta mateixa caixa el
     deixava passar. A 390 px la setena pastella cau a x=1301 i el seu wrapper
     acaba a 1302 = `documentElement.scrollWidth` EXACTE. Amb `relative`, el
     bloc contenidor torna a ser aquesta caixa i el retall sí que l'agafa.
     Mesurat: 1302 → 390 px (mutació: treure la línia el torna a 1302). */
  position: relative;
  /* En COLUMNA (gerent, 19-09-2026): les set vistes es trien d'una
     llista que baixa, no d'una tira que s'embolica. `nowrap` perquè amb
     `column` el `wrap` obriria una SEGONA columna al costat, que és
     exactament el que ell no vol. */
  display:flex; flex-direction:column; flex-wrap:nowrap; gap:4px;
  background: var(--pt-soft);
  border-top:1px solid var(--pt-line); padding:4px; }
/* 17-09-2026: hi havia DUES `min-height` a la mateixa regla (44px i
   després 40px). En CSS guanya l'última, o sigui que el xip mesurava 40
   i incomplia el terra de 44px que el sistema de disseny exigeix a tot
   element tocable. Ho vigila `test_el_xip_te_un_sol_terra_de_44px`. */
.ses-chip { min-height:44px; display:inline-flex; align-items:center;
  padding:6px 14px; border:1px solid transparent; border-radius:var(--pt-radius-sm);
  background:transparent; cursor:pointer; font-size:.88rem;
  font-weight:600; color: var(--pt-muted); }
/* Dins del desplegable, TOTS igual d'amples (gerent, 19-09-2026). El xip
   neix `inline-flex` —amplada natural— i en columna això deixava una vora
   dreta serrada: mesurat, de 66px («Tauler») a 138px («Viatges de gòndola»)
   en la mateixa llista. `dcc.RadioItems` de Dash 4 no posa `labelClassName`
   al `<label>` sinó a un `<span>` de dins, o sigui que estirar l'etiqueta
   no n'hi ha prou: cal estirar el xip mateix. La llegenda ja ho feia (les
   cinc files fan 232px) i ara les dues llistes es comporten igual. */
/* `.ses-pagina .ses-vistes-plec` (0,3,0) per sobre de `.ses-pagina
   .ses-vistes` (0,2,0) del `@media` de la línia ~1864, que posa
   `align-items:center` — escrit quan les vistes eren una tira horitzontal
   que llisca, i que dins d'un desplegable ja no vol dir res. Els `@media`
   NO sumen especificitat, o sigui que sense aquesta tercera classe la
   regla de sota perdria. Era exactament això el que deixava els xips amb
   l'amplada natural. */
.ses-pagina .ses-vistes-plec .ses-vistes {
  align-items:stretch; flex-direction:column; flex-wrap:nowrap; }
.ses-vistes-plec .ses-chip { width:100%; justify-content:flex-start; }
.ses-chip:hover { background: var(--pt-verd-pastel); color: var(--pt-verd-dark); }
.ses-chip:has(input:checked) { background: var(--pt-surface); color: var(--pt-verd-dark);
  border-color: var(--pt-verd); box-shadow:0 1px 4px rgba(28,26,23,.1); }
.ses-chip input { position:absolute; opacity:0; pointer-events:none; }
.ses-pregunta { color: var(--pt-muted); font-style:italic; margin:4px 0 10px; }

.ses-det { background: var(--pt-surface); border:1px solid var(--pt-line);
  border-left:4px solid var(--pt-ambre-fosc); border-radius:var(--pt-radius-sm);
  padding:10px 14px; margin-bottom:14px; font-size:.9rem; }
.ses-det-buida { border-left-color: var(--pt-verd); color: var(--pt-muted); }
.ses-det-cap { margin:0 0 6px; font-weight:600; font-size:.82rem;
  text-transform:uppercase; letter-spacing:.05em; color: var(--pt-muted); }
.ses-det-list { margin:0; padding-left:4px; list-style:none; }
.ses-det-list li { margin-bottom:5px; line-height:1.45; }

/* NOMÉS lectura, «per obra»: mosaic de fitxes que es repassen. NO és
   `.ses-graella` (línia ~915), que és la densitat de la vista `tauler`
   —amb el mateix arrossegament i els mateixos formularis— per veure les
   obres OBERTES del dia de cop. Dues graelles, dues feines. */
.ses-grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(300px,1fr));
  gap:12px; }
.ses-card { background: var(--pt-surface); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); padding:12px 14px; box-shadow: var(--pt-shadow, none); }
.ses-card-cap { font-size:.98rem; margin-bottom:8px; display:flex;
  align-items:center; gap:4px; flex-wrap:wrap; }
.ses-card-peu { color: var(--pt-muted); font-size:.82rem; margin:8px 0 0; }
.ses-glyph { font-size:1.1rem; }
.ses-feina { display:flex; justify-content:space-between; align-items:center;
  gap:10px; padding:7px 0; border-top:1px dashed var(--pt-line);
  flex-wrap:wrap; }
.ses-feina:first-child { border-top:none; }
.ses-muted { color: var(--pt-muted); font-size:.86rem; }
.ses-estat { white-space:nowrap; font-size:.84rem; color: var(--pt-muted); }
.ses-mov { margin-top:8px; font-size:.88rem; }

.ses-btn { min-height:44px; }
.ses-btn-2 { background: var(--pt-blau); }
.ses-btn-2:hover { background:#6E3A2D; }
.ses-btn-mini { border:1px solid var(--pt-line); background: var(--pt-soft);
  border-radius:var(--pt-radius-sm); padding:6px 10px; font-size:.8rem; cursor:pointer;
  color: var(--pt-warn-dark); min-height:34px; }
.ses-btn-mini:hover { background: var(--pt-blau-pastel); }

.ses-tr-form, .ses-tanca-form { display:flex; flex-wrap:wrap; gap:8px;
  align-items:center; margin-top:10px; }
.ses-dd { min-width:220px; flex:1; }
.ses-inp-h { width:110px; min-height:38px; border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); padding:4px 10px; }
.ses-inp-m { flex:1; min-width:160px; min-height:38px;
  border:1px solid var(--pt-line); border-radius:var(--pt-radius-sm); padding:4px 10px; }
.ses-radio label { margin-right:12px; }
.ses-col-h { max-width:140px; }

.ses-avis-text { background: var(--pt-soft); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); padding:10px 12px; font-family:inherit; font-size:.86rem;
  white-space:pre-wrap; margin:8px 0; }

/* ── El lliscament d'un carril NO se n'endú la pàgina ──────────────────────
   El gerent, 07-09-2026: «planificació té scroll horitzontal en mòbil i es
   perd la vista». La causa NO era l'amplada de cap caixa —clamar-les una a una
   guanyava 0 px, mesurat— sinó l'ENCADENAMENT: en prémer una pastella del
   selector, el navegador la porta a la vista i el moviment es propaga del
   carril al document sencer. Efecte al telèfon: toques una vista i tota la
   pàgina se't'n va de costat.

   LA REGLA VA ALS CARRILS, NO A L'ARREL, i costa dir-ho perquè jo mateix vaig
   escriure aquí el contrari durant una hora. `html { overscroll-behavior-x:
   contain }` NO fa res: mutat, la pàgina segueix lliscant els mateixos 912 px
   amb `html` computant `contain`. Qui ha de dur la regla és el carril que
   llisca, perquè `overscroll-behavior` el llegeix el navegador de l'element
   que ARRIBA AL SEU FINAL, no del que rebria l'empenta.

   I SOBRETOT, COM ES PROVA. `window.scrollTo(5000)` NO serveix per a res
   aquí: és un desplaçament PROGRAMÀTIC i `overscroll-behavior` només frena
   els GESTOS. Amb `scrollTo` totes dues versions donen 912 i qualsevol fix
   sembla inútil — és el que em va fer descartar aquesta regla i posar-ne una
   de falsa a l'arrel. La prova bona és una roda de veritat sobre el carril
   (`mouse.wheel(400, 0)` × 12):

     amb `contain`  →  carril 1.131 · pàgina **0**
     amb `auto`     →  carril 1.131 · pàgina **912**   (mutació verificada)

   El carril llisca igual en els dos casos: la regla NO tapa contingut, només
   impedeix que el moviment surti del carril. Després del canvi la barra de
   navegació segueix ensenyant 390 px de 1.521, el selector 346 de 1.046 i la
   fila d'indicadors 362 de 661. Només afecta l'eix X.

   ⚠️ AIXÒ TANCA UN CAMÍ DELS DOS, i queda escrit perquè el proper no es pensi
   que està resolt. N'hi ha un segon que aquesta regla NO frena: **prémer una
   pastella del selector**. El navegador la porta a la vista amb un
   desplaçament que no és un gest, i `overscroll-behavior` no el mira. Mesurat
   passant per les catorze pastelles: `html.scrollLeft` puja 0 → 602 → 912
   amb el `contain` posat. I `html { overflow-x: clip }` TAMPOC el frena —
   provat, amb `overflow-x` computant `clip` i `html.scrollLeft` arribant
   igualment a 912, que és un comportament que no sé explicar i no vull tapar
   amb una regla que no entenc. Queda a VÖR amb aquesta mesura al davant. */
.pt-nav { overscroll-behavior-x: contain; }
/* Els altres tres carrils (`.ses-vistes`, `.ses-controls`, `.pt-kpi-row`) porten
   la mateixa propietat dins de la seva PRÒPIA definició, no aquí: definir-los un
   segon cop és el defecte que `test_css_una_sola_vegada.py` vigila, i em va caçar
   escrivint-lo. Una classe, una font. */

@media (max-width: 768px) {
  .ses-controls { flex-direction:column; align-items:stretch; }
  /* `min-width:0` és el que fa que l'`overflow-x` d'aquesta mateixa línia
     serveixi de res: un fill flexible NO baixa de la mida del seu contingut
     (`min-width:auto` per defecte), o sigui que el selector creixia fins a
     1.048 px dins d'un pare de 362 en una pantalla de 390. Amb la caixa
     desbordada, prémer una pastilla feia que el navegador la portés a la
     vista i el lliscament es propagués al DOCUMENT: la pàgina sencera es
     movia de costat i el gerent perdia on era («es perd la vista», 07-09).
     Autoria del diagnòstic i de la regla: branca `vistes-desborden`
     (c374aac); aquí s'incorpora al tronc perquè allà mai va arribar a main.

     COM ES MESURA, que és la part caríssima: cap de les mesures estàtiques
     ho veu. Amb la pàgina acabada de carregar `body.scrollWidth-innerWidth`
     dona 0 SEMPRE (el pare reté), `documentElement` dona 912 tant si està
     trencat com si no, i `scrollTo(5000)` també dona 0. El lliscament només
     apareix DESPRÉS de prémer les pastilles del selector: 0 → 301 → 474 →
     602 → 760 → 912 a mesura que es passa per les set vistes. La sonda
     `sonda_mobil_planificacio.py --desbordament` exercita el selector abans
     de mesurar justament per això. */
  .ses-vistes { overflow-x:auto; flex-wrap:nowrap; padding-bottom:4px;
    min-width:0; max-width:100%; }
  .ses-chip { min-height:44px; white-space:nowrap; }
  .ses-grid { grid-template-columns:1fr; }
}

/* ── SESHAT · passada IDUN (contrast, targets, focus, jerarquia) ───────── */
/* DS-002: variant argila SEMPRE amb text blanc (6,69:1) */
.ses-btn-2, .ses-btn-2:hover { color:#FFFFFF; }
/* DS-003: target del boto destructiu (Anul·la) */
.ses-btn-mini { min-height:44px; padding:8px 14px; }
/* DS-001: cap font operativa per sota de .84rem; estat a .88rem */
.ses-estat { font-size:.88rem; }
.ses-card-peu { font-size:.84rem; }
.ses-det-cap { font-size:.84rem; }
/* DS-004: zona de controls ancorada + la pregunta guia amb pes de subtitol */
.ses-controls { background: var(--pt-soft); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); padding:12px 14px; margin-bottom:16px; }
/* CONTROL (santi #5, 16-09-2026): a 1366 px, dia+set pastelles+l'interruptor
   nou sumaven 1652 px de `scrollWidth` contra 1336 de `clientWidth` — es
   veia bé perquè `.ses-densitat-sel` (radi natiu amagat amb la mateixa
   tècnica que `.ses-vistes`, `position:absolute;width:1px`) queia FORA de
   la finestra en silenci, i només es notava quan es clicava: el navegador
   enfocava l'`input` amagat i desplaçava la pàgina sencera 192 px per
   ensenyar-lo (`scrollX` 0→192, `documentElement.scrollWidth` 1558 contra
   1366 de `clientWidth`). `flex-wrap:wrap` deixa que l'interruptor baixi a
   una segona línia en lloc de sobresortir invisible. */
.ses-pagina .ses-controls { flex-wrap:wrap; row-gap:8px; }
.ses-pregunta { font-size:.95rem; font-weight:500; color: var(--pt-text);
  font-style:normal; margin:0 0 12px; padding:8px 0;
  border-bottom:1px solid var(--pt-line); }
/* DS-005: inputs de tancament alineats amb el sistema (focus ring de marca) */
.ses-inp-h, .ses-inp-m { border:1.5px solid var(--pt-line);
  font-family:inherit; font-size:.95rem; background: var(--pt-surface);
  color: var(--pt-text);
  transition: border-color .15s ease, box-shadow .15s ease; }
.ses-inp-h:focus, .ses-inp-h:focus-visible,
.ses-inp-m:focus, .ses-inp-m:focus-visible {
  outline:none; border-color: var(--pt-verd);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); }
/* Contracte de focus per a tots els interactius SESHAT (teclat) */
.ses-nav-btn:focus-visible, .ses-chip:focus-visible,
.ses-btn-mini:focus-visible {
  outline:none; box-shadow:0 0 0 3px var(--pt-verd-pastel);
  border-color: var(--pt-verd); }
@media (max-width: 768px) {
  .ses-btn-mini { min-height:44px; padding:10px 14px; }
  .ses-inp-h, .ses-inp-m { min-height:44px; font-size:1rem; }
  /* Defecte 7 de la revisió (04-10-2026): ↑/↓ del quadre de trasllats
     (`.ses-tr-form .ses-btn-mini`) només porten un glif d'una lletra
     («↑»/«↓») — el `padding` de dalt els dona alçada, però amb text tan
     curt l'AMPLADA es queda per sota de 44px. Sense un `min-width` propi
     un dit gruixut els falla al costat de la resta de botons de la casa. */
  .ses-tcard-tr .ses-tr-form .ses-btn-mini { min-width:44px; min-height:44px; }
}

/* ── SESHAT · passada FREYA (context temporal + resum de safata) ────────── */
/* Dia seleccionat != avui: fons ambre suau perquè no es planifiqui
   sobre el dia equivocat sense adonar-se'n */
.ses-dia-off { background: #FBF3E0; border:1px solid var(--pt-ambre-fosc);
  color: var(--pt-text); border-radius:var(--pt-radius-sm); padding:6px 10px; }
.ses-av-resum { font-weight:600; font-size:.92rem; margin:0 0 10px;
  color: var(--pt-text); }
/* Panell «qui falta per confirmar» (d'un cop d'ull) */
.ses-av-panell { border:1px solid var(--pt-line); border-radius:var(--pt-radius);
  background: var(--pt-surface); padding:12px 14px; margin:0 0 12px; }
.ses-av-cap { font-weight:600; margin:0 0 8px; }
.ses-av-linia { font-size:.92rem; margin:3px 0; }
.ses-av-accions { display:flex; flex-wrap:wrap; gap:8px; align-items:center;
  margin-top:6px; }

/* ── SESHAT 2.0 · tauler de targetes (columnes + drag&drop) ─────────────── */
/* El tauler ocupa TOTA l'amplada de pantalla (full-bleed), la resta de la
   pàgina es queda centrada. És l'apartat de treball intensiu amb volum. */
/* 18-09-2026 (ITERAR queixa 4) · «tampoc hauria d'estar recarregant-se la
   pàgina cada cop que moc algo». `do_ses_board` (app.py) repinta `#ses-board`
   SENCER a cada moviment i el navegador saltava sol: mesurat 1721 -> 1773px
   amb `--gest obra`, 1721 -> 1747px amb `--gest targeta`
   (`sonda_compacitat_planificacio.py --moviment-no-salta`). La CAUSA no era
   Dash ni el JS: és l'ANCORATGE DE SCROLL natiu del navegador (CSS Scroll
   Anchoring), que en substituir tot el subarbre tria un ancoratge dins del
   contingut ACABAT D'ESBORRAR i, en no poder-lo retrobar, salta. Provat amb
   Playwright, aïllant la causa: sense aquesta regla el salt hi és SEMPRE
   (fins i tot capturant `scrollY` i restaurant-lo a mà per JS després del
   repintat — l'ancoratge natiu el torna a desplaçar tot sol just després);
   amb `overflow-anchor:none` el `scrollY` NO es mou gens, cap JS necessari.
   Via barata i directa: una propietat, sense estat duplicat de cap mena. */
.ses-pagina { overflow-anchor: none; }
.ses-tauler-wrap { width:100vw; margin-left:calc(50% - 50vw);
  padding:0 clamp(12px, 3vw, 40px); box-sizing:border-box; }
.ses-tauler { display:flex; gap:12px; align-items:flex-start;
  overflow-x:auto; padding-bottom:10px; }
.ses-tcol { flex:0 0 288px; min-width:288px; background: var(--pt-soft);
  border:1px solid var(--pt-line); border-radius:var(--pt-radius); padding:10px; }
/* ── Identitat d'obra (PLA 16-09-2026) ───────────────────────────────────
   Un to de fons per obra, MAI per a text: el rètol (nom/client) hi és
   sempre — «el color no informa tot sol». `_capçalera_columna` (Python) hi
   posa la classe `ses-obra-to-<n>` a `.ses-tcol-cap`, no aquí: aquesta
   funció no construeix mai el `.ses-tcol` de fora. El `:has()` la fa
   pujar, mateix patró que ja fa servir la casa a
   `.ses-pagina.ses-graella:has(.ses-tcard-sel)`. Els 6 tons surten NOMÉS
   de `config.OBRA_TONS` (`--pt-obra-1..6`, `config.tokens_color()`). */
/* La VORA no és del color del fons (19-09-2026). Ho va veure el gerent:
   «no es veu bé la part de baix del quadre de la obra». Mentre el to era
   IDENTITAT d'obra, cada obra en tenia un de diferent i la vora la feia el
   canvi de color: dues cel·les seguides quasi mai coincidien. Amb les
   CATEGORIES, **15 de 22 parelles verticals comparteixen to** —la majoria
   són `01 · Noves`— i, amb la vora pintada del mateix color que el fons,
   dues obres seguides es fonien en un sol bloc. La vora passa a `--pt-line`,
   que separa hi hagi el to que hi hagi. */
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-0) { background: var(--pt-obra-1); }
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-1) { background: var(--pt-obra-2); }
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-2) { background: var(--pt-obra-3); }
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-3) { background: var(--pt-obra-4); }
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-4) { background: var(--pt-obra-5); }
.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-5) { background: var(--pt-obra-6); }
/* ── El PARC, com a carril fix (PLA 16-09-2026) ──────────────────────────
   Marc propi (vora >=1px + fons `--pt-surface`, santi CONTROL: «que quedi
   enquadrat»). `display:flex;flex-direction:column` és la base, EN TOTS
   els modes (a mòbil es dissol amb `display:contents`, més avall): la
   capçalera (rètol) és el primer fill i, després, les DUES meitats
   (`.ses-parc-mitat`) es reparteixen l'alçada que quedi. */
/* 19-09-2026 · 290px → 158px (correcció del gerent, captura marcada en
   groc): «al lateral NOMÉS personal i màquines», i els quatre botons, el
   cercador i el selector d'hores baixen a la barra de controls del tauler
   (`_accions_targeta`/`_cercador_del_tauler`, seshat.py). Sense cap
   comandament a dins, el 290px de l'11-09 (que exigia espai per a
   `#ses-hores-mou` i els botons) ja no té raó de ser: el 158px era el
   MATEIX ample que una vinyeta d'obra tancada (`UNITATS_PER_OBRA=2` de
   `COLUMNES_GRAELLA=12`, mesurat al banc — `.ses-obres > .ses-tcol`
   fa 158px a 1366px de viewport), tal com havia demanat el gerent «si els
   noms hi caben».
   19-09-2026 ~19:19 (R2) · 158px → 240px. AQUELLA raó (coincidir amb
   l'ample d'una obra tancada) queda SUPERADA per l'ordre d'ara: «Han de
   ser 3 desplegables (...) amplia horitzontalment una mica més perque no
   es vegi tant ofegat tot». Amb tres blocs plegables i, dins de
   «Màquines», sub-desplegables per categoria (R3), 158px deixava el
   rètol+comptador de cada `<summary>` -que ara ha de ser un control
   tocable de 44px- pràcticament sense marge. 240/1366 = 17,6%, per sota
   del topall `--amplada-parc-pct <= 24` de `sonda_compacitat_planificacio.py`
   (objectiu numèric, no aquesta regla — mateix motiu que la prova de sota:
   un valor fix en px dona percentatges diferents a cada resolució).
   Mesurat amb els noms REALS del banc (`--sembra-com-produccio`): el
   treballador més llarg («Marcelino Grimau») no passa de 2 línies a
   158px (i per tant tampoc a 240), i la màquina més llarga («Hores Tractor
   Fend 936 Amb Desbrossadora Serrat») arriba a 5 a 158px — es comprova
   amb `flex-shrink:0` de sota, que és qui ho garanteix. */
.ses-tcol-parc { background: var(--pt-surface); border:1px solid var(--pt-line);
  flex:0 0 240px; min-width:240px; display:flex; flex-direction:column;
  /* L'`overflow-y` NO va aquí: `test_franja_del_parc_sense_clip_vertical`
     el prohibeix des del 16-09 perquè la vella franja clipava i el cercador
     queia fora de la finestra. Qui llisca segueix sent el `.ses-tcol-cards`
     de cada bloc. */
  min-height:0; }
/* 19-09-2026 · `flex:1 1 50%` era d'un lateral de DUES meitats. Amb TRES
   blocs desplegables (ordre del gerent), 3 × 50 % = 150 %: el navegador els
   encongeix per força i el bloc de treballadors es va quedar a **27 px**
   mentre el de màquines feia 433 —desviació del 88 %, que la sonda
   `--recursos-a-la-vista` va anul·lar— i les targetes dels dos es pintaven
   **les unes damunt de les altres**. Es veia a la captura, no al número.
   Ara cada bloc es mida pel seu CONTINGUT (`flex:0 1 auto`) i qui llisca és
   la columna sencera (`.ses-tcol-parc`, `overflow-y:auto`): un desplegable
   obert ocupa el que demana i un de plegat, res. És el comportament que un
   `<details>` ha de tenir, i el que fa que plegar-ne un serveixi de debò.
   El `flex-shrink` ha de ser **0**, no 1: amb 261+448+41 px de contingut
   dins de 618, el `1` encara deixava encongir i el bloc de treballadors
   queia a 27 px —l'alçada del seu `summary`— amb 261 px de targetes
   sortint per sota i pintant-se damunt de les màquines. Mesurat. */
.ses-parc-mitat { display:flex; flex-direction:column; flex:0 0 auto;
  min-height:0; }
/* 19-09-2026 · EL LATERAL JA NO TÉ DUES MEITATS, EN TÉ TRES. El gerent:
   «trasllats fix al lateral de treballadors i maquines». Amb tres blocs, el
   `flex:1 1 50%` de sobre deixa de voler dir res: 3 × 50 % = 150 % i el
   repartiment el decideix l'ordre, no el disseny.
   El bloc de trasllats NO és una llista de recursos que hagi de créixer: és
   el quadre del dia, i el que li cal és el que ocupa (68 px amb el dia
   buit). Per això es mida pel CONTINGUT i no es queda amb un terç: així les
   dues llistes de recursos conserven l'espai elàstic que ja tenien i el
   número que el gerent mira («N per moure») no desapareix quan el dia
   s'omple. El topall evita el cas contrari —un dia amb vint trasllats
   empenyent treballadors i màquines fora de la vista—, i a dins hi ha
   `overflow` propi.
   Això NO el fa visible en arribar a escriptori: a 1366 el lateral comença
   a 323 px i la finestra en fa 768, o sigui que hi caben 445 px dels 584
   que demanen els tres blocs. Fer-lo visible en arribar voldria dir posar-lo
   DAVANT de les llistes o escurçar-les, i cap de les dues és una decisió
   d'implementació: totes dues canvien el que el gerent va demanar. Queda
   mesurat i reportat. */
/* El topall del 40 % venia de quan els blocs eren elàstics i es
   barallaven per l'alçada. Amb `flex:0 1 auto` a tots tres i la columna
   sencera lliscant, ja no cal: es queda el `flex:0 0 auto` perquè el
   quadre del dia no s'encongeixi quan les llistes creixen. */
.ses-tcol-parc > .ses-parc-mitat-tr { flex:0 0 auto; }
/* El trajecte d'un trasllat, RETALLAT al lateral. Amb 146 px útils i noms
   d'obra de 40+ caràcters («2177-000 CAFISA-WALQA URBANITZACIÓ CARRERS»),
   la línia es partia en set trossos d'una paraula i la targeta creixia
   fins a menjar-se les dues llistes de recursos — vist a la captura del
   19-09, no a cap número. Dues línies i punts suspensius; el trajecte
   sencer viu al `title` de la targeta, que és el mateix patró que el
   títol de la cel·la compacta. El nom NO es perd: es retalla amb accés. */
/* La capcalera del parc no es la d'una obra: no porta client, ni KPIs, ni
   text d'ajuda. Nomes el retol i la fila d'accions. */
.ses-parc-cap { margin-bottom:4px; }
.ses-parc-cap .ses-tcol-titol { font-size:.85rem; margin:0; line-height:1.2; }
/* Treballadors absorbeix l'aire del carril; màquines i trasllats queden al
   peu. `max-height:none` anul·la el topall global de 46vh que en deixava
   només unes tres targetes visibles a 1600×900. */
.ses-parc-mitat-treb { flex:1 1 auto; min-height:0; }
.ses-parc-mitat-treb > .ses-tcol-cards { flex:1 1 auto; min-height:0;
  max-height:none; }
.ses-parc-mitat-maq { flex:0 0 auto; }
.ses-parc-mitat .ses-tcol-cards { flex:1 1 auto; min-height:34px; }
/* R1 (19-09-2026 ~19:19, encàrrec LITERAL del gerent «ara mateix»: «Han de
   ser 3 desplegables (...)»): `mitat_treb`/`mitat_maq`/`mitat_tr` passen de
   `<div>`/`<p>` a `<details open>`/`<summary>` (`seshat.py`). `.ses-tcol-
   sec` (tipografia: uppercase, `.74rem`) es queda igual; `.ses-parc-summary`
   només hi afegeix el comportament de control tocable — es reutilitza el
   mateix patró de fletxa que `.ses-config-sum` (línia ~1000) en lloc
   d'inventar-ne un altre: amb `display:flex` el navegador perd el
   triangle natiu del `<summary>`, i sense cap substitut l'usuari no sabria
   que es pot plegar. Terra de 44px (DESIGN.md): és un control NOU. */
.ses-parc-summary { list-style:none; min-height:44px; display:flex;
  align-items:center; cursor:pointer; touch-action:manipulation; }
.ses-parc-summary::-webkit-details-marker { display:none; }
.ses-parc-summary::before { content:""; display:inline-block; width:0; height:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:4px solid var(--pt-muted); margin-right:7px; flex-shrink:0;
  transition:transform .15s ease; }
.ses-parc-mitat[open] > .ses-parc-summary::before { transform:rotate(90deg); }
.ses-tcard-tr details[open] > .ses-parc-summary::before { transform:rotate(90deg); }
/* La targeta de trasllat és una fitxa de línies (ruta, qui, gòndola, botons),
   no una fila: en fila, a 390px el nom de l'obra quedava en una columna
   estreta de mitja paraula per línia (captura del banc, 27-09-2026). */
.ses-tcard.ses-tcard-tr { flex-direction:column; align-items:stretch; gap:4px; }
.ses-parc-summary:focus-visible { outline:none; border-radius:var(--pt-radius);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); }

/* R3: sub-desplegables de «Màquines» PER CATEGORIA (`q._cats()`, mateix
   ordre i símbol que `q.maquines_per_categoria()`). Classes NOVES —no
   `.ses-maq-selector`/`.ses-maq-cat`/`.ses-maq-fila`: aquell és el
   selector-per-BOTONS del 04-09 que el gerent va rebutjar
   («l'scrol... no es comode» + «Totes les maquines d'esplegable no es
   gens optim»), es queda mort a sota i `test_cap_DESPLEGABLE_plegat_al_parc`
   en prohibeix el retorn. Aquí les files continuen sent les targetes
   ARROSSEGABLES de sempre (`.ses-tcard`), no botons de selecció. */
/* 19-09-2026 · EL PLEC DE CATEGORIA, que només existeix a MÒBIL.
   A escriptori la cel·la compacta amaga tot el peu de l'obra i el selector
   només es veu amb l'obra oberta: allà el `summary` sobra i el contingut ha
   de ser directe (dos tocs, no quatre). A <=768px no hi ha compactació i
   les 28 obres ensenyaven els sis botons de categoria sencers. Un sol DOM;
   el que canvia és quin dels dos trossos es veu. */
.ses-categoria-sum { list-style:none; min-height:44px; display:flex;
  align-items:center; gap:6px; cursor:pointer; font-weight:600;
  font-size:.82rem; color:var(--pt-muted); touch-action:manipulation; }
.ses-categoria-sum::-webkit-details-marker { display:none; }
/* El TRIANGLE DE VORES de la casa (`.ses-parc-summary::before` línia
   ~862, `.ses-config-sum::before` ~1124), no un caràcter de text: el «▸»
   es pinta amb la tipografia del sistema i no fa la mateixa mida ni el
   mateix gris a dues màquines. Dos idiomes de fletxa a la mateixa pantalla
   és el que agent-santi va marcar el 19-09. */
.ses-categoria-sum::before { content:""; display:inline-block;
  width:0; height:0; flex-shrink:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:4px solid var(--pt-muted);
  transition:transform .12s ease; }
.ses-categoria-plec[open] > .ses-categoria-sum::before {
  transform:rotate(90deg); }
@media (min-width: 769px) {
  /* El plec no existeix: el contingut es veu sempre i el rètol sobra. */
  .ses-categoria-plec > .ses-categoria-sum { display:none; }
  .ses-categoria-plec > .ses-color-selector { display:block; }
}
@media (max-width: 768px) {
  /* I AQUÍ s'ha d'amagar EXPLÍCITAMENT. Un `<details>` tancat amaga els
     fills amb el full del navegador, però qualsevol `display:` d'autor hi
     guanya — i `.ses-color-selector` ja en porta un. Mesurat amb la prova
     honesta (`elementFromPoint` sobre el centre d'un xip): els sis xips
     tenien caixa de 74x44 i qui hi havia de veritat en aquell punt era el
     `summary` de «⚙️ L'obra». No estaven amagats: estaven TAPATS, que no
     és el mateix i es trenca al primer canvi de l'altre element. */
  .ses-categoria-plec:not([open]) > .ses-color-selector { display:none; }
}

/* Un plegable TANCAT del parc (bloc o categoria) amaga de veritat el que porta
   dins. El full del navegador ho fa, però `display:flex` d'autor
   (`.ses-tcol-cards`, `.ses-parc-maq-cats`) hi guanya: el contingut es pintava
   a sobre dels veïns (textos encavalcats) i TAPAVA targetes, i el clic o
   l'arrossegament d'una màquina no arribava mai al servidor (26-09, vist a
   producció). */
.ses-tcol-parc details:not([open]) > :not(summary) { display:none; }
/* I un bloc OBERT no pot vessar sobre el següent: Chromium embolcalla el
   contingut d'un <details> en `::details-content`, que no és fill flex, i les
   targetes no s'encongien (198 px de llista dins un bloc de 180: l'última
   targeta quedava sota el títol «Màquines»). Es dissol l'embolcall i la
   llista fa el seu propi scroll. */
.ses-tcol-parc details.ses-parc-mitat::details-content { display:contents; }
.ses-tcol-parc details.ses-parc-mitat > .ses-tcol-cards,
.ses-pagina.ses-graella .ses-tcol-parc details.ses-parc-mitat > .ses-tcol-cards,
.ses-pagina.ses-graella .ses-tcol-parc details.ses-parc-mitat > .ses-parc-maq-cats {
  min-height:0; overflow-y:auto; }

.ses-parc-maq-cats { display:flex; flex-direction:column; gap:2px;
  flex:1 1 auto; min-height:0; overflow-y:auto; padding:2px; }
.ses-parc-maq-cat { border-top:1px solid var(--pt-line); }
.ses-parc-maq-cat:first-child { border-top:0; }
/* Cada sub-categoria té el seu propi `.ses-tcol-cards`, però l'`overflow-y`
   individual de la base (46vh) ja no cal: ara és `.ses-parc-maq-cats` qui
   porta UN sol `overflow-y` per a totes — dues barres de scroll niades
   (una per categoria + una pel bloc sencer) era pitjor que la llista
   plana que aquesta tanda ve a resoldre. */
.ses-parc-maq-cat .ses-tcol-cards { max-height:none; overflow:visible; }
/* 19-09-2026 · «el desplegable de maquines es veu amb poc format»
   (gerent). Mesurat: la capçalera d'una categoria era text gris de 13 px
   sense fons ni vora — el MATEIX pes visual que el bloc pare «MÀQUINES
   (87)», o sigui que no es veia ni que fos un nivell de dins ni que es
   pogués tocar. Passava igual al PC i al mòbil (mesures idèntiques).
   Ara porta superfície, vora i sagnat: es llegeix com una fila que s'obre,
   i les targetes de dins queden clarament per sota d'ella. El terra de
   44 px ja es complia i es manté. */
/* `touch-action:manipulation` NO és decoració: sense ell, el navegador
   espera ~300ms per si el toc és un doble toc per fer zoom, i el
   desplegable respon tard justament al dit. El porten TOTS els controls
   tocables de la casa (`.ses-parc-summary`, `.ses-config-sum`); aquests
   dos van néixer sense (agent-santi, 19-09), i la queixa que els ha fet
   néixer era de mòbil. */
.ses-parc-maq-cat-sum { list-style:none; min-height:44px; display:flex;
  align-items:center; gap:6px; padding:2px 8px; cursor:pointer;
  font-size:.8rem; font-weight:600; color:var(--pt-text);
  background:var(--pt-soft); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); touch-action:manipulation; }
.ses-parc-maq-cat-sum::-webkit-details-marker { display:none; }
.ses-parc-maq-cat-sum::before { content:""; display:inline-block;
  width:0; height:0; flex-shrink:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:4px solid var(--pt-muted);
  transition:transform .12s ease; }
.ses-parc-maq-cat[open] > .ses-parc-maq-cat-sum::before {
  transform:rotate(90deg); }
.ses-parc-maq-cat[open] > .ses-parc-maq-cat-sum {
  border-bottom-left-radius:0; border-bottom-right-radius:0; }
.ses-parc-maq-cat > .ses-tcol-cards { padding-left:8px;
  border-left:2px solid var(--pt-line); margin-left:4px; }
.ses-parc-maq-cat-sum:focus-visible { outline:none; border-radius:var(--pt-radius);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); }
/* R4 (precedent 04-09: «...despres lu de Totes les maquines d'esplegable
   no es gens optim» perquè amagava la recomanació): la targeta recomanada
   viu en el seu propi mini drop-zone, FORA de `.ses-parc-maq-cats`, entre
   el `<summary>` de «Màquines» i les categories — visible sense obrir res
   i encara arrossegable (`.ses-dnd` propi). */
.ses-parc-maq-rec { margin-bottom:2px; }
.ses-tcol-cap { margin-bottom:8px; }
/* `flex` amb `gap`, i no text corrent: amb la vinyeta del codi davant del
   nom, el navegador els enganxava («012177-000 CAFISA-WALQA…», mesurat el
   19-09). No era només lleig — `--color-sense-retol` el comptava com a to
   SENSE codi, i tenia raó: un codi enganxat al nom ja no es llegeix com un
   codi. `align-items:flex-start` perquè la vinyeta no s'estiri quan el nom
   ocupa dues línies. */
/* Flux normal, NO `flex`. Amb `display:flex` la vinyeta i el nom són dos
   ítems de fila: el nom es queda en una columna estreta al costat i no pot
   embolicar-se per sota de la vinyeta. En flux normal la vinyeta és un
   `inline-block` i el nom l'envolta, que és el que recupera amplada.
   El `margin-right` fa la feina del `gap` que hi havia. */
.ses-tcol-titol { font-size:.95rem; margin-bottom:2px; word-break:break-word; }
.ses-tcol-titol > .ses-cat-codi-vinyeta { margin-right:6px;
  vertical-align:text-bottom; }
/* Client + KPIs fàcils d'obra */
.ses-tcol-client { color: var(--pt-muted); font-size:.82rem; margin:0 0 4px;
  font-weight:600; word-break:break-word; }
.ses-tcol-kpis { display:flex; flex-wrap:wrap; align-items:center; gap:6px;
  font-size:.8rem; margin:2px 0 4px; }
/* `--pt-muted` (#6E6A5E) està calibrat AA contra els fons de PÀGINA
   (`COLORS["muted"]`, comentari propi: "AA 4.5:1 sobre fons clar"), no
   contra `--pt-line` (#E8E4DA), que és més clar: junts donen 4,256:1, sota
   el mínim. `--pt-text` hi dona 12,2:1 (trobat per
   `tests/test_contrast_text.py::
   test_cap_parell_fons_color_declarat_junts_baixa_del_minim_AA`, cp2c,
   22-09-2026). */
.ses-tcol-badge { padding:1px 8px; border-radius:999px; font-weight:600;
  font-size:.76rem; background: var(--pt-line); color: var(--pt-text); }
.ses-tcol-badge-on { background: var(--pt-verd-pastel); color: var(--pt-verd-dark); }
.ses-tcol-ritme { color: var(--pt-verd-dark); font-weight:600;
  font-size:.86rem; margin:2px 0; }
.ses-tcol-sub { color: var(--pt-muted); font-size:.84rem; margin:2px 0; }
.ses-tcol-nota { color: var(--pt-text-ambre); font-size:.8rem; margin:2px 0; }
.ses-tcol-sec { font-size:.74rem; letter-spacing:.05em; text-transform:uppercase;
  color: var(--pt-muted); font-weight:600; margin:10px 0 4px; }
.ses-tcol-cards { display:flex; flex-direction:column; gap:6px;
  min-height:34px; max-height:46vh; overflow-y:auto; padding:2px; }
/* El peu porta DOS blocs (feina del dia + configuració) i han d'anar un sota
   l'altre. En fila es repartien l'amplada de la columna: els camps quedaven a
   130 px amb el text escapçat i el bloc de configuració se n'anava a la dreta,
   fora del flux. Era la causa del que es veia a la captura del 03-09. */
.ses-tcol-peu { display:flex; flex-direction:column; align-items:stretch;
  gap:6px; margin-top:8px; }

/* 19-09-2026 · `flex-shrink:0`, defecte real trobat mesurant l'ample del
   parc a 158px (correcció del gerent). `.ses-tcard` és un ITEM d'un
   contenidor flex EN COLUMNA (`.ses-tcol-cards`, `max-height:46vh;
   overflow-y:auto`): amb `min-height` a un VALOR explícit (44px, no
   `auto`), l'algorisme de flexbox perd la protecció de «mai per sota del
   contingut» que `min-height:auto` donaria de franc, i quan la llista no
   hi cap sencera (427 màquines al banc), el navegador ENCONGIA les
   targetes de contingut llarg fins als 44px del `min-height` — el text
   de més (fins a 5 línies en una targeta real) quedava VISUALMENT TALLAT
   sota la targeta següent (`overflow:visible` el deixava fora de la
   caixa, i el fons opac de la targeta de sota el tapava). Verificat per
   mutació: sense aquesta línia, `offsetHeight` es queda a 44px amb un
   `scrollHeight` de 98px per a la targeta més llarga del banc; amb la
   línia, creix als 108px que demana el contingut. Sense flex-shrink, cap
   targeta de la llista encongeix mai per sota del que necessita. */
.ses-tcard { display:flex; gap:8px; align-items:flex-start; flex-shrink:0;
  background: var(--pt-surface); border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); padding:8px 10px; cursor:pointer; min-height:44px;
  transition: box-shadow .1s ease, border-color .1s ease; }
.ses-tcard:hover { border-color: var(--pt-verd); }
.ses-tcard-sel { border:2px solid var(--pt-verd);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); }
.ses-tcard-cos { display:flex; flex-direction:column; gap:1px;
  font-size:.9rem; min-width:0; word-break:break-word;
  overflow-wrap:anywhere; line-height:1.25; }
.ses-tcard-maq { color: var(--pt-muted); font-size:.84rem; }
.ses-tcard-sub { color: var(--pt-muted); font-size:.8rem; }
/* CP13 (19-09-2026): les hores de la fitxa del PLA, germanes de
   `.ses-tcard-cos` (mai a dins: `seshat.py`, `_targeta`), empeses a la
   dreta de la mateixa línia del nom amb `margin-left:auto` — `.ses-tcard`
   ja és `flex`. `align-self:flex-start` la manté arran de la primera línia
   encara que el nom faci dues línies (noms llargs, terra de 44px). */
.ses-tcard-hores { margin-left:auto; align-self:flex-start; flex-shrink:0;
  white-space:nowrap; font-size:.8rem; font-weight:600;
  color: var(--pt-muted); padding-top:1px; }
.ses-card-drag { touch-action:manipulation; }
.ses-card-drag.ses-movent { opacity:.62; pointer-events:none; position:relative; }
.ses-card-drag.ses-movent::after { content:"Movent…"; font-size:.75rem;
  font-weight:600; margin-left:.4rem; color:var(--pt-muted); }
/* T1f: el bloqueig temporal evita que Sortable tingui una segona operació
   oberta mentre React repinta la primera. */
.ses-moviment-en-vol .ses-dnd, .ses-moviment-en-vol .ses-dnd-origen,
.ses-moviment-en-vol .ses-obres { cursor:wait; }
.ses-moviment-en-vol .ses-card-drag, .ses-moviment-en-vol .ses-tcol-cap {
  cursor:wait !important; }
#ses-dnd-senyal:not([hidden]) { display:inline-block; margin:.3rem 0;
  color:var(--pt-muted); font-size:.82rem; font-weight:600; }
.sortable-ghost { opacity:.4; }
.sortable-drag { box-shadow:var(--pt-elev-3); }

.ses-colbtn { width:100%; border:1px dashed var(--pt-verd);
  background: var(--pt-verd-pastel); color: var(--pt-verd-dark);
  border-radius:var(--pt-radius-sm); padding:8px; font-size:.82rem; font-weight:600;
  cursor:pointer; min-height:44px; margin-top:6px; }
.ses-colbtn:hover { background: var(--pt-verd); color:#fff; }
.ses-btn-est { color: var(--pt-verd-dark); }

.ses-bar { height:8px; background: var(--pt-line); border-radius:var(--pt-radius-sm);
  overflow:hidden; margin:6px 0 2px; }
.ses-bar-fill { height:100%; background: var(--pt-verd); border-radius:var(--pt-radius-sm); }

/* ── SESHAT 2.0 · ronda 1 agents (IDUN r2 + NJORD + FREYA) ──────────────── */
/* DS-S01: nota de calibratge llegible (abans 3.66:1 sobre --pt-soft) */
/* El color d'aquesta nota ja el mana --pt-text-ambre a la seva regla de
   dalt; abans hi havia aqui un hex a pel que la tapava. */
.ses-tcol-nota { font-size:.82rem; font-weight:500; }
/* DS-S02: seleccio tap-tap INEQUIVOCA (halo verd pur + fons tenyit) */
.ses-tcard-sel { border:2px solid var(--pt-verd);
  background: var(--pt-verd-pastel);
  box-shadow:0 0 0 3px rgba(27,94,52,.28); }
/* DS-S02b (18-09-2026, ITERAR queixa 3) · el cercador del tauler
   (`duat_seshat_dnd.js`, `reaplicaCercaRessalt`) reutilitza aquesta MATEIXA
   classe per marcar la COLUMNA d'obra sencera que casa amb la cerca, mai
   una targeta. Sense la regla de sota, la vora/fons quedarien TAPATS pel
   to d'obra (`.ses-tcol:has(> .ses-tcol-cap.ses-obra-to-N)`, més amunt):
   aquella regla és MÉS específica (3 classes) que `.ses-tcard-sel` sola (1
   classe) i guanya la cascada encara que vingui abans al full. Amb
   l'atribut `[data-obra]` de més aquesta regla iguala l'especificitat i,
   venint DESPRÉS, guanya l'empat per ordre. */
.ses-tcol[data-obra].ses-tcard-sel { border-color: var(--pt-verd);
  background: var(--pt-verd-pastel); }
/* DS-S03: drag llegible + zona de desti marcada (:has, no cal JS extra) */
.sortable-ghost { opacity:.35; border-radius:var(--pt-radius-sm); }
.sortable-drag { opacity:1; box-shadow:var(--pt-elev-3); }
.ses-tcol-cards:has(.sortable-ghost) { outline:2px dashed var(--pt-verd);
  outline-offset:3px; background: var(--pt-verd-pastel); border-radius:var(--pt-radius-sm); }
/* DS-S04: track de la barra de progres visible (abans 1.05:1). Els literals
   han passat a token (--pt-track) el 20-08, quan el mateix forat va reapareixer
   a dues barres noves. */
.ses-bar { height:10px; background:var(--pt-track);
  border:1px solid var(--pt-track-vora); }
.ses-bar-fill { border-radius:4px; }
/* Jerarquia tipografica de columna (3 nivells) */
.ses-tcol-sec { font-size:.78rem; }
.ses-tcol-sub { font-size:.85rem; }
.ses-tcol-ritme { font-size:.875rem; font-weight:500; }
/* DS-S05: scroll amb snap + sense conflicte de gestos */
.ses-tauler { scroll-snap-type:x proximity; overscroll-behavior-x:contain; }
.ses-tcol { scroll-snap-align:start; }

/* NJORD/FREYA: la targeta triada i les complementaries HO DIUEN */
.ses-tcard-badge { display:inline-block; background: var(--pt-verd);
  color:#fff; font-size:.76rem; font-weight:600; border-radius:var(--pt-radius-sm);
  padding:2px 8px; margin-top:3px; }
.ses-tcard-lliga { background: var(--pt-blau); }
/* Banner de viatges pendents amb drecera */
.ses-banner-tr { display:flex; align-items:center; gap:6px; flex-wrap:wrap;
  background: var(--pt-surface); border:1px solid var(--pt-warn);
  border-left:4px solid var(--pt-warn); border-radius:var(--pt-radius-sm);
  padding:8px 12px; margin-bottom:10px; font-size:.9rem; }
.ses-btn-goto { color: var(--pt-verd-dark); font-weight:600; }
/* Controls del tauler (obrir obra + portar màquina del catàleg) */
.ses-tauler-ctrls { display:flex; flex-wrap:wrap; gap:10px; margin:6px 0 4px;
  align-items:center; }
.ses-tauler-ctrls .ses-ctrls-cap { flex:0 0 100%; margin:0 0 2px;
  font-weight:600; font-size:.9rem; color: var(--pt-muted); }
.ses-tauler-ctrls .ses-tr-form { flex:1 1 320px; margin:0; }
/* Barra d'agilitat: comptador «sense destí» + cercador global */
.ses-tauler-barra { display:flex; flex-wrap:wrap; align-items:center;
  justify-content:space-between; gap:10px; margin:4px 0 10px; }
.ses-tauler-compt { font-size:.95rem; }
.ses-tauler-compt strong { color: var(--pt-verd-dark); }
/* DS-S10: target tàctil ≥44px (WCAG 2.5.8) */
.ses-tauler-cerca { flex:1 1 260px; max-width:420px; min-height:44px;
  border:1.5px solid var(--pt-line); border-radius:var(--pt-radius-sm); padding:8px 12px;
  font-family:inherit; font-size:.95rem; background: var(--pt-surface); }
/* 18-09-2026 · `.ses-tauler-cerca` (classe, de sobre) cau al `<div>`
   embolcall que posa Dash 4.1 al voltant d'un `dcc.Input`, mai a
   l'`<input>` real —la mateixa cicatriu que ja documenta
   `duat_seshat_dnd.js` pel filtre del cercador—, o sigui que el
   `min-height` d'aquell selector mai arriba a l'element que `--parc-cap-
   tall` mesura de veritat (`input#ses-tauler-cerca`, 26px). L'`id` sí que
   el porta Dash a l'`<input>`: aquí és on cal el terra de 44px. */
#ses-tauler-cerca { min-height:44px; }
.ses-tauler-cerca:focus, .ses-tauler-cerca:focus-visible { outline:none;
  border-color: var(--pt-verd); box-shadow:0 0 0 3px var(--pt-verd-pastel); }
/* El bloc de 600px que hi havia aquí (barra en columna + cercador al 100%) va
   al bloc de mòbil de sota, fusionat: tenir-ne dos que fan el mateix a dos
   llindars diferents era la mateixa duplicació que aquesta tanda ha tret de
   `.ses-tcol`. I portava un defecte que ningú havia mesurat, explicat allà. */
/* Configuració plegada (un sol cop, fora del flux diari) */
.ses-config { margin-top:14px; border:1px solid var(--pt-line);
  border-radius:var(--pt-radius); background: var(--pt-surface); }
.ses-config[open] { padding-bottom:6px; }
.ses-config-sum { cursor:pointer; padding:12px 16px; font-weight:600;
  color: var(--pt-verd-dark); list-style:none; display:flex;
  align-items:center; }
.ses-config-sum::-webkit-details-marker { display:none; }
/* DS-S11: chevron CSS que rota (affordance d'estat clar) + focus visible */
.ses-config-sum::before { content:""; display:inline-block; width:0; height:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:4px solid var(--pt-verd-dark); margin-right:9px;
  transition:transform .2s ease; }
.ses-config[open] .ses-config-sum::before { transform:rotate(90deg); }
.ses-config-sum:focus-visible { outline:none; border-radius:var(--pt-radius);
  box-shadow:0 0 0 3px var(--pt-verd-pastel); border-color: var(--pt-verd); }
.ses-config .pt-section, .ses-config section { margin:0 8px 6px; }

/* ── El selector de màquines del parc (04-09-2026) ──────────────────────────
   «Carrega totes les màquines que tenim i fica-ho per categories, de tal forma
   que seleccionis per exemple el Dario i després giratòries i la 310.»

   Reutilitza `.ses-config`, que ja és el patró de plec de la casa: un patró
   nou aquí voldria dir dues fletxes diferents a la mateixa pàgina. */

/* El camp del cercador + el botó «×» que el buida (PLA 16-09-2026, punt 5).
   `.ses-cerca-camp` embolcalla el `dcc.Input`
   (`_embolcalla_cerca_amb_neteja` a seshat.py).
   19-09-2026 · correcció del gerent: viu ara dins de `.ses-tauler-barra`
   (abans, dins de `.ses-parc-ctrls`, retirat — el parc ja no porta cap
   comandament). `order:-1` el manté PRIMER dins de la barra, com demanava
   el pla quan encara vivia al parc; `flex`/`max-width` copien els de
   `.ses-tauler-cerca` d'abans del 04-09 perquè, en una barra AMPLA, no
   s'estiri al 100% com feia dins de la columna estreta. */
.ses-cerca-camp { position:relative; order:-1; flex:1 1 260px;
  max-width:420px; }
.ses-cerca-camp .ses-tauler-cerca { width:100%; }
.ses-cerca-neteja { position:absolute; right:4px; top:50%;
  transform:translateY(-50%); width:44px; height:44px; min-width:44px;
  /* 18-09-2026 · era 36x36: el comentari vell deia que el `padding`
     arribava als 44px reals de toc, però amb `box-sizing:border-box`
     (regla global, `:root`) `width`/`height` FIXES ja inclouen el
     padding — la caixa real es quedava a 36px, mesurat per
     `--parc-cap-tall` («BAIX»). Es puja la caixa sencera. */
  padding:4px; border:1px solid var(--pt-line); border-radius:999px;
  background: var(--pt-surface); color: var(--pt-muted); font-size:1.1rem;
  line-height:1; cursor:pointer; display:flex; align-items:center;
  justify-content:center; }
.ses-cerca-neteja::before { content:""; position:absolute; inset:-4px; }
.ses-cerca-neteja:hover { background: var(--pt-soft); color: var(--pt-text); }
.ses-cerca-neteja:focus-visible { outline:none;
  box-shadow:0 0 0 3px var(--pt-verd-pastel); border-color: var(--pt-verd); }

/* Les categories, encaixades: el marge de 14 px de `.ses-config` entre dotze
   blocs són 168 px de res. */
.ses-maq-selector { margin-top:10px; }
/* Els altres dos nivells d'aquest mateix bloc ja declaren els 44 px (DS-S10);
   aquest, que és l'entrada a les 82 màquines, se'ls havia deixat a l'atzar de
   la mida de lletra heretada. */
.ses-maq-selector > .ses-config-sum { min-height:44px; display:flex;
  align-items:center; touch-action:manipulation; }
/* La sagnia és l'única pista que les 12 categories viuen DINS del desplegable
   general: amb 6 px i mig gruix de lletra de diferència no es distingia el
   pare del fill baixant de pressa. */
.ses-maq-cats { padding:0 6px 4px 14px; }
.ses-maq-cat { margin-top:4px; }
.ses-maq-cat > .ses-config-sum { padding:10px 12px; min-height:44px;
  display:flex; align-items:center; gap:6px; font-weight:500;
  touch-action:manipulation; }
.ses-maq-emoji { font-size:1.05rem; line-height:1; }

.ses-maq-files { display:flex; flex-direction:column; padding:2px 6px 6px; }
/* Cada màquina és un BOTÓ, no un div clicable: així el teclat hi arriba sol i
   el lector de pantalla diu que es pot prémer. Àrea de toc de 44 px, que és
   amb el dit i a l'obra que es farà servir.
   `flex-wrap` perquè la columna del parc fa ~240 px i, restats els encoixinats,
   en queden ~196 de text útil: amb un nom llarg («Hidromek 310 · nº1») més la
   matrícula més l'etiqueta, els `span` embolicaven cadascun pel seu compte i
   la fila quedava de dues o tres línies desiguals. I justament passava a la
   fila recomanada, que és l'única que l'usuari té garantit veure sense tocar
   res. Ho va trobar el judici cec d'IDUN. */
.ses-maq-fila { display:flex; align-items:center; gap:8px; width:100%;
  flex-wrap:wrap; row-gap:2px;
  min-height:44px; padding:6px 10px; text-align:left; cursor:pointer;
  border:1px solid transparent; border-radius:var(--pt-radius);
  background:none; color:inherit; font:inherit;
  /* Sense això, cada toc en tauleta paga el retard de doble toc del navegador;
     és el mateix que ja fa `.ses-card-drag`. */
  touch-action:manipulation; }
.ses-maq-fila:hover { background:var(--pt-soft); }
.ses-maq-fila:focus-visible { outline:2px solid var(--pt-verd);
  outline-offset:-2px; }
.ses-maq-mat { font-size:.78rem; color:var(--pt-muted);
  font-variant-numeric:tabular-nums; }

/* La que aquella persona sol portar. El color NO va sol: porta el text «la que
   sol portar» al costat, perquè una vora verda tota sola no diu per què aquella
   fila és diferent de les altres 81.
   Els tokens són els REALS de la casa (`--pt-soft`, `--pt-verd-pastel`). Abans
   deien `--pt-bg-soft` i `--pt-verd-soft`, que no existeixen enlloc: el
   navegador es quedava sempre amb el valor de reserva i aquests dos colors
   quedaven fora del sistema, immunes a qualsevol canvi de paleta. Ara ho
   vigila `tests/test_tokens_de_color_existeixen.py`. */
.ses-maq-rec { border-color:var(--pt-verd); background:var(--pt-verd-pastel); }
/* L'etiqueta va a LÍNIA PRÒPIA (`flex-basis:100%`) en comptes d'empènyer-se a
   la dreta amb `margin-left:auto`: així el nom i la matrícula es queden junts
   en una línia i l'etiqueta no s'hi barreja quan el nom és llarg. */
.ses-maq-rec-txt, .ses-maq-sel-txt { flex-basis:100%; margin-left:0;
  text-align:right; font-size:.72rem; font-weight:600;
  text-transform:uppercase; letter-spacing:.04em;
  color:var(--pt-verd-dark); }

/* La que acabes de TRIAR. És un estat diferent de «la que sol portar»: aquella
   es calcula al render i no depèn de cap toc. Es fa amb la vora de 2 px de
   `.ses-tcard-sel`, que és el que ja diu «triada» a la resta del tauler. */
.ses-maq-sel { border:2px solid var(--pt-verd);
  background:var(--pt-verd-pastel); }
/* El focus de la fila recomanada NO pot ser del mateix color que la seva vora
   permanent: qui hi arriba amb el tabulador no veuria res de nou. */
.ses-maq-rec:focus-visible, .ses-maq-sel:focus-visible {
  outline-color:var(--pt-blau); }

/* Panell d'avisos: jerarquia semàfor (DS-S14) */
.ses-av-panell { border-top:3px solid var(--pt-ambre-fosc); }
.ses-av-panell.ses-av-tot-ok { border-top-color: var(--pt-verd);
  background: var(--pt-verd-pastel); }
.ses-av-cap { font-size:1rem; }
/* Tancament en lot */
.ses-tanca-lot { display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin:0 0 12px; padding:10px 12px; border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); background: var(--pt-surface); }
/* Banner de transport en vermell (error operacional) */
.ses-banner-tr-r { border-color: var(--pt-warn); border-left-color: var(--pt-warn); }
/* DS-S13: text operatiu de targeta a 14px mínim (llegibilitat) */
.ses-tcard-sub { font-size:.875rem; }
/* DS-S12: track de la barra de progrés amb contrast ≥3:1 (WCAG 1.4.11) */
.ses-bar { background:#7E7568; }
/* FREYA: el feedback acompanya l'scroll */
.ses-fb-sticky { position:sticky; top:8px; z-index:60; }
.ses-fb-sticky > div { box-shadow:0 4px 14px rgba(28,26,23,.18); }
/* Boto del parc diferenciat del de les obres (evitar el toc equivocat) */
.ses-colbtn-parc { border-color: var(--pt-blau); background: var(--pt-blau-pastel);
  color: var(--pt-blau); }
.ses-colbtn-parc:hover { background: var(--pt-blau); color:#fff; }

/* ── El quadre de planificació al MÒBIL ─────────────────────────────────────
   Mesurat el 03-09-2026 al banc amb el volum real del gerent (25 obres, 61
   assignacions) a 390x844: la primera columna d'obra era al píxel **1.994**, i
   cap obra es veia sencera sense lliscar de costat. El barem de mòbil de la
   casa (`docs/baremoteca/tauler-kpis-mobil-grafana.png`) posa la primera dada
   a ~310 px.

   El que se'ls menjava, per ordre: el paràgraf d'entrada, quatre indicadors en
   graella, la cua de revisió d'hores i els controls del tauler. Cap d'aquestes
   coses és per a què obre el mòbil A L'OBRA: hi obre per veure qui va on.

   Àmbit `.ses-pagina` a posta: `_modbase` el comparteixen les dotze pantalles.

   Una sola regla per classe: abans n'hi havia DUES dins d'aquest mateix
   breakpoint (`.ses-tcol` a 84vw i a 78vw) i manava la segona, així que qui
   llegia la primera creia que tocava el que es veu i no tocava res. */


/* ── L'ESPAI EN BLANC DEL PC ─────────────────────────────────────────────────
   El gerent (04-09-2026): «a la vista en PC hi ha molts espais en blanc».
   Mesurat a 1680 px: la pàgina feia 4.594 px d'alt i CADA bloc de context
   ocupava una banda de 1.636 px d'ample per ensenyar-hi una o dues línies —
   els moviments, «qui és qui», «per resoldre», les hores per revisar, els
   avisos i la configuració, un sota l'altre.

   El que mana (el dia, la gestió de les obres, el quadre) es queda a tota
   l'amplada, que és on el necessita. La resta va a dues columnes: el mateix
   contingut, la meitat d'alçada, i cap scroll de més per arribar-hi.

   Només a partir de 1200 px: per sota no hi caben dues columnes de context
   sense escanyar-les, i allà ja mana el disseny d'aparell. */
/* La graella de dues columnes per al context es va PROVAR i es va treure el
   mateix dia: mesurada a 1680 px, la pàgina passava de 4.594 px a 5.074. En
   dues columnes cada fila val el que val el bloc més alt, i el text embolicat
   a mitja amplada creix més del que s'estalvia. El que ocupava de veritat era
   una altra cosa i la mesura ho deia: la taula d'avenç, 1.266 px per dir
   «sense pressupost a l'ERP» a cada fila. */

/* El paràgraf d'entrada explica QUÈ FA l'eina, i qui l'obre ho sap: la fa
   servir cada dia. Segueix sencer dins del «?». Al PC també: era el primer que
   el gerent va marcar com a text que no necessita. */
.ses-pagina .pt-mod-lead { display:none; }
/* Les instruccions d'ús («toca una targeta i després Posar aquí») també al PC:
   el gerent les va marcar totes com a text que no necessita, i qui obre l'eina
   la fa servir cada dia. Segueixen senceres dins del «?». */
.ses-pagina .ses-com-va { display:none; }

/* Els controls d'afegir al tauler s'estiraven fins a l'altra punta de la
   pantalla: a 1680 px els desplegables quedaven a 400 px els uns dels altres i
   el botó, sol al mig del no-res. És l'espai en blanc que el gerent va marcar.
   Es tanquen en columnes de mida humana i el que sobra queda a la dreta, que
   és millor que repartir-ho entre els controls. */
/* La graella va al CONTINGUT, no al `Details`. Posada al `Details` mateix, el
   resum passava a ser una cel·la de graella i el bloc plegat feia 98 px en
   comptes de 50: el doble, per no res. */
@media (min-width: 1000px) {
  .ses-pagina .ses-ctrls-graella { display:grid;
    grid-template-columns:repeat(auto-fit,minmax(17rem,20rem));
    justify-content:start; gap:10px 16px; align-items:start; }
  .ses-pagina .ses-ctrls-graella > .ses-ctrls-cap { grid-column:1/-1; margin:0; }
  .ses-pagina .ses-ctrls-graella .ses-tr-form { flex-wrap:wrap; }
}

/* ── CADA VISTA, EL SEU TO ───────────────────────────────────────────────────
   El gerent (04-09-2026): «les vistes són molt importants però et perds.
   Potencia aquesta idea. Jo ficaria una targeta de cada color i que al canviar
   de vista es canviés el color de la base de treball també».

   **El que diu la mesura, i s'ha de dir.** La casa té un terra de separació
   perceptual de 15 (`config.separacio`, OKLab×100) per als colors que
   informen TOT SOLS — és el que va fer fora l'argila el 20-08. Amb set vistes
   aquest terra NO s'assoleix: mesurat, el màxim amb set tons sobris és **10,5**
   (la parella que lliga és tauler/màquina), i amb sis, 15,1. Provat també
   optimitzant per separació pura: en surten set colors que passen el terra
   però són de festa major, i aquesta casa no és així.

   Per què es fa igualment: **aquests tons no informen sols**. La regla escrita
   de la casa és «el color no informa tot sol — mana el rètol», i aquí el rètol
   hi és tres vegades: la pastilla porta icona i nom, la capçalera del quadre
   repeteix icona i nom, i la pregunta de la vista està escrita a sota. El to
   serveix per saber de reüll que has canviat de vista, no per saber a quina
   ets. Si algun dia el to s'hagués de fer servir com a única marca d'alguna
   cosa, aquesta decisió s'ha de refer.

   Cap dels set trepitja les franges reservades: el vermell vol dir perill i
   l'ambre vol dir avís, i això no es toca. */
.ses-pagina .ses-vista { --ses-vista:var(--pt-verd); --ses-vista-suau:var(--pt-verd-pastel); }
.ses-pagina .ses-vista-tauler      { --ses-vista:#1B5E34; --ses-vista-suau:#ECF6F0; }
.ses-pagina .ses-vista-treballador { --ses-vista:#2466A8; --ses-vista-suau:#ECF1F6; }
.ses-pagina .ses-vista-obra        { --ses-vista:#6A3A9E; --ses-vista-suau:#F1ECF6; }
.ses-pagina .ses-vista-maquina     { --ses-vista:#0E7A6E; --ses-vista-suau:#ECF6F5; }
.ses-pagina .ses-vista-transport   { --ses-vista:#A02A78; --ses-vista-suau:#F6ECF3; }
.ses-pagina .ses-vista-tancament   { --ses-vista:#1C1C5E; --ses-vista-suau:#ECECF6; }
/* `categoria` (CP7): oliva. Triat MESURANT, no a ull — to 75°, o sigui ni
   vermell (<=18 o >=352) ni ambre (28-52), que és el que la porta prohibeix;
   5,83:1 sobre blanc; i la separació més curta amb les altres set vistes és
   8,8 (contra el verd de marca), en línia amb el que ja hi havia (amb set
   tons el màxim assolible era 10,5). */
.ses-pagina .ses-vista-categoria   { --ses-vista:#5C6B2F; --ses-vista-suau:#F0F2E8; }
.ses-pagina .ses-vista-informe     { --ses-vista:#454B57; --ses-vista-suau:#EFF0F3; }

/* La BASE DE TREBALL canvia de to amb la vista. És el que va demanar: que es
   vegi que has canviat de lloc sense haver de llegir res. */
.ses-pagina .ses-vista {
  background: var(--ses-vista-suau); border-radius: var(--pt-radius);
  padding: 10px 12px 14px; }
.ses-pagina .ses-vista .ses-tauler-wrap { background: transparent; }

/* La capçalera de la vista: icona, NOM i la pregunta que respon. El nom va en
   el to de la vista; la pregunta, en gris, que és context i no titular. */
.ses-vista-cap { display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
  padding:2px 2px 8px; margin-bottom:8px;
  border-bottom:1px solid rgba(0,0,0,.07); }
.ses-vista-icona { font-size:1.05rem; }
.ses-vista-nom { color: var(--ses-vista); font-size:1.02rem; letter-spacing:.01em; }
.ses-vista-pregunta { color: var(--pt-muted); font-size:.88rem; }

/* Les pastilles de vista, una de cada color. L'ordre segueix la llista
   `VISTES` de `seshat.py` i hi ha una prova que ho vigila: si algú n'afegeix
   una al mig, els colors ballarien sense que res es queixés. */
.ses-pagina .ses-vistes > label:nth-of-type(1) { --c:#1B5E34; }
.ses-pagina .ses-vistes > label:nth-of-type(2) { --c:#2466A8; }
.ses-pagina .ses-vistes > label:nth-of-type(3) { --c:#6A3A9E; }
.ses-pagina .ses-vistes > label:nth-of-type(4) { --c:#0E7A6E; }
.ses-pagina .ses-vistes > label:nth-of-type(5) { --c:#A02A78; }
.ses-pagina .ses-vistes > label:nth-of-type(6) { --c:#1C1C5E; }
.ses-pagina .ses-vistes > label:nth-of-type(7) { --c:#5C6B2F; }
.ses-pagina .ses-vistes > label:nth-of-type(8) { --c:#454B57; }
.ses-pagina .ses-vistes .ses-chip { color: var(--c); border:1px solid var(--c);
  background: var(--pt-surface); border-radius: var(--pt-radius-sm);
  /* 17-09-2026: aquí hi havia `min-height:38px`. Per ser més específica
     que `.ses-chip` guanyava, i el xip de les vistes mesurava 38px
     computats al navegador —per sota del terra de 44 que `DESIGN.md`
     exigeix a TOT element tocable. El va caçar agent-santi mesurant la
     caixa renderitzada, no el fitxer: treure la declaració duplicada de
     `.ses-chip` no va canviar res perquè el valor no venia d'allà. */
  padding:6px 12px; min-height:44px; display:inline-flex; align-items:center; }
.ses-pagina .ses-vistes label.selected .ses-chip { background: var(--c);
  color:#fff; font-weight:600; }
/* El rodonet del radio no aporta res quan la pastilla ja diu si està triada,
   però `display:none` el treu del TABULADOR i deixa el selector de vistes
   inservible sense ratolí. Mesurat el 04-09: els set radios quedaven a 0x0, no
   acceptaven el focus i amb 60 tabulacions no s'hi arribava. Ho va trobar la
   lent de la porta de revisió, no jo.
   S'amaga a la vista i es queda al teclat: l'`input` segueix al flux, enfocable
   i llegible per un lector de pantalla, i el focus es veu sobre la pastilla. */
.ses-pagina .ses-vistes .dash-options-list-option-wrapper {
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; }
.ses-pagina .ses-vistes label:focus-within .ses-chip {
  outline:2px solid var(--c); outline-offset:2px; }

/* CONTROL (santi #3, ja demanat a l'ENCARREC punt 3): l'interruptor
   Graella/Detall ha de seguir el MATEIX patró de casa que el selector de
   vistes bessó (`.ses-vistes`, línies 900-916) — sense aquestes 3 regles el
   radi natiu es veu sencer i lila, apilat sobre la icona i el rètol
   (`opacity:1, position:static`, mesurat en viu). Selector propi
   (`.ses-densitat-sel`), definit un sol cop: mateixes 3 regles, mai la base
   de `.ses-chip`. Un sol color de marca (verd fosc), no calen 7 tons perquè
   només hi ha dues opcions. */
.ses-pagina .ses-densitat-sel { margin-left:auto; flex:0 0 auto; }
.ses-pagina .ses-densitat-sel .ses-chip { color: var(--pt-verd-dark);
  border:1px solid var(--pt-verd-dark); background: var(--pt-surface);
  border-radius: var(--pt-radius-sm); padding:6px 12px; min-height:44px;
  display:inline-flex; align-items:center; }
.ses-pagina .ses-densitat-sel label.selected .ses-chip {
  background: var(--pt-verd-dark); color: var(--pt-sobre-marca);
  font-weight:600; }
/* `position:static`, NO `absolute` com a `.ses-vistes` (línia 912): aquí
   l'interruptor viu al marge dret (`margin-left:auto`) i un `position:
   absolute` sense cap avantpassat posicionat proper es col·loca a la seva
   posició ESTÀTICA original —a la vora dreta, x≈1444 en un viewport de
   1366— fora de la caixa. En enfocar-lo (clic), el navegador desplaçava la
   PÀGINA sencera 192 px per ensenyar-lo (`scrollX` 0→192, mesurat en viu).
   Quedant-se AL FLUX però a mida zero, l'enfocament no mou res. */
.ses-pagina .ses-densitat-sel .dash-options-list-option-wrapper {
  position:static; width:0; height:0; overflow:hidden; padding:0;
  margin:0; border:0; white-space:nowrap; }
.ses-pagina .ses-densitat-sel label:focus-within .ses-chip {
  outline:2px solid var(--pt-verd-dark); outline-offset:2px; }

/* Xips del resum de recursos (nom de treballador/màquina) i «N persones · M
   màquines»: NOMÉS existeixen a la cel·la compacta del mode Graella. Amagats
   per defecte perquè el mode Detall no ha de canviar gens (PLA 16-09-2026,
   supòsit 2). */
.ses-tcol-recompte { display:none; }
.ses-tcol-resum { display:none; }

/* ── SESHAT · MODE GRAELLA (densitat del tauler a escriptori) ────────────────
   PLA 16-09-2026: les ~25 obres del dia de cop, amb comptador i almenys un
   nom, i un clic que obre el detall complet (`ses-oberta`, acordió: una sola
   alhora). Cap component surt del DOM —la classe `ses-graella` sobre
   `.ses-pagina` (embolcall ESTABLE, Dash no el re-renderitza) només amaga i
   redistribueix— i les 4 classes DEUTE (`ses-tcol-ritme`, `ses-bar`,
   `ses-tcol-sec`, `ses-tcol-sub`, exemptes a `test_css_una_sola_vegada.py`)
   es toquen NOMÉS amb selector compost: mai es redefineix la seva base.

   Des de 769px: per sota, el mode LLISTA del mòbil (setembre) ja resol el
   mateix problema amb una tècnica pròpia i no s'hi toca res. */
@media (min-width: 769px) {
  /* ── El CARRIL FIX (PLA 16-09-2026) ─────────────────────────────────────
     `.ses-tauler` és SEMPRE (graella i detall, des de 769px) una graella
     de DUES columnes: el parc (250px, fix) i `.ses-obres` (tota la resta:
     trasllats + columnes d'obra). Compartit entre els dos modes perquè el
     pla ho demana igual als dos («Detall: same two-column shell») — el que
     canvia entre modes és NOMÉS el `display` de `.ses-obres`, més avall.
     Amb `display:grid` i UNA sola fila implícita, `align-items:stretch`
     (el valor per defecte de grid) ja alinea el top i el bottom del parc
     amb els de `.ses-obres` sense cap regla extra — és el que mesura
     `sonda_graella_planificacio.py --parc-fix`. I com que el parc viu FORA
     de `.ses-obres` (l'únic que llisca en Detall), no li cal `position:
     sticky`: estar-ne fora ja el manté fix. */
  /* 19-09-2026 · 290px → 158px, mateix motiu i mesura que `.ses-tcol-parc`
     de sota (correcció del gerent: buidat el lateral, el parc torna a
     l'ample d'una vinyeta d'obra).
     19-09-2026 ~19:19 (R2) · 158px → 240px, mateix motiu que
     `.ses-tcol-parc` de sota: aquella raó (coincidir amb la vinyeta
     tancada) queda superada per l'ordre d'ara («3 desplegables (...)
     amplia horitzontalment»). Els DOS números s'han de moure ALHORA —
     `test_tauler_es_una_graella_de_dues_columnes_des_de_769` ho vigila. */
  /* 19-09-2026 · El trajecte d'un trasllat, RETALLAT — i NOMÉS aquí dins.
     Escrites globals, agent-santi (porta FINAL) va caçar que **al mòbil no
     hi ha hover**: el text sencer viu al `title` de la targeta i amb el dit
     no s'hi arriba. Al mòbil tampoc calen —el parc es dissol i la targeta té
     l'amplada de la pantalla—; el problema que arreglen (la línia «de X → Y»
     partida en set trossos d'una paraula) és del carril estret, i el carril
     només existeix per sobre de 768.
     I van DINS d'aquest bloc, no en un de nou: obrint un `@media
     (min-width:769px)` propi més amunt, la prova que vigila que el tauler
     sigui una graella de dues columnes mirava el PRIMER bloc d'aquest rang
     i hi topava abans d'arribar al de la graella. Una regla correcta al
     lloc equivocat també trenca coses. */
  .ses-parc-mitat-tr .ses-tr-ruta { display:-webkit-box; -webkit-line-clamp:2;
    -webkit-box-orient:vertical; overflow:hidden; }
  .ses-parc-mitat-tr .ses-tr-gond { display:-webkit-box; -webkit-line-clamp:1;
    -webkit-box-orient:vertical; overflow:hidden; }
  .ses-parc-mitat-tr .ses-tcard-tit { display:-webkit-box; -webkit-line-clamp:1;
    -webkit-box-orient:vertical; overflow:hidden; }
  .ses-pagina .ses-tauler { display:grid; grid-template-columns:240px 1fr;
    align-items:stretch; gap:var(--pt-space-3); overflow-x:visible; }
  .ses-pagina .ses-obres { min-width:0; }

  /* DETALL: `.ses-obres` és la fila que llisca, tal com abans ho feia
     `.ses-tauler` sencer (quan el parc encara hi vivia a dins com una
     columna més). El parc es queda quiet: el pla ho demana i aquí ja no
     cal cap truc, perquè el parc no és fill de qui llisca. */
  .ses-pagina.ses-detall .ses-obres { display:flex; gap:12px;
    align-items:flex-start; overflow-x:auto; padding-bottom:10px;
    overscroll-behavior-x:contain; }

  /* GRAELLA: `.ses-obres` és la quadrícula compacta — abans ho era
     `.ses-tauler` sencer. Per defecte (fins a 1200px, tauleta 1024 inclosa)
     columnes de 150px SENSE el resum de xips («quan no hi cap, ho diu»:
     només el comptador); a partir de 1201px (escriptori) 170px i amb els
     xips. El llindar de la roda de xips és a sota. */
  /* 18-09-2026 · GRAELLA D'UNITATS de 12 columnes. Abans era `auto-fit`, que
     decidia el navegador segons l'amplada: amb això una targeta no es pot
     col·locar en una casella concreta, perquè la casella canviava de mida i
     de nombre a cada pantalla. Amb 12 unitats fixes, una obra ocupa 2 (sis
     per fila) i l'oberta 4, i el servidor pot dir «aquí ja n'hi ha una»
     sense saber què ha pintat el navegador.
     Les obres SENSE casella desada no porten `grid-column` i el navegador
     les col·loca soles al primer forat, que és el que volem fins que algú
     les mogui. */
  /* 18-09-2026 · FILA FIXA (queixa 1, `--buit-vertical`; maqueta de Codex,
     CP1: `MAQUETA-codex-2026-09-17/maqueta.html`, `.board{grid-auto-rows:
     80px}`). El defecte no era la graella de columnes —les targetes ja
     queien a la casella (x,y) correcta— sinó que CADA FILA es dimensionava
     a la targeta MÉS ALTA que hi queia, encara que fos d'una altra
     columna: sense `grid-auto-rows` declarat el valor per defecte és
     `auto` (mida de contingut), i dues targetes a files consecutives de la
     MATEIXA columna no es toquen si la fila de la primera s'ha estirat per
     la veïna. Amb l'alçada FIXA, cap fila la pot estirar ningú.
     El número (93px) surt de MESURAR la targeta TANCADA real del banc
     (`.ses-tcol-cap` amb títol+client+recompte+resum, mode Graella,
     28 obres, 1366 i 1920 — el mateix a totes dues resolucions), no de
     copiar els 80px de la maqueta (aquella tenia menys línies per targeta).
     Perquè la mesura fos CONSTANT calia una segona correcció, vista sota
     (`.ses-tcol-resum{min-height}`): sense ella, una obra sense cap
     recurs assignat feia 69px en lloc de 93 i la fila de sota tornava a
     deixar 24px de blanc — el mateix defecte, ara DINS de la caixa en
     lloc d'ENTRE columnes.
     Les targetes TANCADES ocupen sempre 1 fila (`grid-row:var(--ses-y)`,
     span implícit 1) perquè totes fan la mateixa alçada; els trasllats i
     la targeta OBERTA -que no- porten el seu propi span, més avall. */
  /* `--ses-fila-px` (18-09-2026, MITJANA de Fable): abans era
     `calc(93px + var(--pt-space-1))`, i `getComputedStyle` NOMÉS avalua un
     `calc()` sobre una custom property REGISTRADA (`@property`) — sense
     registrar, torna la cadena LITERAL `"calc(93px + 4px)"`, `parseFloat`
     hi llegeix NaN i el JS (`dnd.js:150`/`:511`) queia sempre al `|| 97`
     clavat. El comentari que deia «només hi ha UN lloc que sap el número»
     era fals: n'hi havia dos i només un funcionava.
     Via triada: VALOR JA RESOLT per cada rang de `@media` (l'altra opció
     era `@property`), perquè no calgui dependre que el navegador el sàpiga
     registrar i perquè el número seguís sortint d'aquí (fila + gap
     D'AQUEST rang), mai d'un duplicat inventat. A tauleta (769-1200,
     `gap:3px` sota) es torna a escriure al costat del `gap` que el deriva
     — la MATEIXA parella «dos números que han de coincidir», ara els dos
     junts i vigilats a la vista, no un aquí i l'altre 300 línies avall. */
  .ses-pagina.ses-graella .ses-obres { display:grid; position:relative;
    grid-template-columns:repeat(12, minmax(0, 1fr));
  /* 19-09-2026 · 93→114 i 69→90. Els dos números són MESURATS de nou, no
     ajustats a ull: la targeta tancada ha crescut perquè el títol passa a
     tenir dues línies fixes (el gerent: «el nom de les obres no es veu bé»).
     Amb la fila vella, cada cel·la trepitjava la de sota **17px** a
     l'escriptori i **18px** a la tauleta —«no es veu bé la part de baix del
     quadre de la obra»—, i això no ho veia cap sonda: `--forats-amb-oberta`
     donava 0 igualment perquè mira CASELLES buides, no encavalcament.
     `--ses-fila-px` és fila+gap i el JS l'hi llegeix: si un canvia, l'altre
     també. Ho vigila `--cel-les-encavalcades`. */
    /* La coordenada y continua sent el número de fila desat, però una fila
       ja no pot retallar el seu contingut: cada pista té un terra de 80px i
       creix amb la targeta més alta. El JS llegeix les pistes computades,
       no assumeix `--ses-fila-px` per convertir el punter en y. */
    grid-auto-rows:minmax(80px, auto); --ses-fila-px:84px; --ses-ample-oberta:6;
    grid-auto-flow:row dense;
    align-items:start; align-content:start; gap:var(--pt-space-1);
    border:1px dashed var(--pt-line); border-radius:14px; padding:8px;
    background-color:var(--pt-soft);
    background-origin:content-box;
    background-image:
      linear-gradient(var(--pt-line) 1px, transparent 1px),
      linear-gradient(90deg, var(--pt-line) 1px, transparent 1px);
    background-size:calc(100%/12) var(--ses-fila-px);
    background-position:0 0; }
  /* La quadrícula de fons (mateix patró que la maqueta: dos `linear-
     gradient` d'1px) ENSENYA les caselles lliures — mitja queixa 1 del
     gerent («no les puc deixar a qualsevol lloc còmodament»): l'altra
     meitat és que hi càpiguen forats a posta, que ja feia la graella
     d'unitats des del 17-09. És només decoració (`background-image`, mai
     un element del DOM): no la mesura cap sonda i no interfereix amb el
     drag.
     18-09-2026 · BAIXA de Fable: `background-size`/`background-position`
     amb l'origen per defecte (`padding-box`) resolen el `100%` sobre la
     caixa AMB padding (8px als 4 costats), i el vell `calc((100% - 8px)/12)`
     només en descomptava LA MEITAT — mai coincidia amb els carrils reals
     de `grid-template-columns`, que sempre es calculen sobre la caixa de
     CONTINGUT (sense padding). Amb `background-origin:content-box`, el
     `100%` ja és exactament aquesta mateixa caixa: la mateixa referència
     que fa servir el grid, sense haver de descomptar res a mà (ni 8px ni
     16px) ni desplaçar la posició. */
  .ses-pagina.ses-graella .ses-obres > .ses-tcol:not([data-x]) {
    grid-column:span 2; }
  /* La targeta col·locada rep la casella per variable (`_casella()` a
     seshat.py). En línia no servia: un `style` guanya sobre el full i la
     regla que l'eixampla en obrir-se no hi podia arribar. */
  .ses-pagina.ses-graella .ses-obres > .ses-tcol[data-x] {
    grid-column:var(--ses-x) / span 2; grid-row:var(--ses-y); }
  /* Trasllats: SENSE casella (mai `data-x`), sempre visible i mai
     compacte (PLA punt 7). Amb la fila fixa necessita el seu propi span
     de files —el seu contingut (títol + llista de moviments + formulari)
     no cap en 93px— calculat en VIU per `apilaTrasllats()`
     (`duat_seshat_dnd.js`) a partir de l'alçada real que porta; `span 3`
     aquí és NOMÉS el valor de sortida abans que el JS corri (evita que
     es vegi tallat un instant al primer pintat). */
  .ses-pagina.ses-graella .ses-obres > .ses-tcol-tr {
    grid-row:span var(--ses-tr-span, 3); }
  /* CONTROL (coordinador, 16-09-2026): `align-content` per defecte
     («normal») es comporta com `stretch` en una graella — un cop el parc
     va deixar de clipar-se i el seu contingut real (10+4 targetes) el va
     fer més alt que les 5 files d'obres, `align-items:stretch` de
     `.ses-tauler` va estirar `.ses-obres` a l'alçada del parc (921px) i,
     SENSE `align-content:start`, les seves pròpies files —de mida `auto`—
     es repartien aquell sobrant a parts iguals: 124px entre files en lloc
     dels 98px naturals (93px de cel·la + 5px de gap), i la 5a fila queia
     a y=754, fora del viewport. Amb `align-content:start` les files es
     queden EMPAQUETADES a dalt de tot i el sobrant es queda sota, sense
     ús — mai empenyent res fora de la pantalla. */
  /* 17-09-2026 · LA BANDA BLANCA. El comentari de sobre ho deixava escrit:
     amb `align-content:start` «el sobrant es queda sota, sense ús». Mesurat
     el 17-09 amb el parc real: `.ses-obres` feia 1024x1095 amb 350px de
     contingut — 745px de blanc, el 68% del rectangle. El gerent va mirar la
     pantalla i el primer que va dir va ser que hi havia espais buits.
     La causa NO era `auto-fill` (canviar-lo a `auto-fit` no va moure el
     número ni un decimal): és que `.ses-tauler` estira les seves DUES
     columnes a la més alta, i el parc —amb 42 treballadors lliures— és molt
     més alt que les obres.
     L'arranjament no toca les files (allò ja ho resol `align-content:start`
     i la 5a fila no ha de tornar a caure fora): treu l'estirada i acota el
     parc a la finestra amb scroll propi. El parc ja té cercador a dalt i
     fora de la zona que llisca, o sigui que no perd res.
     Mesurat amb la sonda `sonda_compacitat_planificacio.py`, que compta
     obres senceres sense scroll I forats: les dues alhora, perquè inflar
     les targetes guanya la segona i PERD la primera. */
  .ses-pagina.ses-graella .ses-tauler { align-items:stretch; }
  /* 19-09-2026 · QUI LLISCA ÉS LA LLISTA, NO EL CARRIL. Amb `overflow-y:auto`
     aquí, els tres blocs es mesuraven pel seu contingut i el carril s'estirava
     per dins: treballadors 319px + màquines 670px (12 capçaleres de categoria
     PLEGADES) deixaven el rètol «🚚 Trasllats» a y=1341 dins d'un carril que
     només en pinta 618 — calien **573px de desplaçament INTERN** per descobrir
     que el tercer desplegable existeix. Un desplegable que s'ha de trobar
     desplaçant no és un desplegable: és una llista llarga amb un títol.
     Ara el carril no llisca (`overflow-y:hidden`) i els DOS blocs de recursos
     que estan oberts es reparteixen l'alçada que sobra, cadascun amb el seu
     scroll propi (`.ses-tcol-cards` i `.ses-parc-maq-cats` ja el porten). Els
     TRES rètols queden sempre a la vista i plegar-ne un dona l'espai als
     altres, que és el que un `<details>` ha de fer.
     Trasllats es queda `flex:0 0 auto` a posta (regla base, línia ~837): és el
     quadre del dia, no una llista de recursos, i el que li cal és el que
     ocupa. Fer-lo elàstic li donaria un terç del carril amb el dia buit.
     El `min-height:0` NO és decoració: sense ell, el `min-height:auto` per
     defecte d'un ítem flex impedeix encongir per sota del contingut i el bloc
     de màquines tornaria a fer 670px — el mateix defecte amb una regla nova a
     sobre. Mesurat al banc: 573px -> 0px. */
  /* L'ALÇADA LA MESURA EL JS, i no és cerimònia: és l'única manera que sigui
     certa a més d'una pantalla. El carril ha d'acabar on acaba la finestra, i
     per saber-ho cal saber on COMENÇA — cosa que el CSS no pot llegir.
     El 150px d'aquí venia del 17-09, quan el carril començava molt més amunt.
     El vaig substituir per `calc(100vh - 330px)` perquè a 1366x768 el carril
     comença a y=323... i la constant només podia ser certa en AQUELLA
     pantalla. Mesurat a vuit mides, fallava a quatre:

         1920x1080 -> 59px de desplaçament     1366x768  -> 0  ✓
         1600x900  -> 59px                     1280x800  -> 0  ✓
         1440x900  -> 141px                    1100x760  -> 0  ✓
         800x1000  -> 18px                     1024x700  -> 0  ✓

     La capçalera i la barra de controls emboliquen diferent a cada amplada:
     cap constant pot ser correcta a totes alhora. `--ses-carril-alt` la posa
     `acotaCarrilDelParc()` (`duat_seshat_dnd.js`) a partir de la base REAL de
     la capçalera sticky/fixa, i es refà a cada repintat i a cada `resize`. */
  .ses-pagina.ses-graella .ses-tcol-parc {
    max-height:var(--ses-carril-alt, calc(100vh - 330px));
    overflow-y:hidden; }
  /* El carril i la graella són germans: la variable que el JS escriu al
     seu pare fa que el tauler també arribi al peu visible, sense una
     segona mesura ni un forat sota les obres. */
  .ses-pagina.ses-graella .ses-obres {
    min-height:var(--ses-carril-alt, 0px); }
  /* QUI LLISCA ÉS EL BLOC, i el seu rètol s'hi queda enganxat.
     La primera versió d'aquesta tanda posava `overflow:hidden` al bloc
     confiant que la llista de dins (`.ses-tcol-cards`/`.ses-parc-maq-cats`,
     totes dues amb `overflow-y:auto` propi) s'encongiria i lliscaria ella.
     NO ho fa: mesurat, el bloc quedava client 91 / scroll 319 i la llista
     client 261 / scroll 261 — no havia encongit gens, o sigui que la seva
     barra no tenia res a desplaçar. Un `<details>` no reparteix l'alçada
     entre els seus fills com un flex normal: el contingut plegable viu dins
     d'una caixa pròpia del navegador, i el `flex:1 1 auto` de la llista no
     hi arriba.
     El resultat era el pitjor possible: 228px de treballadors i 479px de
     màquines RETALLATS, sense barra, sense rodeta i sense teclat. Contingut
     que existeix, es compta i no es pot agafar — i la pàgina serveix
     justament per arrossegar aquella gent a les obres. Caçat per
     agent-santi amb un GEST (rodeta de veritat), no amb una propietat:
     `scrollTop = 9999` per codi es mou igual amb `overflow:hidden`, o sigui
     que mirar la propietat hauria dit que tot anava bé.
     Ara llisca el bloc sencer i el `<summary>` va `sticky`: una sola barra
     per desplegable (no les dues niades que el gerent va rebutjar el 04-09)
     i els tres rètols segueixen sempre a la vista, també mentre lliscues. */
  /* 19-09-2026 (nit) · TRASLLATS entra a la llista dels elàstics. Amb
     l'acordió (decisió del gerent: un calaix obert cada cop) el que s'obre
     s'ha de quedar amb TOT el que sobra, i si el que s'obre és Trasllats i
     es mida pel contingut, el carril queda amb un forat blanc a sota. */
  .ses-pagina.ses-graella .ses-tcol-parc > .ses-parc-mitat-treb[open],
  .ses-pagina.ses-graella .ses-tcol-parc > .ses-parc-mitat-maq[open],
  .ses-pagina.ses-graella .ses-tcol-parc > .ses-parc-mitat-tr[open] {
    flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior-y:contain; }
  .ses-pagina.ses-graella .ses-tcol-parc > .ses-parc-mitat > .ses-parc-summary {
    position:sticky; top:0; z-index:2; background:var(--pt-surface); }
  /* Les llistes de dins deixen de lliscar elles: dues barres niades per al
     mateix contingut fan que la rodeta no sàpiga quina mou. El `max-height`
     de la base (46vh) tampoc hi pinta res aquí — qui posa el topall ara és
     el carril, mesurat. */
  .ses-pagina.ses-graella .ses-tcol-parc .ses-tcol-cards,
  .ses-pagina.ses-graella .ses-tcol-parc .ses-parc-maq-cats {
    max-height:none; overflow-y:visible; }

  /* La categoria viu DINS la línia del títol: és un punt clicable, no una
     línia que infli cada obra. El selector s'obre flotant per no canviar la
     mida de la targeta tancada. */
  .ses-pagina.ses-graella .ses-categoria-cap-plec { display:inline-block;
    position:relative; flex:0 0 auto; margin:1px 4px 0 0; line-height:1; }
  .ses-pagina.ses-graella .ses-categoria-cap-sum {
    display:grid; place-items:center; width:24px; height:24px; padding:0; border:0;
    cursor:pointer; list-style:none; background:transparent; }
  .ses-pagina.ses-graella .ses-categoria-cap-sum::before {
    /* La vora fosca és deliberada: el to del punt i el de la seva cel·la
       són el mateix, així que una vora clara el convertia en un anell buit. */
    content:""; display:block; width:12px; height:12px; border:1.5px solid var(--pt-text);
    border-radius:50%; background:transparent;
    /* Mesurat al navegador (26-09): amb un token de color que NO
       existia, el navegador anul·lava la vora sencera i el punt ple
       desapareixia sobre la cel·la del seu mateix to. `--pt-text` sí hi és. */
    box-shadow:none; }
  /* El popover obert viu dins la seva cel·la: sense pujar-la de capa, el
     punt de la cel·la veïna (que ve després al DOM) es pintava per sobre
     de «03 · Importants» (foto del banc, 26-09). */
  .ses-pagina.ses-graella .ses-tcol:has(.ses-categoria-cap-plec[open]) {
    position:relative; z-index:20; }
  /* `--pt-obra-N` surt de `config.OBRA_TONS` a `app.py`: la vinyeta i la
     columna comparteixen la mateixa font de color, sense cap hex duplicat. */
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-0::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-0 { background:var(--pt-obra-1); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-1::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-1 { background:var(--pt-obra-2); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-2::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-2 { background:var(--pt-obra-3); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-3::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-3 { background:var(--pt-obra-4); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-4::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-4 { background:var(--pt-obra-5); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-obra-to-5::before,
  .ses-pagina.ses-graella .ses-categoria-mostra.ses-obra-to-5 { background:var(--pt-obra-6); }
  .ses-pagina.ses-graella .ses-categoria-cap-sum.ses-categoria-cap-sense::before {
    /* Sense categoria no és un punt ple d'un altre color: és una absència. */
    background:transparent; border:1.5px dashed var(--pt-muted); box-shadow:none; }
  .ses-pagina.ses-graella .ses-categoria-cap-sum::-webkit-details-marker { display:none; }
  .ses-pagina.ses-graella .ses-categoria-cap-plec:not([open]) > .ses-categoria-popover,
  .ses-pagina.ses-graella .ses-categoria-cap-plec:not([open]) > .ses-color-fb { display:none; }
  .ses-pagina.ses-graella .ses-categoria-cap-plec[open] > .ses-categoria-popover {
    position:absolute; z-index:4; top:24px; left:0; width:220px; box-sizing:border-box;
    padding:6px; border:1px solid var(--pt-line); border-radius:var(--pt-radius);
    background:var(--pt-surface); box-shadow:var(--pt-elev-2); }
  .ses-pagina.ses-graella .ses-categoria-opcio { display:flex; align-items:center;
    position:relative; gap:7px; min-height:28px; padding:2px 5px; margin:0; white-space:nowrap;
    cursor:pointer; border-radius:4px; }
  /* Dash 4 requereix que el label sigui text. Les mostres viuen per tant al
     CSS, ordenades com les opcions (Cap, 01…06), no dins options[].label. */
  .ses-pagina.ses-graella .ses-categoria-opcio::before { content:""; width:12px; height:12px;
    flex:0 0 12px; display:inline-block; box-sizing:border-box; border:1px solid var(--pt-text);
    border-radius:50%; background:transparent; }
  /* Dash 4 embolica cada opció en el seu propi `label`, o sigui que
     `:nth-child` de l'span sempre és 1: el ganxo és `data-option-index` del
     label, i el to de cada índex el porta `--ses-opcio-N` (seshat.py). */
  .ses-pagina.ses-graella [data-option-index="0"] .ses-categoria-opcio::before {
    border:1.5px dashed var(--pt-muted); }
  .ses-pagina.ses-graella [data-option-index="1"] .ses-categoria-opcio::before { background:var(--ses-opcio-1, transparent); }
  .ses-pagina.ses-graella [data-option-index="2"] .ses-categoria-opcio::before { background:var(--ses-opcio-2, transparent); }
  .ses-pagina.ses-graella [data-option-index="3"] .ses-categoria-opcio::before { background:var(--ses-opcio-3, transparent); }
  .ses-pagina.ses-graella [data-option-index="4"] .ses-categoria-opcio::before { background:var(--ses-opcio-4, transparent); }
  .ses-pagina.ses-graella [data-option-index="5"] .ses-categoria-opcio::before { background:var(--ses-opcio-5, transparent); }
  .ses-pagina.ses-graella [data-option-index="6"] .ses-categoria-opcio::before { background:var(--ses-opcio-6, transparent); }
  .ses-pagina.ses-graella [data-option-index="7"] .ses-categoria-opcio::before { background:var(--ses-opcio-7, transparent); }
  .ses-pagina.ses-graella [data-option-index="8"] .ses-categoria-opcio::before { background:var(--ses-opcio-8, transparent); }
  .ses-pagina.ses-graella [data-option-index="9"] .ses-categoria-opcio::before { background:var(--ses-opcio-9, transparent); }
  .ses-pagina.ses-graella [data-option-index="10"] .ses-categoria-opcio::before { background:var(--ses-opcio-10, transparent); }
  .ses-pagina.ses-graella [data-option-index="11"] .ses-categoria-opcio::before { background:var(--ses-opcio-11, transparent); }
  .ses-pagina.ses-graella [data-option-index="12"] .ses-categoria-opcio::before { background:var(--ses-opcio-12, transparent); }
  .ses-pagina.ses-graella .ses-categoria-opcio:hover { background:var(--pt-soft); }
  /* El ràdio continua al DOM i rep focus de teclat, però no pot quedar solt
     damunt el text d'una fila com passava a «03 · Importants». */
  .ses-pagina.ses-graella .ses-categoria-radio { position:absolute; width:1px; height:1px;
    margin:-1px; clip:rect(0 0 0 0); clip-path:inset(50%); overflow:hidden; white-space:nowrap; }
  /* El ràdio és GERMÀ de l'span de text (dins el `label` de Dash), no fill. */
  .ses-pagina.ses-graella .dash-options-list-option:has(.ses-categoria-radio:checked) .ses-categoria-opcio {
    background:var(--pt-soft); font-weight:700; }
  .ses-pagina.ses-graella .dash-options-list-option:has(.ses-categoria-radio:focus-visible) .ses-categoria-opcio {
    outline:2px solid var(--pt-text); outline-offset:1px; }
  .ses-pagina.ses-graella .ses-categoria-mostra,
  .ses-pagina.ses-graella .ses-categoria-mostra-sense { width:12px; height:12px;
    flex:0 0 12px; display:inline-block; border:1px solid var(--pt-line); border-radius:2px; }
  .ses-pagina.ses-graella .ses-categoria-mostra-sense { background:transparent;
    border-color:var(--pt-muted); }
  .ses-m4pro-marca { margin-left:4px; padding:1px 4px; border-radius:999px;
    background:var(--pt-soft); color:var(--pt-muted); font-size:.68rem; white-space:nowrap; }

  .ses-pagina.ses-graella .ses-tcol { min-width:0; padding:4px 6px; }
  /* ── L'efecte de FLOTAR (PLA 17-09-2026, CP5) ─────────────────────────
     La cel·la que es pot agafar ho DIU sota el punter: puja al nivell 2 de
     l'escala d'elevació (`:root`) i 1px amunt. Només les cel·les d'obra
     (`[data-obra]`: són les que el Sortable d'obres mou); ni el parc ni els
     trasllats floten, perquè no es mouen. La cel·la OBERTA descansa al
     nivell 1 —és la que mana a la pantalla— i no salta en passar-hi. El
     `transform` no toca la caixa de layout: la sonda de forats i d'obres
     visibles mesura el mateix amb el punter a sobre o fora. Mentre s'està
     arrossegant, `.sortable-drag` (nivell 3) ja ho diu.
     El cursor de la capçalera es queda `pointer` (regla de sobre): el clic
     l'obre i el gest la mou, i «clicable» és el que diu la veritat de les
     dues. Un `cursor:grab` aquí perdria contra els tres `:not` de la regla
     de sobre —mesurat: el navegador deia `pointer`— i seria una regla que
     no mana, que és pitjor que cap. */
  .ses-pagina.ses-graella .ses-tcol[data-obra]:not(.ses-oberta) { transition:box-shadow .15s ease, transform .15s ease; }
  .ses-pagina.ses-graella .ses-tcol[data-obra]:not(.ses-oberta):hover { box-shadow:var(--pt-elev-2); transform:translateY(-1px); }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta { box-shadow:var(--pt-elev-1); }
  /* La cel·la OBERTA (acordió) s'estén a tota la fila de LA SEVA graella:
     com que ara `.ses-tcol` és fill de `.ses-obres` (no de `.ses-tauler`),
     `grid-column:1/-1` ja s'aplica relatiu a `.ses-obres` sense cap canvi. */

  /* Trasllats: sempre VISIBLE en graella (PLA 16-09-2026, punt 7) — mai es
     compacta com les obres (vegeu el `:not(.ses-tcol-tr)` de sota) perquè
     el formulari («Apunta un trasllat») ha de quedar a mà sense obrir
     cap cel·la. Al final de la quadrícula. */
  .ses-pagina.ses-graella .ses-tcol-tr { order:99; }

  /* La cel·la TANCADA: només capçalera. Les targetes i el peu —tot el que
     Detall ensenya— es queden al DOM i s'amaguen amb selector compost.
     El parc ja no cal excloure'l (és fora de `.ses-obres`); els trasllats
     SÍ (`:not(.ses-tcol-tr)`, PLA punt 7: el seu formulari es queda visible
     sempre, no és una obra que s'obri i es tanqui). Cada selector en UNA
     sola línia (encara que sigui llarga) perquè cap eina que llegeixi
     «l'inici de línia» confongui una continuació amb una regla nua sobre
     la classe DEUTE. */
  /* T1d (25-09): una obra plegada NO ensenya les fitxes senceres, però el
     tros que queda sota la capçalera continua sent la seva zona de deixar.
     Abans aquesta mateixa `.ses-dnd` era 191×0 amb `overflow:hidden`: el
     Sortable existia al DOM però el ratolí no hi podia arribar. El contenidor
     és flex per omplir la cel·la; les fitxes completes s'amaguen en una regla
     separada per no confondre «no es veu» amb «no es pot deixar anar». */
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) { display:flex; flex-direction:column; box-sizing:border-box; }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-cards { flex:1 1 auto; min-height:24px; max-height:none; padding:0; margin:0; overflow:visible; border:0; }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-cards > .ses-tcard { display:none; }
  .ses-pagina.ses-graella .ses-tcol.ses-drop-activa { border-style:dashed; }
  .ses-pagina.ses-graella .ses-tcol.ses-drop-sobre { border-color:var(--pt-verd); box-shadow:0 0 0 3px var(--pt-verd-pastel); background:var(--pt-surface); }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-peu, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-enc, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-kpis, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-sec, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-ritme, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-sub, .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-bar { display:none; }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-cap { margin-bottom:2px; min-height:44px; cursor:pointer; }
  /* DUES línies, no una (gerent, 19-09-2026: «el nom de les obres no es veu
     bé»). Mesurat al banc amb una línia: cap dels 29 noms es veia sencer, la
     mediana n'ensenyava el 65% i el pitjor el 35% —una columna compacta fa
     166px i els noms de l'ERP en fan de 269 a 435. La vinyeta del codi que
     va néixer avui encara li prenia un tros més. El preu són ~17px d'alçada
     per capçalera, i el vigila `--forats-amb-oberta`. */
  /* DUES línies SEMPRE, també quan el nom en fa servir una. Amb l'alçada
     lliure les cel·les sortien de dues mides —98px les de nom curt i 118px
     les de nom llarg, mesurat— i la graella quedava dentada: el gerent ho va
     veure de seguida («es veu bé la forma dels quadrats?»). Amb el `min-
     height` clavat a dues línies, totes les cel·les tornen a fer la mateixa
     forma i el nom segueix tenint les dues línies quan les necessita. El
     preu són ~20px a les de nom curt, i el vigila `--forats-amb-oberta`. */
  /* A la cel·la compacta la vinyeta no infla la línia: amb `min-height:24px`
     la primera línia feia 24px i el títol 41; amb l'alçada de la línia el
     títol baixa a 34 i la cel·la de 114 a 107. El codi hi segueix cabent
     —són dos dígits— i el terra de 44px no hi aplica: la vinyeta NO és
     tocable, és un rètol. */
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta) .ses-cat-codi-vinyeta {
    min-height:17px; line-height:17px; padding:0 4px; }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-titol { font-size:.85rem; margin:0; display:flex; align-items:flex-start; overflow:visible; line-height:17px; min-height:36px; }
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-titol > strong { min-width:0; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
  /* Els 41px són MESURATS, no calculats: la primera línia no fa 17px sinó
     24, perquè hi va la vinyeta del codi (`.ses-cat-codi-vinyeta`,
     `min-height:24px`) i és ella qui mana l'alçada de la línia. 24 + 17 = 41.
     Calculant-ho com «dues línies de text» sortien 34 i les cel·les seguien
     de dues mides (107 i 114px). */
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-tcol-client { font-size:.74rem; margin:0; display:-webkit-box; -webkit-line-clamp:1; -webkit-box-orient:vertical; overflow:hidden; }
  /* «Posar aquí»: amagat a la cel·la tancada llevat que hi hagi una targeta
     TRIADA — la marca ja existeix (`.ses-tcard-sel`, `_targeta()` a
     seshat.py); no calia cap classe nova (PLA, supòsit 1). La zona de drop
     (`.ses-tcol-cards.ses-dnd`) es queda VIVA per l'arrossegament encara amb
     0 px d'alt.
     18-09-2026 (ITERAR queixa 3) · `:has(.ses-tcard-sel)` sol ja NO basta:
     el cercador ara també posa `.ses-tcard-sel` a la COLUMNA d'obra que
     casa (`duat_modules.css` DS-S02b), i sense escopar el selector,
     escriure al cercador faria aparèixer «Posar aquí» a TOTES les
     columnes tancades sense que ningú hagi triat cap targeta de veritat.
     `.ses-tcard.ses-tcard-sel` només és cert quan la marca cau sobre una
     targeta real —el cas de sempre—, mai sobre una columna. */
  .ses-pagina.ses-graella .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-colbtn { display:none; }
  .ses-pagina.ses-graella:has(.ses-tcard.ses-tcard-sel) .ses-tcol:not(.ses-oberta):not(.ses-tcol-tr):not(.ses-tcol-parc) .ses-colbtn { display:inline-flex; min-height:44px; }

  /* El resum: «👷 N · 🚜 M» (icones+xifra, la paraula ja la diu l'emoji —
     santi #2: amb les paraules senceres el text feia 175 px de `scrollWidth`
     contra 124 de `clientWidth` i tapava la M de màquines) + xips d'un sol
     nom cadascun, amb el comptador de «+N més» que calcula el JS
     (`data-mes`, mai un número fix: l'amplada de la cel·la depèn de quantes
     columnes hi caben). El text llarg es queda al `title`. */
  .ses-pagina.ses-graella .ses-tcol-recompte { display:block;
    font-size:.74rem; font-weight:600; color: var(--pt-muted); margin:1px 0;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  /* Senyal d'estat (jutge de disseny, ronda cega 1: «25 targetes idèntiques
     sense variable d'estat»): mai només color — el text ho diu sempre. */
  .ses-pagina.ses-graella .ses-tcol-recompte.ses-recompte-sense-maq {
    color: var(--pt-text-ambre); }
  .ses-pagina.ses-graella .ses-tcol-recompte.ses-recompte-buida {
    color: var(--pt-muted); font-weight:400; font-style:italic; }
  /* `min-height` (18-09-2026): abans una obra SENSE cap recurs assignat
     no tenia cap xip i la fila desapareixia (0px), deixant la targeta
     TANCADA a 69px en lloc de 93px — mesurat en viu. Amb la fila fixa que
     demana la maqueta (`grid-auto-rows`, sota), una targeta més curta que
     la seva fila era exactament el defecte del blanc vertical: només que
     ara, en lloc de fuita entre columnes, era fuita DINS de la mateixa
     caixa. Reservar-ho aquí és un ajust de CONTINGUT (el clon de
     `--targetes-inflades` fa servir la MATEIXA regla, o sigui que «natural»
     i «real» tornen a coincidir), no un estirament del contenidor. */
  .ses-pagina.ses-graella .ses-tcol-resum { display:flex; gap:4px;
    overflow:hidden; white-space:nowrap; margin:2px 0 0; position:relative;
    min-height:22px; }
  /* CONTROL (santi #1): `flex:0 1 auto` dins d'un contenidor `overflow:
     hidden` deixava que el navegador ESPRÉMÉS els xips (14 px, cap lletra)
     ABANS que `calculaMes()` els mesurés — `offsetWidth` llegia la mentida
     comprimida i la suma mai superava l'amplada, o sigui que mai en
     detectava cap "de més". `flex:0 0 auto` treu la compressió: ara
     `offsetWidth` és l'amplada NATURAL i el JS pot decidir de veritat quants
     hi caben. Els que no hi caben s'amaguen amb la CLASSE `ses-xip-fora`
     (mai `display:none` inline ni fora del DOM). */
  .ses-pagina.ses-graella .ses-tcol-xip { flex:0 0 auto; font-size:.74rem;
    padding:1px 6px; border-radius:999px; background: var(--pt-surface);
    border:1px solid var(--pt-line); color: var(--pt-text);
    white-space:nowrap; box-sizing:border-box; }
  .ses-pagina.ses-graella .ses-tcol-xip.ses-xip-fora { display:none; }
  /* El PRIMER xip mai s'amaga (PLA + santi #1: «almenys un nom LLEGIBLE»):
     si ni ell hi cap, es retalla amb punts suspensius, mai per sota de
     60 px. Sense `escapcat` es queda a l'amplada natural, encara que
     sobresurti una mica del contenidor (que ja el talla per `overflow`). */
  .ses-pagina.ses-graella .ses-tcol-xip.ses-xip-escapcat { max-width:100%;
    min-width:60px; overflow:hidden; text-overflow:ellipsis; flex:0 1 auto; }
  /* `flex:0 1 auto` NOMÉS al xip ja escapçat (la classe la posa el JS DESPRÉS
     de mesurar les amplades naturals, o sigui que la trampa del CONTROL #1
     no torna): així, quan al costat hi ha el comptador «+N més», és el nom
     qui cedeix amb punts suspensius i el comptador es queda sencer
     (17-09-2026, `--resum-desborda`). */
  .ses-pagina.ses-graella .ses-tcol-resum[data-mes]::after {
    content:"+" attr(data-mes) " més"; flex:0 0 auto; font-size:.74rem;
    font-weight:600; color: var(--pt-muted); background: var(--pt-soft);
    padding:1px 6px; border-radius:999px; }

  /* La cel·la OBERTA (acordió, una de sola: JS a `duat_seshat_dnd.js`):
     s'estén a tota la fila amb el contingut actual sencer —no s'amaga res
     de nou, simplement no coincideix amb `:not(.ses-oberta)` de sobre. */
  /* 17-09-2026 · L'OBRA OBERTA JA NO S'EMPASSA LA PANTALLA. Mesurat: amb
     `grid-column:1/-1` la cel·la oberta feia 1024x795 començant a y=259, o
     sigui el 103,5% de la finestra — se sortia sencera. I el marc pesava més
     que la feina: capçalera 206px + peu 305px al voltant de 258px de fitxes.
     Petició del gerent (17-09): «si obres un projecte que no agafi tota la
     pantalla» i «que el títol un cop l'obris quedi compacte».
     Tres coses, i cap toca el contingut: (1) ocupa 3 carrils en lloc de tots,
     o sigui que les altres obres es queden a la vista; (2) topall d'alçada
     amb scroll propi; (3) les fitxes de dins deixen de ser files de l'amplada
     sencera per dir un nom i «8 h». Mesurat: 103,5% → 46,0%. */
  /* CP2 (18-09-2026, ordre del gerent): l'obra oberta NO amaga res.
     El topall de 46vh amb scroll propi era la decisió del 17-09; el gerent l'ha
     canviada: «no creïs scrolls dintre les targetes de projecte». Mesurat abans
     de treure'l: 853px de contingut en 351px de caixa —502px amagats— i 3
     fitxes de 10 a la vista. Després: 0 scrolls i 10 de 10.
     La targeta CREIX amb el que porta: `.ses-obres` té les files implícites i
     `align-content:start`, o sigui que una targeta més alta només fa més alta
     la SEVA fila.
     El `max-height` de la llista s'anul·la NOMÉS aquí: la regla base
     (`.ses-tcol-cards`, línia 626) la comparteixen el parc, els trasllats i
     les obres tancades, i tocar-la propagaria el canvi a quatre llocs. */
  /* 18-09-2026 14:30 · REENQUADRAT #3, DECISIÓ DEL GERENT (veure diari):
     torna a ser un element DE FLUX amb ÀREA PRÒPIA RESERVADA dins la
     graella, com `.p1` de la maqueta de Codex (`grid-column:1/5;
     grid-row:1/4` — 4 columnes × 3 files). Es descarten el plafó ANCORAT
     (`position:absolute`, sota, retirat) i el calaix acoblat (proposta de
     Fable): el gerent ha triat aquesta, sabent-ne el preu — les targetes
     que quedin DINS d'aquesta àrea es RECOL·LOQUEN (`.ses-alliberada`,
     `duat_seshat_dnd.js`); les de FORA no es poden moure mai
     (`--obrir-mou-forans`). El `span 6` d'una sola fila (mig quadre) es
     substitueix per `q.UNITATS_OBRA_OBERTA` × `q.FILES_OBRA_OBERTA` (4×3,
     `q_planificacio.py`) — mateix nombre d'unitats de contingut (12), més
     alt i menys ample, com la maqueta. Fallback SENSE casella (no hauria
     de passar mai: totes les obres en porten una, punt 1 del pla). */
  /* 18-09-2026 16:45 (Codex, diagnòstic acceptat) · 4×3 era MATEMÀTICAMENT
     incompatible amb 10 recursos: amb 4 unitats, a 1366 i a 1000 no hi
     caben dues fitxes de 190px i l'`auto-fill` de `.ses-tcol-cards` (sota)
     en posa una sola columna — les fitxes s'apilen fins a desbordar el
     viewport. A 1920 sí que hi caben dues columnes, per això només allà
     donava 100%. La via triada NO toca cap de les 6 restriccions (mai
     `position:absolute`, mai scroll intern, cap fitxa amagada, terra de
     44px, les de FORA no es mouen, mateix mecanisme de graella): eixampla
     l'àrea reservada a `--ses-ample-oberta` (6 a escriptori, 8 a tauleta,
     declarada a `.ses-obres` amunt i re-declarada al bloc de tauleta,
     sota — el mateix patró que `--ses-fila-px`). DESCARTAT amb motiu: més
     files (reserven espai, no creen píxels) · dues columnes dins de 4
     unitats (fitxes de 120-160px, sota el mínim de 190 del sistema de
     disseny) · «+N més» (amaga fitxes i falseja la sonda) · fitxes més
     petites (ja són al terra de 44px) · scroll intern (contradiu la
     restricció 3). */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta {
    grid-column:span var(--ses-ample-oberta, 6); grid-row:span 3; }
  /* La casella EXPLÍCITA (`--ses-xo`/`--ses-y`, `_casella()` a seshat.py):
     `--ses-xo` ja és el resultat de `min(x, COLUMNES_GRAELLA -
     UNITATS_OBRA_OBERTA)` — «si `x + amplada > 12`, es desplaça cap a
     l'esquerra» és EXACTAMENT això, calculat al servidor amb el PITJOR
     cas (8, tauleta) que aquí es reserva: un `span` més petit (6,
     escriptori) que comenci al mateix punt sempre hi cap si el gran ja hi
     cabia — no calen dues fonts del número, només el clamp més gran. La
     fila sempre comença a `--ses-y`: cap desplaçament vertical, la
     graella ja pot créixer avall sense topall dur.
     `span var(--ses-span-oberta, 3)`, MAI `span 3` a soles (18-09-2026,
     `--obres-encavalcades` mesurat: 6): una obra amb moltes assignacions
     desborda 3 files fixes (contingut real, mai scroll intern, CP2), i
     amb `span 3` el grid només marcava 3 files OCUPADES — la targeta
     tancada de la fila just per sota es quedava «formalment lliure» i
     s'hi auto-col·locava igual, tapada per píxels sense haver xocat per
     casella. `--ses-span-oberta` (`duat_seshat_dnd.js`, `reservaAlcadaOberta`,
     mateix patró que `--ses-tr-span` dels trasllats, unes línies avall)
     el mesura amb l'alçada REAL un cop oberta i el grid ja sap que totes
     aquestes files són seves. `3` és NOMÉS el valor de sortida abans que
     el JS corri (evita un instant d'encavalcament visible al primer
     pintat), com ja fa `--ses-tr-span` per als trasllats. */
  .ses-pagina.ses-graella .ses-obres > .ses-tcol[data-x].ses-oberta {
    grid-column:var(--ses-xo) / span var(--ses-ample-oberta, 6);
    grid-row:var(--ses-y) / span var(--ses-span-oberta, 3);
    box-shadow:var(--pt-elev-2); }
  /* Les targetes TAPADES per l'àrea de dalt perden la seva casella fixa
     (JS els hi afegeix `.ses-alliberada`, mai les mou al DOM) i cauen en
     `grid-auto-flow:row dense` (`.ses-obres`, amunt): el navegador els
     troba soles la primera casella LLIURE de debò —ni la de la vinyeta
     oberta ni la de cap altra targeta fixa—, sense reimplementar cap
     càlcul de col·lisió en JS. En tancar-se, `.ses-alliberada` es treu i
     recuperen la seva casella de `[data-x]` de sempre. */
  .ses-pagina.ses-graella .ses-obres > .ses-tcol[data-x].ses-alliberada {
    grid-column:span 2; grid-row:auto; }
  /* L'amplada de `.ses-tcol-cards` ja NO depèn de qui hi ha al costat
     (`amplariaLliure()` és FORA): l'àrea reservada (`--ses-ample-oberta`
     unitats, 6 o 8 segons rang) dona sempre la MATEIXA amplada real, variï
     qui variï de veí. `minmax(min(190px, 100%),1fr)` es queda igual: amb
     6-8 unitats la caixa té prou per a dues columnes de 190px a 1366,
     1920 i 1000 (18-09-2026 16:45, Codex) i mai en demana més del que hi
     ha — mateixa guarda que abans contra el desbordament horitzontal. */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-cards {
    display:grid;
    grid-template-columns:repeat(auto-fill, minmax(min(190px, 100%), 1fr));
    gap:5px; max-height:none; overflow:visible; }
  /* El resum de xips és el resum de la cel·la TANCADA. Amb l'obra oberta diu
     exactament els mateixos noms que les fitxes de sota: duplicat, fora. */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-resum { display:none; }

  /* CP13 (19-09-2026, captura del gerent marcada en vermell: «la
     distribució de dintre està massa poc compacte»). La capçalera de la
     vinyeta oberta feia ~188px abans de cap contingut: 8 blocs, cadascun
     amb el seu propi marge vertical pensat per a la cel·la TANCADA (una
     targeta entre moltes). Oberta n'hi ha NOMÉS una, i els marges se sumen
     sols. Escopat a `.ses-oberta`: la cel·la tancada i les vistes de
     tauleta/mòbil no es toquen. Cap bloc desapareix, cap dada es perd —
     només s'ajusten els espais entre ells. */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-cap {
    margin-bottom:2px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-client {
    margin:0 0 2px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-recompte {
    margin:0 0 2px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-enc {
    margin:0 0 2px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-kpis {
    margin:2px 0; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-sub {
    margin:1px 0 2px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-bar { margin:2px 0; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-colbtn {
    margin-top:0; }

  /* CP13 · les dues zones 3 i 4 que el gerent va marcar («el formulari de
     comentari»/«de petició»): camp en una fila i botó EMPÈS a una segona,
     amb tota l'esquerra buida. La causa NO és `.ses-com-form` en si —ja fa
     `display:flex` amb el camp a `width:100%`— és que APILA (`flex-
     direction:column`) perquè quan aquesta regla es va escriure (03-09) la
     columna feia 288px i un camp+botó en línia deixava el camp a 130px,
     escapçat (comentari escrit al costat de la regla, més amunt). La
     vinyeta oberta d'avui fa 533px a 1366 —el CP8/9 ja la va eixamplar—:
     hi ha lloc de sobres per posar-los en línia sense repetir aquell
     error. NOMÉS escopat a `.ses-oberta`: la resta de llocs on
     `.ses-com-form`/`.ses-pet-form` es pinten (si mai n'hi ha cap altre,
     més estrets) segueixen apilats. */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-com-form,
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-pet-form {
    flex-direction:row; align-items:stretch; gap:6px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-com-form .ses-inp-h,
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-pet-form .ses-inp-h {
    flex:1 1 auto; min-width:0; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-com-form .ses-btn-mini,
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-pet-form .ses-btn-mini {
    flex:0 0 auto; align-self:stretch; white-space:nowrap; }

  /* CP13 · la resta de l'objectiu numèric (`--alcada-oberta` <= 100% a
     1366): coixinets pensats per a UNA targeta entre moltes que, oberta,
     només n'hi ha una i se sumen tots. `min-height:44px` (terra tàctil,
     DESIGN.md) es queda EXACTE a tot arreu — només es toca el `padding`
     que hi sobrava per sobre d'aquell terra. Escopat SEMPRE a `.ses-oberta`
     perquè el parc (158px, `.ses-tcol-parc`) i la cel·la tancada no es
     toquen — `.ses-tcard` i `.ses-tcol-cards` són compartides amb tot
     arreu. */
  .ses-pagina.ses-graella .ses-tcol.ses-oberta { padding:5px 10px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcard {
    padding:6px 10px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-tcol-cards { gap:4px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-peu-diari {
    margin-top:4px; gap:4px; }
  .ses-pagina.ses-graella .ses-tcol.ses-oberta .ses-peu-config {
    margin-top:2px; padding-top:2px; }

  /* El quadre primer; la gestió que decideix QUÈ hi surt, i «el que convé
     mirar», DESPRÉS (PLA, supòsit 2). És el mateix mecanisme que ja fa
     `.pt-mod > * { order }` per a tauleta i mòbil (línia ~934): aquí puja a
     escriptori, però només sota `.ses-graella`. */
  .ses-pagina.ses-graella #ses-obres-tria { order:6; }
  .ses-pagina.ses-graella .ses-tauler-ctrls { order:6; }
  .ses-pagina.ses-graella .ses-board-wrap { order:1; }
  .ses-pagina.ses-graella .ses-com-va { display:none; }
  .ses-pagina.ses-graella .ses-vista-tauler { display:flex;
    flex-direction:column; }
  .ses-pagina.ses-graella .ses-vista-tauler > .ses-tauler-wrap { order:1; }
  .ses-pagina.ses-graella .ses-vista-tauler > .ses-det { order:2; }
  /* El comptador «N treballadors sense destí · M màquines al parc»
     (`.ses-tauler-barra`) NO és fill de `.ses-tcol-parc`: viu a
     `.ses-tauler-wrap`, germà de `.ses-tauler`. Santi #4 (quan `barra` era
     NOMÉS el comptador) en demanava veure-la JUST SOTA el quadre.

     19-09-2026 · REGRESSIÓ mesurada pel gerent i CORREGIDA: la mateixa
     correcció d'avui («el cercador i les 4 accions tornen aquí») va omplir
     `barra` de navegació crítica sense tocar aquest `order`, i `order:2`
     (darrere `.ses-tauler`, `order:1`) l'enterrava sota els 755px del
     quadre de 28 obres — a 1366×768 el cercador queia a y=1074, fora de
     qualsevol finestra normal. `--barra-visible-a-larribada`
     (`sonda_compacitat_planificacio.py`) ho mesura EN ARRIBAR, sense tocar
     res, escopant `.ses-tauler-cerca` DINS de `.ses-tauler-wrap >
     .ses-tauler-barra` (n'hi ha tres al DOM amb aquesta classe; qualsevol
     altra és una altra pàgina). `barra` puja a `order:0` — mateix valor
     per defecte que `avis_dia`, que la precedeix al DOM i per tant hi
     segueix davant — i `.ses-tauler` passa a `order:1`: es veu SEMPRE en
     arribar, mai sota el plec. */
  .ses-pagina.ses-graella .ses-tauler-wrap { display:flex;
    flex-direction:column; }
  .ses-pagina.ses-graella .ses-tauler-wrap > .ses-tauler-barra { order:0; }
  .ses-pagina.ses-graella .ses-tauler-wrap > .ses-tauler { order:1; }
  .ses-pagina.ses-graella .ses-tauler-wrap > .ses-banner-tr { order:2; }
}

/* ── GRAELLA · tauleta (769-1200px, 1024 inclòs) ─────────────────────────────
   PLA 16-09-2026, punt 1: «a 1024 px use minmax(150px,1fr) and hide the
   chip line: cells show only counts». Ja és el DEFECTE del bloc de sobre
   (`minmax(150px, 1fr)`, sense res més a dir): aquí NOMÉS cal amagar la
   fila de xips — el comptador «👷 N · 🚜 M» es queda, que és el que
   `--dins-viewport-comptadors` mesura. */
@media (min-width: 769px) and (max-width: 1200px) {
  .ses-pagina.ses-graella .ses-tcol-resum { display:none; }
  /* «Quan no hi cap, ho diu»: la nota «· sense màquina» es queda al DOM
     (`.ses-recompte-nota`, seshat.py) però s'amaga aquí — mesurat en
     viu a 1024×768: amb la cel·la a 152px el comptador base («👷 N ·
     🚜 M») ja ocupava l'amplada sencera i la nota el feia desbordar
     (156px de `scrollWidth` contra 138px disponibles). */
  .ses-pagina.ses-graella .ses-recompte-nota { display:none; }
  /* CONTROL (mesurat en viu a 1024×768): amb el parc a 250px, `.ses-obres`
     només tenia 701px i `repeat(auto-fill, minmax(150px,1fr))` només hi
     encabia 4 columnes — amb 25 obres calien 7 files i la 5a-7a queien
     fora del viewport (20/25, no 25/25). Estretint el parc a 200px (per
     sobre dels 200px mínims que demana el cercador de dins) l'`.ses-obres`
     guanya prou amplada per a 5 columnes senceres. */
  /* Mesurat en viu, per passes: amb el parc a 250px `.ses-obres` només
     tenia 701px i `repeat(auto-fill, minmax(150px,1fr))` només hi
     encabia 4 columnes (20/25 amb 7 files, la 5a-7a fora del viewport). Es
     retallen TRES coses alhora perquè cap sola n'hi ha prou: el marge
     lateral de la pàgina (`clamp(12px,3vw,40px)` = 31px a 1024 → 12px), el
     `gap` de la graella i el propi parc (220px — encara per SOBRE dels
     200px mínims que demana el cercador de dins, `.ses-tcol` hi posa
     20px de farciment: 220-20=200). */
  .ses-pagina .ses-tauler-wrap { padding:0 12px; }
  .ses-pagina .ses-tauler { grid-template-columns:220px 1fr; gap:8px; }
  /* `.ses-tcol-parc` porta `min-width:250px` a la base (per al `flex` de
     Detall i de mòbil): sota `display:grid` un `min-width` explícit
     guanya sobre `grid-template-columns` i la pista es quedaria a 250px
     igualment sense això. */
  .ses-pagina .ses-tcol-parc { min-width:220px; flex-basis:220px; }
  /* `grid-auto-rows` MÉS BAIX, no la targeta inflada (18-09-2026, Fable
     MITJANA #6 i ALTA #2). Primer intent: forçar `min-height:93px` a la
     targeta tancada «a tots els rangs» — mesurat i DESCARTAT: a tauleta la
     fila de xips (`.ses-tcol-resum`) està en `display:none` per a TOTES
     les targetes (no és contingut variable, és una decisió de disseny), o
     sigui que la seva alçada natural és SEMPRE 69px (mesurat en viu, les
     28 targetes del banc, cap excepció) — forçar-les a 93px no tapava cap
     forat de contingut, INFLAVA les 28 targetes senceres (`--targetes-
     inflades` 0→28, guardià ja no cec). La fila ha de valer el que val LA
     TARGETA en aquest rang, no al revés: `grid-auto-rows:69px` (mesurat,
     `getBoundingClientRect().height` de 10 targetes tancades diferents,
     totes 68,92px). `--ses-fila-px` es deriva d'AQUESTA fila + el `gap`
     d'aquest mateix rang (3px): 69+3=72, no 93+3=96 del primer intent —
     `background-size` (base, més amunt) ja llegeix `var(--ses-fila-px)`,
     o sigui que la quadrícula de fons segueix sola, sense un altre número
     a mantenir sincronitzat. Mesurat DESPRÉS del canvi: `--buit-vertical`
     27→3, `--targetes-inflades` 28→0, cap regressió a `--fitxes-visibles`
     ni `--scrolls-dins-oberta` (la targeta OBERTA no depèn d'aquesta
     fila: `grid-row:var(--ses-y)/span 3`, unitats pròpies). */
  /* 18-09-2026 16:45 (Codex) · `--ses-ample-oberta:8`, NOMÉS aquí: a
     tauleta cada unitat val menys píxels que a escriptori (el carril és
     més estret, `220px 1fr` amunt) i calen 8 unitats, no 6, per arribar a
     la mateixa amplada mínima de dues fitxes de 190px. Mateix patró que
     `--ses-fila-px`: el número es deriva d'AQUEST rang i es llegeix des
     del full (CSS) i des del JS (`getComputedStyle`, `duat_seshat_dnd.js`
     `amplaOberta`), mai duplicat com a constant fixa. */
  .ses-pagina.ses-graella .ses-obres { gap:3px; grid-auto-rows:minmax(80px, auto);
    --ses-fila-px:93px; --ses-ample-oberta:8; }
}

/* ── GRAELLA · escriptori (>=1201px) ─────────────────────────────────────────
   18-09-2026 · Aquest bloc redeclarava `grid-column`/`grid-row` de les
   targetes exactament IGUAL que el bloc base (>=769px, línia ~1140): la
   graella de 12 unitats i l'àrea reservada de la targeta oberta ja no
   dupliquen res per amplada — el que canvia per amplada és NOMÉS quants
   xips hi caben (`.ses-tcol-resum`/`.ses-tcol-xip`, bloc de dalt) i
   l'amplada del carril del parc (tauleta, sota). Bloc buit retirat perquè
   no s'hi quedés la regla `grid-row:auto` vella.
   18-09-2026 16:45 (Codex) · segueix buit: `--ses-ample-oberta` val 6 pel
   valor de sortida del bloc base (>=769px, línia ~1191) i NOMÉS es
   redeclara a tauleta (8, amunt). No cal repetir-lo aquí. */


/* ── L'ORDRE DE LA PANTALLA · a TOTES les amplades ───────────────────────────
   El gerent, mirant el PC (04-09-2026): «el més important, que és la gestió de
   les obres, encara està a baix de tot». Tenia raó i el número ho diu: a
   1680 px la pàgina fa 4.594 px d'alt i el bloc d'obres obertes queia a 1.195,
   després del títol, el paràgraf, els indicadors, els moviments, «qui és qui»,
   «per resoldre» i «hores per revisar». Set blocs de context abans de la cosa
   que decideix QUÈ surt al quadre.

   L'ordre ja existia per a telèfon i tauleta. Aquí puja a TOTES les amplades,
   perquè la pregunta «què vull veure primer» no depèn de la mida de la
   pantalla: depèn de per a què s'obre l'eina.

     0  el dia i les vistes        ← on ets
     2  quines obres surten        ← què vols veure  (LA GESTIÓ)
     4  el quadre                  ← la feina
     6+ tot el context             ← el que es mira després

   Res desapareix del DOM: un `Output` sobre un id absent tomba el callback
   sencer. Només canvia l'ordre en què es veu. */
.ses-pagina .pt-mod { display:flex; flex-direction:column; }
.ses-pagina .pt-mod > * { order:6; }
.ses-pagina .pt-mod > .pt-mod-head,
.ses-pagina .pt-mod > div:has(> .pt-back-link) { order:0; }
.ses-pagina .ses-controls { order:1; }
/* La gestió de les obres, JUST sota el dia. És el que decideix el contingut
   del quadre, o sigui que va abans del quadre i no al final de la pàgina. */
.ses-pagina #ses-obres-tria { order:2; }
.ses-pagina .ses-tauler-ctrls { order:3; }
.ses-pagina .ses-board-wrap { order:4; }
/* A partir d'aquí, context: es mira quan ja saps què tens al quadre. */
.ses-pagina .pt-kpi-row { order:7; }
.ses-pagina .ses-mov-wrap { order:8; }
.ses-pagina #ses-qui-es-qui { order:9; }
.ses-pagina .pt-sec-eina { order:10; }
.ses-pagina .ses-cua-block { order:11; }

/* ── L'ORDRE DE LA PÀGINA · fins a la TAULETA ────────────────────────────────
   El gerent (04-09-2026): «ataca tauleta, serà l'eina que faran servir». Amb el
   disseny aturat als 768 px, un iPad vertical (820) es quedava fora i la primera
   obra li queia a **2.329 px** — pitjor que el telèfon abans d'arreglar-lo.

   El llindar es parteix en dos perquè són dues decisions diferents:
     · **≤1366** (aquest bloc): QUIN ORDRE té la pàgina. El quadre primer i el
       context a sota. Val per a telèfon, per a tota tauleta i per a portàtil
       petit, que és on es fa servir l'eina.
     · **≤768** (el bloc de sota): COM es dibuixa el quadre. Apilat en llista,
       que només té sentit quan no hi caben columnes.

   Res desapareix del DOM: un `Output` sobre un id absent tomba el callback
   sencer. Tot el que baixa segueix a la pàgina, sota el quadre. */
@media (max-width: 1366px) {
  /* El paràgraf d'entrada explica QUÈ FA l'eina. Qui l'obre ja ho sap: la porta
     a sobre cada dia. L'explicació segueix sencera al «?». */
  .ses-pagina .pt-mod-lead { display:none; }
  .ses-pagina .ses-pregunta { display:none; }
  .ses-pagina .ses-com-va { display:none; }

  /* Primer el que és FEINA, després el que és context. Només canvia l'ordre en
     què es veuen; els elements segueixen tots al DOM. */
  .ses-pagina .pt-mod { display:flex; flex-direction:column; }
  /* ── L'ordre canvia a partir d'aquí, i no és cap contradicció ───────────
     Al PC la gestió de les obres va ABANS del quadre: és un despatx, s'obre
     per decidir què entra al pla i el gerent ho va demanar així.
     Amb l'aparell a la mà, a l'obra, no: allà el quadre és el primer i les
     obres ja estan triades des del despatx. Posar-hi la gestió al davant
     tornaria a empènyer la primera obra a 800 px, que és d'on venim.
     La resta d'ordres els declara la regla de dalt, fora de tot media query. */
  .ses-pagina #ses-obres-tria { order:5; }
  .ses-pagina .ses-tauler-ctrls { order:5; }
  .ses-pagina .ses-board-wrap { order:2; }
  .ses-pagina .pt-mod > .pt-mod-head,
  .ses-pagina .pt-mod > div:has(> .pt-back-link) {
    display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
  /* El dia i les vistes, en UNA fila que llisca. En dues files fan 126 px al
     telèfon i 194 a la tauleta, perquè allà hi caben vuit pastilles i se'n van
     a dues línies. La data NO s'escurça —saber quin dia planifiques és el que
     el gerent va demanar que no es pogués confondre— i que hi ha més coses a
     la dreta ho diu una vora esvaïda, que és el senyal que la gent coneix. */
  .ses-pagina .ses-controls { gap:8px; padding:6px; margin-bottom:8px;
    flex-direction:row; flex-wrap:nowrap; overflow-x:auto; align-items:center;
    overscroll-behavior-x:contain; scroll-snap-type:x proximity;
    -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent);
    mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent); }
  /* La llista de vistes ha de dir que NO s'embolcalla ella mateixa. En posar
     la fila en `nowrap`, el seu contenidor s'encongeix i les vuit pastilles
     s'apilaven: 214 px en columna, pitjor que les dues files que volíem
     treure. La fila que llisca és la de fora; la de dins va estirada. */
  .ses-pagina .ses-vistes-plec { flex:0 0 auto; scroll-snap-align:start; }
  .ses-pagina .ses-vistes { display:flex; flex-wrap:nowrap;
    align-items:center; gap:6px; }
  .ses-pagina .ses-dianav { flex:0 0 auto; }
  /* Obrir una obra o portar una màquina del catàleg no és el que es fa amb
     l'aparell a la mà, a l'obra: es fa assegut. Va DESPRÉS del quadre. */

  /* Dins del quadre. `display:contents` dissol la caixa de la barra: el
     cercador, el comptador i «la pròxima que posis» deixen de ser germans
     entre ells i passen a ser-ho del quadre, i així cadascun busca el seu lloc.
     El cercador es queda a dalt —és el que el gerent va demanar, escriure el
     nom per trobar algú— i els altres dos baixen. */
  .ses-pagina #ses-board > div { display:flex; flex-direction:column; }
  .ses-pagina .ses-tauler-wrap { display:flex; flex-direction:column; }
  .ses-tauler { order:2; }
  /* La barra ja no reparteix res. Des del 04-09 el cercador i «la pròxima que
     posis» viuen DINS de la columna del parc, damunt d'on es tria la gent i les
     màquines (petició del gerent), i aquí només hi queda el comptador. El
     `display:contents` que dissolia la barra ja no té cap fill a repartir:
     mantenir-lo hauria estat una regla que no fa res i que el pròxim que la
     llegís hauria de desxifrar. */
  /* L'ordre ara el porta la CAIXA, no el comptador: mentre la barra es
     dissolia, el comptador era germà del quadre i es podia ordenar sol; ara
     que torna a ser una caixa amb un sol fill, dir-l'hi a dins no fa res i la
     barra sencera es quedaria damunt del quadre. Mesurat: 27 px. */
  .ses-pagina .ses-tauler-barra { order:96; margin:6px 0 0; }
  .ses-pagina .ses-tauler-compt { margin:0; }
  /* L'avís de gòndoles es queda: baixa just sota el quadre, no s'amaga. */
  .ses-pagina .ses-banner-tr { order:94; margin:8px 0 0; }
  /* «El que convé mirar» no és germà de les columnes: és germà de tot el
     quadre, un nivell més amunt. */
  .ses-pagina .ses-det { order:95; }
  /* Si NO és avui, l'avís mana i va al davant de tot. */
  .ses-pagina .ses-avis-dia { order:0; }

  /* El parc i els trasllats, AL FINAL de la fila d'obres. A l'escriptori van
     al davant perquè s'hi veu tot alhora; a la tauleta no. Mesurat el 04-09 a
     820 px: amb les dues columnes al davant es veien **zero** obres sense
     lliscar de costat, tot i que la primera queia a 309 px de dalt. La xifra
     vertical era bona i la pantalla no servia — mesurar una sola cosa fa
     justament això.
     La gent lliure és el magatzem d'on s'omplen les obres, i el que s'ha de
     moure condiciona el dia, però cap de les dues és el dia. */
  .ses-pagina .ses-tcol-tr { order:98; }

  /* El cercador ha de seguir sent el PRIMER que es toca, també aquí.
     A l'escriptori el gerent el va voler damunt d'on es tria la gent i les
     màquines, i allà és; però en llista la columna del parc va DESPRÉS de les
     25 obres, i deixar-lo a dins voldria dir haver de passar 25 obres per
     escriure un nom — que és justament el que ell va demanar que s'acabés.
     `display:contents` dissol la caixa de la columna: els seus fills passen a
     ser germans de les columnes d'obra i cadascun busca el seu lloc. Els
     comandaments van al davant de tot; la resta del parc es queda al 99, on
     era. Cal donar ordre a TOTS els fills: sense dir-ho, els que no en tenen
     valen 0 i s'escamparien entre les obres.

     NOMÉS l'`order`, aquí: el `display:contents` que dissolia la caixa
     baixa al bloc de ≤768 (bug del CP0, 16-09-2026, mesurat al banc). Entre
     769 i 1366 `.ses-tauler` encara és `flex-direction:row` (l'apilat en
     columna no arriba fins als 768): dissoldre la caixa del parc hi fica el
     cercador com a germà de les columnes DINS d'una fila, i
     `align-self:stretch` l'estira a l'alçada de la fila i empeny la primera
     obra a x=1338, fora de la caixa de 1326 — el quadre es veia BUIT en
     portàtil i tauleta horitzontal. La classe només es defineix un cop per
     breakpoint (`tests/test_css_mobil_planificacio.py`); qui la vulgui veure
     sencera la té al bloc de ≤768. */
  .ses-pagina .ses-tcol-parc { order:99; }

  /* La capçalera de la pàgina, en UNA línia: l'enllaç d'inici, el símbol, el
     títol i el «?». El subtítol se'n va —diu què fa la pantalla, i qui l'obre
     des de l'obra ja ho sap— però segueix sencer dins del «?». */
  .ses-pagina .pt-mod-head { display:flex; align-items:center; gap:8px;
    margin:0; padding-bottom:0; min-height:44px; flex:1 1 auto; }
  .ses-pagina .pt-mod-glyph { font-size:1.15rem; }
  .ses-pagina .pt-mod-title { font-size:1.05rem; margin:0; line-height:1.2; }
  .ses-pagina .pt-mod-que-fa { display:none; }
  /* El terra de 44 px es REPETEIX aquí a posta. La guarda de la casa llegeix la
     PRIMERA regla que troba amb aquest nom, i aquesta hi és abans que la bona:
     si només digués «alinea't a la dreta», qui la llegís no sabria que el terra
     segueix garantit, i qualsevol canvi aquí el podria trepitjar. */
  .ses-pagina .pt-ajuda-boto { margin-left:auto; flex:0 0 auto;
    min-height:44px; min-width:44px; }
  .ses-pagina .pt-back-link { font-size:.82rem; flex:0 0 auto; }

  /* La franja de missatges del quadre ocupava 76 px ESTANT BUIDA. Hi és sempre
     perquè un `Output` sobre un id absent tomba el callback sencer, però una
     caixa sense res a dins no ha de reservar mitja obra de pantalla. */
  .ses-pagina .ses-fb-sticky:empty { display:none; }

  /* La capçalera de la vista NO es repeteix a l'aparell. El rètol que
     garanteix que el color no informi sol el porta la PASTILLA triada, que és
     just a sobre del quadre i va plena del color de la vista amb la seva
     icona i el seu nom. Repetir-ho aquí costava 99 px i tornava a empènyer la
     primera obra de 307 a 406 el mateix dia que es va afegir.
     Al PC sí que hi és: allà les pastilles queden lluny del contingut. */
  .ses-pagina .ses-vista-cap { display:none; }
  .ses-pagina .ses-vista { padding:2px 6px 8px; }

}

/* CONTROL (coordinador, 4a volta, 16-09-2026): a 1366 px `.ses-controls`
   carregava amb `scrollLeft=316` (el carril arrencava DESPLAÇAT, no a
   l'esquerra) i `.ses-dianav` («‹ Avui · dimecres 16/9 ›») queia a x=-295,
   fora de la pantalla — es veia «Avui» tot sol. Decisió del 04-09-2026: el
   dia que es planifica no pot faltar mai.

   Causa: el bloc de ≤1366 (just a sobre) fa `.ses-controls` una fila que
   LLISCA (`nowrap`+`overflow-x:auto`, pensada per al telèfon i la
   tauleta) i marca `.ses-vistes { scroll-snap-align:start }`; en carregar,
   el navegador «assenta» el carril al punt d'ancoratge més proper —les
   vistes—, no a l'inici real, i s'emporta el dia per davant. Empitjorava
   amb l'interruptor (217 px més a encabir). Aquesta regla ha d'anar
   DESPRÉS del bloc de ≤1366 al fitxer: mateixa especificitat de selector,
   i en un empat guanya la que el navegador llegeix més tard.

   TRIA (santi + coordinador): a partir de 769 px, aquesta fila JA NO ha
   de lliscar —és l'amplada d'escriptori i tauleta, no la del telèfon—, es
   parteix en DUES línies si cal i l'interruptor hi va al final, alineat a
   la dreta. El bloc de ≤768 (mòbil), de sota, NO es toca: hi continua
   lliscant amb el mateix ancoratge d'abans. */
@media (min-width: 769px) {
  .ses-pagina .ses-vistes { scroll-snap-align:none; }
  .ses-pagina .ses-controls { flex-wrap:wrap; overflow-x:visible;
    scroll-snap-type:none; -webkit-mask-image:none; mask-image:none; }
  /* CONTROL (PLA 16-09-2026, punt 2 «controls en UNA fila»): `flex-basis:
     100%` forçava l'interruptor Graella/Detall a la SEVA pròpia línia
     sencera dins d'un contenidor `flex-wrap:wrap` — exactament una segona
     fila garantida, encara que hi hagués espai de sobres a la primera (a
     1366 i a 1920 n'hi ha). Amb `flex:0 0 auto` i `margin-left:auto` es
     queda al MARGE DRET de la MATEIXA fila que el dia i les vistes, i
     només salta de línia si de veritat no hi cap — que és quan es permet
     una 2a fila com a últim recurs (contracte del pla). */
  .ses-pagina .ses-densitat-sel { flex:0 0 auto; justify-content:flex-end;
    display:flex; margin-left:auto; }
  /* CONTROL (PLA 16-09-2026, punt 2, mesurat en viu a 1366×768): dia +
     vistes + interruptor NOMÉS caben en una fila si les 7 pastilles de
     vistes i les 2 de l'interruptor es fan més estretes — mesurat: `.ses-
     dianav` 359px + `.ses-vistes` 1048px + `.ses-densitat-sel` 217px =
     1624px contra 1338px disponibles. Es retalla el farciment i la
     lletra (mai per sota del que ja fa servir el bloc plegat de mòbil,
     línia ~479: `.ses-chip{min-height:44px}` es queda igual perquè el
     toc no es toca). `.ses-vistes` passa a `flex-wrap:nowrap` perquè les
     7 pastilles es quedin totes en UNA línia real, no repartides en dues
     dins la seva pròpia caixa (que hauria comptat com «una fila» per a
     `.ses-controls` però hauria fet la caixa igual d'alta). */
  .ses-pagina .ses-vistes { flex-wrap:nowrap; }
  /* NOMÉS es retalla l'amplada (farciment horitzontal, lletra): l'àrea de
     toc de 44px (`min-height`) NO baixa mai — «tot element tocable ≥44px»
     és regla dura de la casa, i encongir-la seria arreglar l'alçada
     trencant l'accessibilitat. */
  .ses-pagina .ses-controls .ses-chip { padding:3px 6px; font-size:.72rem;
    gap:2px; }
  .ses-pagina .ses-nav-avui { padding:0 8px; font-size:.74rem; }
  .ses-pagina .ses-dia-label { min-width:118px; font-size:.8rem;
    padding:0 4px; }
  .ses-pagina .ses-dianav { gap:4px; }
  .ses-pagina .ses-controls { gap:8px; }
  /* El carril del parc (ordre dins de `.ses-tauler`, ≥769): la regla del
     bloc de ≤1366 (`order:99`), pensada per a quan parc encara era una
     columna més entre les d'obra, faria caure el CARRIL a la SEGONA
     columna de la graella (250px 1fr) en lloc de la primera — exactament
     al revés del que demana el pla («parc FIX a l'esquerra»). Mateixa
     especificitat i DESPRÉS al fitxer: guanya aquesta. */
  .ses-pagina .ses-tcol-parc { order:0; }
}

@media (max-width: 768px) {
  /* MODE LLISTA. Amb columnes del 78% de l'amplada, les obres visibles sense
     lliscar de costat eren ZERO: el parc n'ocupava el 70% al davant i ni la
     primera obra es veia sencera. Veure el pla del dia eren 25 lliscades.
     Apilades i plegades, en van 8-10 per pantalla. El barem d'Odoo resol el
     mateix fent columnes estretes que llisquen; aquí la llista guanya perquè
     la nostra graella no té l'hora com a eix vertical. */
  .ses-tauler { flex-direction:column; overflow-x:visible; gap:6px; }
  .ses-tcol { flex:1 1 auto; min-width:0; width:100%; }
  /* El parc AL FINAL. Apilat, anava al davant i empenyia la primera obra 523
     px avall: qui obre el quadre vol veure les obres, i la gent lliure és el
     magatzem d'on les omple. A l'escriptori es queda a l'esquerra, que allà
     es veu tot alhora. */
  .ses-tcol-parc { flex:1 1 auto; min-width:0; width:100%; }
  /* Els trasllats van DESPRÉS de les obres al telèfon (abans del parc). A
     l'escriptori van al davant perquè es veu tot alhora i el que s'ha de moure
     condiciona el dia; al mòbil, cada píxel abans de la primera obra és una
     obra menys que es veu. Mesurat: la columna els empenyia 146 px avall. */
  /* L'ORDRE del parc i dels trasllats el declara el bloc de 1366, un de sol i
     més específic que aquest: tenir-lo als dos llocs feia que el d'aquí no
     s'apliqués mai i que qui l'edités es pensés que tocava el que es veu.
     La regla nua de sobre (`.ses-tcol-parc { flex:1 1 auto; ...}`) ja no
     l'aplica MAI cap navegador: la de sota, més específica
     (`.ses-pagina .ses-tcol-parc`), sempre guanya. Es queda escrita perquè
     esborrar-la no és feina d'aquesta tanda. */

  /* CP0 (16-09-2026): `display:contents` dissol la caixa del parc NOMÉS
     aquí, ≤768. Al bloc de 1366 hi havia la mateixa regla i és exactament el
     bug que es va mesurar al banc: entre 769 i 1366 el quadre encara és una
     FILA (`.ses-tauler` no apila en columna fins als 768), i dissoldre la
     caixa hi posa el cercador com a germà de les columnes DINS d'aquella
     fila — `align-self:stretch` l'estira i empeny la primera obra fora de la
     caixa. Aquí, en canvi, `.ses-tauler` ja és `flex-direction:column`
     (línia 1139) i dissoldre la caixa és segur: els fills del parc passen a
     ser germans de les columnes d'obra, totes apilades igual. */
  .ses-pagina .ses-tcol-parc { display:contents; }
  /* `.ses-obres` (PLA 16-09-2026, embolcall NOU del carril fix): dissolta
     igual que el parc, i pel mateix motiu — a partir d'aquí `.ses-tauler`
     ja apila en columna, o sigui que dissoldre la caixa és segur: els
     seus fills (trasllats + columnes d'obra) passen a ser germans directes
     de les columnes del parc ja dissolt, exactament com abans que
     `.ses-obres` existís (regla 1: cap embolcall nou trenca el mode
     LLISTA — DOM ADDITION only, sense canviar com es veu). */
  .ses-pagina .ses-obres { display:contents; }
  /* `align-self:stretch` i no `width:100%`: `.ses-tauler` en mode llista porta
     `align-items:flex-start`, o sigui que els seus fills NO s'estiren i cadascun
     s'ajusta al seu contingut. Les columnes d'obra fan els 366 px perquè el seu
     contingut hi arriba; el selector de màquines es quedava a 220 dels 390 del
     telèfon i deixava una franja buida a la dreta (el gerent m'ho va ensenyar
     amb una captura del seu mòbil, 05-09). Provat abans amb
     `width:100% + flex:0 0 auto` i el número NO es movia: contra
     `align-items:flex-start` qui mana és `align-self`. */
  .ses-pagina .ses-tcol-parc > * { order:99; align-self:stretch; }
  /* 19-09-2026 13:30 · encàrrec del gerent, literal: «trasllats fix al
     lateral de treballadors i maquines. Sera un punt molt important. Que
     no quedi al final». El bloc de trasllats ara viu DINS de
     `.ses-tcol-parc` (tercer fill, `_bloc_trasllats_parc` a seshat.py), i
     la regla de sobre el faria caure a `order:99` igual que treballadors i
     màquines — DARRERE de les 28 obres, exactament el que aquest encàrrec
     prohibeix. Guanya per especificitat, no per ordre al fitxer:
     `.ses-tcol-parc > .ses-parc-mitat-tr` són 3 classes contra les 2 de
     `.ses-tcol-parc > *` (una classe + l'universal, que no en compta cap).
     `order:-1` el posa DAVANT de tot —també de les 28 obres (`order:0`)—:
     és el punt «molt important» que no es pot enterrar a cap mida. */
  .ses-pagina .ses-tcol-parc > .ses-parc-mitat-tr { order:-1; align-self:stretch; }
  /* 19-09-2026 · correcció del gerent: el cercador, el comptador i les
     accions ja no viuen al parc — tornen a `.ses-tauler-barra` (la seva
     casa d'abans del 04-09). Mateix criteri d'aleshores, reaplicat aquí:
     de la barra només PUJA el cercador. Mesurat el 04-09 (quan encara
     vivia dins del parc): pujant cercador+hores la primera obra passava
     de 303 px a 464; pujant NOMÉS el cercador, es queda a 311 (barem de
     la casa, 310). La caixa es dissol —`order` només ordena germans— i
     cada fill diu el seu: el cercador PRIMER, el comptador i les quatre
     accions es queden baix, amb el parc (`order:99`, com abans). */
  .ses-pagina .ses-tauler-barra { display:contents; }
  .ses-pagina .ses-tauler-barra > .ses-cerca-camp { order:-1; margin:0 0 8px;
    flex:0 0 auto; max-width:100%; width:100%; min-height:44px; }
  .ses-pagina .ses-tauler-barra > .ses-tauler-compt,
  .ses-pagina .ses-tauler-barra > .ses-accions-barra { order:99; }
  /* D3 (26-09-2026): «Endreça» és una acció més i baixa amb les altres; sense
     aquesta línia es quedava entre el cercador i les obres (52 px). */
  .ses-pagina .ses-tauler-barra > #ses-endreca { order:99; }
  /* D3: TRASLLATS es queda a dalt i obert (gerent, 19-09), però BUIT no cal
     repetir el text d'ajuda a cada càrrega ni reservar lloc a una llista
     buida. «Res per moure avui.» es queda: és la frase que diu que el dia és
     buit (santi FINAL #7, 19-09). */
  .ses-pagina .ses-parc-mitat-tr.ses-tr-buit > .ses-tcol-sub:first-of-type,
  .ses-pagina .ses-parc-mitat-tr.ses-tr-buit > .ses-tcol-cards:empty { display:none; }
  .ses-tcol-cards { max-height:38vh; overscroll-behavior-y:contain; }

  /* Plegada: s'amaguen les TARGETES i el detall, mai l'obra. El nom, el
     client, el compte de gent i el botó «Posar aquí» es queden, que és el que
     fa falta per assignar sense obrir res. */
  .ses-tcol.ses-plegada .ses-tcol-cards,
  .ses-tcol.ses-plegada .ses-tcol-sec,
  .ses-tcol.ses-plegada .ses-tcol-ritme,
  .ses-tcol.ses-plegada .ses-tcol-sub,
  .ses-tcol.ses-plegada .ses-bar { display:none; }
  /* Una fila plegada ha de caber-hi moltes: amb 210 px només se'n veien 4 de
     25, i el sentit d'aquesta pantalla és el cop d'ull. Es reparteix així:
     nom d'obra + client en dues línies petites, el compte de gent en línia, i
     el peu compacte. */
  .ses-tcol.ses-plegada { padding:6px 10px; }
  .ses-tcol.ses-plegada .ses-tcol-cap { margin-bottom:2px; min-height:0; }
  .ses-tcol.ses-plegada .ses-tcol-titol { font-size:.9rem; margin:0;
    display:-webkit-box; -webkit-line-clamp:1; -webkit-box-orient:vertical;
    overflow:hidden; }
  .ses-tcol.ses-plegada .ses-tcol-client { font-size:.76rem; margin:0; }
  .ses-tcol.ses-plegada .ses-tcol-kpis { margin:2px 0 0; font-size:.74rem; }
  .ses-tcol.ses-plegada .ses-tcol-peu { margin-top:4px; }
  .ses-tcol.ses-plegada .ses-tcol-peu .ses-btn-mini { padding:4px 8px; }
  /* Estimar les hores d'una obra és feina de despatx, no de camp: amb l'obra
     plegada el camp i el seu botó són soroll entre 25 files. Surten en obrir-la. */
  .ses-tcol.ses-plegada .ses-inp-est,
  .ses-tcol.ses-plegada .ses-btn-est { display:none; }
  /* El formulari d'apuntar trasllats i el de triar encarregat són feina de
     despatx: amb la columna plegada ocupaven 272 px de pantalla al telèfon i
     empenyien la primera obra avall. Surten en obrir-la. */
  .ses-tcol.ses-plegada .ses-tr-form,
  .ses-tcol.ses-plegada .ses-enc-form,
  .ses-tcol.ses-plegada .ses-com-form,
  .ses-tcol.ses-plegada .ses-com-llista,
  .ses-tcol.ses-plegada .ses-pet-form { display:none; }
  /* La capçalera és el control d'obrir: àrea de toc sencera i el senyal de
     que s'hi pot tocar. */
  .ses-tcol .ses-tcol-cap { cursor:pointer; min-height:44px;
    display:flex; flex-direction:column; justify-content:center; }
  .ses-tcol.ses-plegada .ses-tcol-cap::after { content:"▾  toca per obrir";
    font-size:.74rem; color:var(--pt-muted); font-weight:600; }
  .ses-tcol:not(.ses-plegada) .ses-tcol-cap::after { content:"▴";
    font-size:.74rem; color:var(--pt-muted); }

  /* «El que convé mirar»: amb 25 obres la llista feia 800 px i empenyia el
     quadre fora de la pantalla. Es queda sencera i visible —no s'amaga, que
     és informació que evita errors— però dins de la seva pròpia finestra. */
  /* «El que convé mirar» es queda —és informació que evita errors— però en
     una línia que llisca. Amb 25 obres feia 800 px; a 116 encara menjava una
     obra i mitja de les que es podrien veure. El senyal (n'hi ha) es manté;
     el detall es llegeix desplaçant-hi. */
  .ses-pagina .ses-det { max-height:52px; overflow-y:auto;
    overscroll-behavior-y:contain; padding:6px 10px; }
  .ses-pagina .ses-det-cap { font-size:.72rem; margin:0; }
  .ses-pagina .ses-det-list { margin:2px 0 0; font-size:.8rem; }

  /* La navegació de dia i el selector de vistes: 146 px per a dues files de
     controls. Es prem el que sobra sense tocar l'àrea de toc de 44 px. */
  .ses-pagina .ses-dianav { gap:6px; }
  .ses-pagina .ses-dia-label { font-size:.86rem; }

  /* Indicadors: una fila que llisca, no una graella de dos per dos que ocupa
     mitja pantalla abans que es vegi cap obra. */
  .ses-pagina .pt-kpi-row { display:flex; flex-wrap:nowrap; overflow-x:auto;
    gap:8px; scroll-snap-type:x proximity; }
  .ses-pagina .pt-kpi { flex:0 0 auto; min-width:44%; scroll-snap-align:start;
    padding:8px 10px; }
  .ses-pagina .pt-kpi-val { font-size:1.4rem; }

  /* El selector de vistes NO es toca aquí: ja llisca per la regla de la
     línia 341 d'aquest mateix fitxer. Afegir-n'hi una de més específica seria
     tornar a tenir dues regles per a la mateixa classe al mateix breakpoint,
     que és el defecte que aquesta tanda ha vingut a treure. */

  /* Les instruccions d'ús i la frase d'orientació de la vista s'amaguen des
     del bloc de 1366: al telèfon i a la tauleta, cada línia de text abans del
     quadre és una obra menys que es veu. Segueixen senceres al «?».
     El que queda AQUÍ és només el que depèn de dibuixar el quadre en llista. */
  /* El comptador de gent lliure: aquí només la mida de lletra. Que BAIXI sota
     el quadre ho decideix el bloc de 1366, perquè val igual a la tauleta. */
  .ses-tauler-compt { font-size:.8rem; }
  /* Les TRES caselles de cerca de la pàgina (la del quadre, la d'obres i la de
     màquines) a tota l'amplada i amb l'àrea de toc de 44 px. Es queda aquí i no
     puja a 1366: al telèfon és el que ja hi havia, i a la tauleta les altres
     dues no ho han demanat. La del quadre porta la seva pròpia regla allà.
     `flex:0 0 auto` NO és cosmètica: la regla d'escriptori és `flex:1 1 260px`,
     i en columna aquest `flex-basis` deixa de ser amplada i passa a ser
     **alçada** — mesurat el 03-09: la caixa feia 260 px d'alt. */
  .ses-tauler-cerca { flex:0 0 auto; max-width:100%; width:100%;
    min-height:44px; }
}

/* CTA d'empty state (HORUS i futurs): botó prominent, no una nota al peu.
   Autocontingut perquè funcioni sobre un <a> (dcc.Link) sense dependre de .btn. */
.pt-empty-cta { margin-top: 16px; }
.pt-empty-cta a.pt-btn,
.pt-empty-cta a {
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 10px 20px; background: var(--pt-verd); color: #fff;
  border-radius: var(--pt-radius-sm, 9px); text-decoration: none;
  font-weight: 600; font-size: .9rem;
}
.pt-empty-cta a:hover { background: var(--pt-verd-dark); color: #fff; }

/* ══ IMHOTEP · gestió de recursos (Fase C) ══════════════════════════════ */
.rec-grup-cap { display:flex; flex-wrap:wrap; align-items:center; gap:8px;
  margin-bottom:8px; }
.rec-chips { display:flex; flex-wrap:wrap; gap:6px; margin:4px 0 8px; }
.rec-chip { display:inline-flex; align-items:center; gap:2px; padding:3px 4px 3px 10px;
  border:1px solid var(--pt-line); border-radius:999px; background: var(--pt-surface);
  font-size:.86rem; }
/* La × es veu petita però l'àrea tocable és ≥44px (::after invisible) — acció
   destructiva usable amb guants al mòbil (WCAG 2.5.8). */
.rec-chip-x { position:relative; border:none; background:transparent;
  cursor:pointer; font-size:1rem; line-height:1; color: var(--pt-muted);
  min-width:24px; min-height:24px; padding:0; }
.rec-chip-x::after { content:""; position:absolute; top:50%; left:50%;
  transform:translate(-50%,-50%); width:44px; height:44px; }
.rec-chip-x:hover { color: var(--pt-warn); }
.rec-llista { display:flex; flex-direction:column; }

/* Coherència /recursos: chip de tipus/categoria, filtre i blocs del form. */
/* Chip: text carbó sobre pastel (contrast ~9,6:1, AA) — no verd sobre verd. */
.rec-tipus-tag { display:inline-block; margin-left:6px; padding:1px 8px;
  background:var(--pt-verd-pastel); color:var(--pt-text);
  border-radius:var(--pt-radius-sm); font-size:.78rem; font-weight:600;
  white-space:nowrap; }
/* Tag secundari (grau de conveni): gris, sense fons, per no competir amb la funció. */
.rec-cat-tag { display:inline-block; margin-left:6px; color:var(--pt-muted);
  font-size:.78rem; font-weight:600; white-space:nowrap; }
/* Filtre ancorat visualment a la LLISTA de sota (no al formulari de dalt). */
.rec-filtre-row { display:flex; align-items:center; gap:8px; margin:16px 0 6px;
  flex-wrap:wrap; border-top:1px solid var(--pt-line); padding-top:12px; }
.rec-filtre-dd { min-width:240px; }
/* Blocs del form: accent verd PUR + fons propi → "dues coses separades". */
.rec-form-block { border-left:3px solid var(--pt-verd); padding-left:14px;
  padding-right:10px; background:var(--pt-soft);
  border-radius:0 var(--pt-radius-sm) var(--pt-radius-sm) 0; }
.rec-form-block > strong { display:block; margin-bottom:6px; color:var(--pt-verd-dark); }
.rec-sub-note { color:var(--pt-muted); font-size:.875rem; margin:0 0 6px;
  line-height:1.5; }

/* Flota unificada: pestanyes del mòdul (📍 Ara mateix / 📊 Estat i ús / ⛽ Consum). */
/* Marge retallat (ronda 5 del judici cec): la tira de pestanyes costava
   79 px MESURATS al navegador, i cada 32 px d'aquests son una fila de
   taula que no es veu. El `min-height:44px` del tab NO es toca: es el
   minim tocable de la casa i no es negocia per guanyar una fila. */
.flota-tabs { margin:8px 0 10px; border-bottom:1px solid var(--pt-line); }
.flota-tab { border:none !important; background:transparent !important;
  color:var(--pt-muted) !important; font-weight:600; font-size:.95rem;
  min-height:44px !important; display:inline-flex !important; align-items:center;
  gap:5px; padding:8px 18px !important;
  border-bottom:3px solid transparent !important; }
.flota-tab:hover { color:var(--pt-verd-dark) !important;
  background:var(--pt-verd-pastel) !important; }
/* Actiu: PINDOLA SOLIDA, la mateixa estetica que MIDGARD te fixada per a tota
   la plataforma («el gerent vol UNA sola estetica de pestanyes», style.css:434,
   passada UX del 07-25). DUAT reutilitzava el nom `flota-tab*` pero pintava un
   subratllat, i qui ve de MIDGARD nota que «es comporten diferent» sense saber
   dir per que. NO nomes color: la pindola canvia superficie, pes i contrast
   (WCAG 1.4.1), i el blanc sobre verd fosc dona 8,6:1. */
.flota-tab-sel { color:#FFFFFF !important; font-weight:600;
  background:var(--pt-verd-dark) !important;
  border-radius:999px !important;
  border-bottom:3px solid transparent !important; }
.flota-tab-sel:hover { color:#FFFFFF !important;
  background:var(--pt-verd-dark) !important; }
.flota-tab-cards { display:flex; flex-direction:column; }
@media (max-width:480px) {
  .flota-tabs { overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .flota-tab { padding:8px 10px !important; font-size:.82rem !important; }
}

/* Flota unificada: commutador de vistes (Llista/Mapa/Resum), D-A1 22-08.
   Bloc NOU i additiu: .flota-tab* NO es toca — el fan servir economia.py,
   licitacions.py, responsable.py i tools/sonda_densitat.js fora de /flota.
   La pindola es copia literal de .flota-tab-sel (mateixa superfície verd
   fosc, mateix contrast 8,6:1 blanc-sobre-verd-fosc), sense `!important`:
   aquí no hi ha cap DOM de dcc.Tabs a vèncer. */
.pt-commut { display:flex; gap:6px; margin:8px 0 10px; flex-wrap:wrap; }
.pt-commut-btn { border:1px solid var(--pt-line); background:var(--pt-surface);
  color:var(--pt-muted); font-weight:600; font-size:.95rem;
  min-height:44px; display:inline-flex; align-items:center; gap:5px;
  padding:8px 18px; border-radius:999px; cursor:pointer; }
.pt-commut-btn:hover { color:var(--pt-verd-dark); background:var(--pt-verd-pastel); }
.pt-commut-sel { border:1px solid transparent; color:#FFFFFF; font-weight:600;
  background:var(--pt-verd-dark); border-radius:999px;
  min-height:44px; display:inline-flex; align-items:center; gap:5px;
  padding:8px 18px; cursor:default; }
@media (max-width:480px) {
  .pt-commut { overflow-x:auto; -webkit-overflow-scrolling:touch; flex-wrap:nowrap; }
  .pt-commut-btn, .pt-commut-sel { padding:8px 10px; font-size:.82rem; }
}

/* Licitacions públiques (/licitacions) */
.lic-obj { line-height:1.35; }
/* .875rem (12.25px) = pis mínim de text amb informació (IDUN DS-001). */
.lic-sub { display:block; color:var(--pt-muted); font-size:.875rem; line-height:1.45; }
.lic-classif { color:var(--pt-verd-dark); font-weight:600; }
.lic-mini { color:var(--pt-muted); font-size:.8rem; }
.lic-strong { font-weight:700; color:var(--pt-verd-dark); }
/* Enllaç amb àrea de toc >=44px (IDUN DS-004, WCAG 2.5.8). */
.lic-link { display:inline-block; min-height:44px; padding:10px 2px; line-height:24px;
  color:var(--pt-verd-dark); font-weight:600; text-decoration:none; white-space:nowrap; }
.lic-link:hover { text-decoration:underline; }

/* Estats de la clàusula del 5% d'àrid — color propi, no només caràcter (IDUN DS-002). */
.lic-estat-ok  { color:var(--pt-verd-dark); font-weight:600; font-size:.875rem; }
.lic-estat-err { color:var(--pt-warn-dark); font-weight:600; font-size:.875rem; }
.lic-estat-pnd { color:var(--pt-muted); font-size:.875rem; }

/* Badge de procediment i urgència de termini. */
.lic-badge { display:inline-block; background:var(--pt-soft); color:var(--pt-text);
  border:1px solid var(--pt-line); border-radius:var(--pt-radius-sm); padding:2px 8px; font-size:.8rem;
  font-weight:600; white-space:nowrap; }
.lic-termini { font-weight:600; }
.lic-urg-sub { color:var(--pt-muted); font-size:.8rem; font-weight:400; }
.lic-urg-alta { color:var(--pt-warn-dark); font-weight:700; }
.lic-urg-alta .lic-urg-sub { color:var(--pt-warn-dark); }
.lic-urg-mitja { color:var(--pt-text-ambre); font-weight:700; }
.lic-urg-mitja .lic-urg-sub { color:var(--pt-text-ambre); }

/* Estat de dades + llegenda dels dos nivells. */
.lic-fresc { color:var(--pt-muted); font-size:.85rem; margin:2px 0 12px; }
.lic-llegenda { display:flex; flex-wrap:wrap; gap:10px; margin:0 0 16px; }
.lic-leg { font-size:.85rem; color:var(--pt-text); background:var(--pt-surface);
  border:1px solid var(--pt-line); border-left-width:4px; border-radius:var(--pt-radius-sm);
  padding:7px 12px; line-height:1.4; }
.lic-leg-n1 { border-left-color:var(--pt-verd); }
.lic-leg-n2 { border-left-color:var(--pt-blau); }

/* ── PRESSUPOST · l'editor (/pressupost) ──────────────────────────────────
   Reutilitza els inputs de SESHAT (.ses-inp-*, .ses-tr-form) i el sistema de
   targetes/taules de _modbase. Aquí només el que és propi d'aquesta pàgina:
   el desplegable, el retorn d'una acció d'escriptura i els dos distintius de
   l'arbre (l'estat i el capítol). */
.pt-dd { min-width:180px; flex:1; }
.pt-dd.ses-inp-s { flex:0 0 170px; min-width:170px; }
.ses-inp-s { width:150px; min-height:38px; border:1.5px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); padding:4px 10px; font-family:inherit; font-size:.95rem;
  background:var(--pt-surface); color:var(--pt-text);
  transition:border-color .15s ease, box-shadow .15s ease; }
.ses-inp-s:focus, .ses-inp-s:focus-visible { outline:none;
  border-color:var(--pt-verd); box-shadow:0 0 0 3px var(--pt-verd-pastel); }

/* Retorn d'escriptura. Mai NOMES el color: el text ja diu que ha passat, i
   el simbol el repeteix per a qui no distingeixi verd de vermell (WCAG 1.4.1). */
.pt-fb { margin:10px 0; }
.pt-fb-ok, .pt-fb-err { border-radius:var(--pt-radius); padding:10px 14px;
  font-size:.92rem; border:1px solid; }
.pt-fb-ok { background:var(--pt-verd-pastel); border-color:var(--pt-verd);
  color:var(--pt-text); }
.pt-fb-ok::before { content:"✔ "; font-weight:700; }
.pt-fb-err { background:var(--pt-soft); border-color:var(--pt-warn);
  color:var(--pt-warn-dark); }
.pt-fb-err::before { content:"⚠ "; font-weight:700; }

/* «Certificacions emeses» amb els mesos a l'eix horitzontal (22-08). Una
   cel·la per mes, i l'estat NO es diu nomes amb el color: l'aprovada porta pes
   i l'anul·lada va ratllada, que es la forma. El motiu i qui la va emetre
   viatgen al `title` — la taula plana en tenia una columna cadascun i amb els
   mesos a l'eix no hi caben, pero perdre-ho seria tornar a corregir a cegues. */
.pt-cert-aprovada { font-weight:600; color:var(--pt-verd-dark); }
.pt-cert-anullada { text-decoration:line-through; color:var(--pt-muted);
  font-size:.78rem; cursor:help; margin-left:4px; }

/* LA CUA DE REVISIO D'HORES (22-08). Es llegeix per OBRA: cada obra porta el
   seu encapcalament i la seva taula, i la unitat es la LINIA que no quadra, mai
   la persona. La nota i el boto van a la MATEIXA linia: apilats, la fila creix
   el doble i deixa de llegir-se d'una ullada — i es el que passava sense
   aquesta regla, perque la classe no en tenia cap. */
.ses-cua-revisio { display:flex; flex-direction:column; gap:14px; }
.ses-cua-obra .ses-det-cap { margin:0 0 4px; font-size:.82rem;
  color:var(--pt-muted); letter-spacing:.02em; }
.ses-cua-resol { display:flex; align-items:center; gap:8px; flex-wrap:wrap;
  justify-content:flex-end; }
/* El punt d'equilibri, i les DUES vores es van veure al navegador: amb 180px
   la casella no cabia i el boto queia a sota (una nota i el seu boto en dues
   linies es llegeixen com dues coses); amb `min-width:0` la casella
   s'encongia fins a DESAPAREIXER, i un camp que no es veu no es un camp —
   pitjor que apilat. 130px i `wrap`: es veu sempre, i nomes s'apila quan de
   debo no hi cap. */
.ses-cua-resol .ses-inp-m { min-width:130px; flex:1 1 130px; }
.ses-cua-resol .pt-btn { flex:0 0 auto; }
@media (max-width: 768px) {
  /* A un telefon la nota ocupa tota l'amplada i el boto va sota, alineat amb
     ella: aqui apilar SI que es correcte, i s'ha de dir. */
  .ses-cua-resol { justify-content:flex-start; }
  .ses-cua-resol .ses-inp-m { width:100%; }
}

/* La FILA DE TOTALS de la relacio valorada (22-08). El paper la porta des del
   21-08 amb fons i linia; a la pantalla hi era sense cap pes i es llegia com una
   linia mes. Vora a sobre i fons: es el que separa un total d'una fila. */
.pt-rv-totals tbody tr:last-child td { border-top:2px solid var(--pt-verd);
  background:var(--pt-verd-pastel); font-weight:600; }

/* Estat del pressupost. El pes i la vora el fan llegible en gris tambe. */
.pt-tag { display:inline-block; border:1px solid var(--pt-line);
  border-radius:999px; padding:2px 10px; font-size:.78rem; font-weight:600;
  color:var(--pt-muted); background:var(--pt-soft); vertical-align:middle; }
.pt-tag.ok { border-color:var(--pt-verd); color:var(--pt-text);
  background:var(--pt-verd-pastel); }
.pt-tag.warn { border-color:var(--pt-warn); color:var(--pt-warn-dark); }
/* fons propi: nomes amb la vora, "ofert" i "esborrany" eren indistingibles a
   la llista, que es on s'escaneja l'estat de cop d'ull. */
.pt-tag.gold { border-color:var(--pt-blau); color:var(--pt-text);
  background:var(--pt-blau-pastel); }

/* Un capitol no es una partida: el to el separa sense cridar. Al hover, el
   gris sobre el verd pastel es queda a 4,58:1 -- passa AA per 0,08, un marge
   que qualsevol pantalla es menja. Sobre fila activa, text ple (13,1:1). */
.pt-cap { color:var(--pt-muted); letter-spacing:.02em; }
.pt-table tr:hover .pt-cap { color:var(--pt-text); }

/* Sagnat de l'arbre PER NIVELL. Abans es feia amb espais dins d'un span i
   l'HTML els col·lapsa: totes les files sortien al mateix marge i la jerarquia
   no es veia (el contrari del que la pagina promet). 16px = el grid de 8pt del
   sistema. Patro de treegrid del WAI-ARIA: sagnat per estil, mai per caracters. */
.pt-arbre-nom { display:inline-flex; align-items:baseline; }

/* Target tactil dels desplegables: Dash els renderitza a ~36px i son l'entrada
   de cada formulari d'aquesta pagina. 44px es el minim que es pot encertar amb
   el dit a la primera (WCAG 2.5.5). Va a TOTS els .pt-dd, no nomes als petits:
   la regla anterior nomes cobria .pt-dd.ses-inp-s i deixava fora els sis
   desplegables amples (triar pressupost, partida, recurs...). */
.pt-dd .Select-control, .pt-dd .Select-placeholder,
.pt-dd .Select--single > .Select-control .Select-value { min-height:44px; }
.pt-dd .Select-placeholder, .pt-dd .Select-value { line-height:44px; }
.ses-radio input[type="checkbox"] { width:20px; height:20px;
  margin-right:6px; vertical-align:middle; }
.ses-radio label { display:inline-flex; align-items:center; min-height:44px; }

@media (max-width: 768px) {
  .ses-inp-s, .pt-dd.ses-inp-s { width:100%; flex:1 1 100%; min-height:44px; }
  .pt-dd { min-width:100%; }
}

/* ── La pantalla d'entrada · accions, no llocs ────────────────────────────
   Concepte del gerent (19-08): una pregunta i respostes grans, pensades per a
   una ma i el sol de cara. Res centrat: a l'esquerra s'escaneja, i l'ull no ha
   de tornar al mig a cada linia. */
.pt-home { max-width: 760px; margin: 0 auto; padding: 8px 0 40px; }
.pt-home-q { font-size: 1.55rem; font-weight: 600; letter-spacing: -.015em;
  margin: 6px 0 18px; text-wrap: balance; }

.pt-acc-llista { display: flex; flex-direction: column; gap: 10px; }
.pt-acc { display: flex; flex-direction: column; justify-content: center;
  gap: 3px; min-height: 68px; padding: 14px 18px;
  background: var(--pt-surface); border: 1px solid var(--pt-line);
  border-radius: var(--pt-radius); box-shadow: var(--pt-shadow);
  text-decoration: none; color: var(--pt-text);
  transition: border-color .15s ease, transform .15s ease; }
.pt-acc:hover, .pt-acc:focus-visible { border-color: var(--pt-verd);
  transform: translateY(-1px); }
.pt-acc-verb { font-size: 1.12rem; font-weight: 600; line-height: 1.25; }
/* El recompte es DADA: mateixa amplada de xifra i color de marca segur. */
.pt-acc-n { font-size: .92rem; color: var(--pt-text-verd); font-weight: 500;
  font-variant-numeric: tabular-nums; }
.pt-acc-sub { font-size: .92rem; color: var(--pt-muted); }

/* Tot el tauler, a sota i tranquil: no es perd res, pero no competeix. */
.pt-home-peu { margin-top: 34px; padding-top: 18px;
  border-top: 1px solid var(--pt-line); }
.pt-home-peu-t { font-size: .78rem; font-weight: 600; letter-spacing: .11em;
  text-transform: uppercase; color: var(--pt-muted); margin: 0 0 14px; }
.pt-mod-mini-grup { margin-bottom: 14px; }
.pt-mod-mini-pilar { display: block; font-size: .74rem; color: var(--pt-muted);
  margin-bottom: 6px; }
.pt-mod-mini-fila { display: flex; flex-wrap: wrap; gap: 8px; }
.pt-mod-mini { display: inline-flex; align-items: center; gap: 7px;
  min-height: 44px; padding: 8px 14px; border-radius: var(--pt-radius-sm);
  background: var(--pt-soft); border: 1px solid var(--pt-line);
  color: var(--pt-text); text-decoration: none; font-size: .9rem; }
.pt-mod-mini:hover, .pt-mod-mini:focus-visible { border-color: var(--pt-verd);
  background: var(--pt-verd-pastel); }
.pt-mod-mini-glyph { font-size: 1rem; }

@media (max-width: 768px) {
  .pt-home-q { font-size: 1.35rem; }
  .pt-acc { min-height: 72px; }        /* dit gros, guants, sol de cara */
  .pt-mod-mini { flex: 1 1 calc(50% - 4px); justify-content: center; }
}

/* ═════════════════════════════════════════════════════════════════════════
   /avui · el semàfor i el full de ruta (vies 2 i 1 de la proposta del 19-08)

   Dues llistes, no dues graelles de targetes: totes dues es llegeixen de dalt
   a baix i cap element ha de competir amb el del costat. Els colors surten
   dels tokens de text (--pt-text-*), mai dels de fons: --pt-ambre és 2,86:1 i
   com a text no es pot fer servir.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── El semàfor ─────────────────────────────────────────────────────────── */
.pt-exc-llista { display: flex; flex-direction: column; }
.pt-exc { display: flex; align-items: center; gap: 12px;
          padding: 12px 2px; border-bottom: 1px solid var(--pt-line); }
.pt-exc:last-child { border-bottom: 0; }

/* LA LÍNIA SENCERA ÉS LA PORTA (20-09-2026).
   `.pt-exc` era un <div> amb només la xifra clicable; ara és un <a>. Sense
   aquestes tres línies sortiria subratllat i blau, que a dins d'una llista
   d'alarmes es llegeix com un error. L'alçada mínima de 44px no és decoració:
   és el que el dit pot encertar, i aquesta fila és la porta més important del
   redisseny. */
a.pt-exc, a.pt-exc:hover, a.pt-exc:focus {
  text-decoration: none; color: inherit; min-height: 44px; }
a.pt-exc:hover { background: var(--pt-soft); }
a.pt-exc:focus-visible { outline: none; box-shadow: var(--pt-focus); }
/* `--pt-focus` és un BOX-SHADOW, no un color: posat a `outline` no pinta
   res i el focus desapareix en silenci. Ho diu el comentari de la línia
   3200 d'aquest mateix fitxer i ho vigila `tests/test_elevacio_tokens.py`. */
.pt-exc-bar { flex: 0 0 3px; align-self: stretch; min-height: 34px;
              border-radius: 2px; background: var(--pt-muted); }
.pt-exc-bar.mal { background: var(--pt-text-warn); }
.pt-exc-bar.avis { background: var(--pt-text-ambre); }
.pt-exc-cos { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto;
              min-width: 0; }
.pt-exc-t { font-size: .98rem; font-weight: 600; line-height: 1.3; }
.pt-exc-p { font-size: .86rem; color: var(--pt-muted); line-height: 1.4; }
/* La xifra és l'ancoratge i alhora la porta al detall: alineada a la dreta,
   tabular perquè les columnes de números no ballin. */
.pt-exc-x { flex: 0 0 auto; font-size: .95rem; font-weight: 600;
            font-variant-numeric: tabular-nums; text-decoration: none;
            color: var(--pt-text); padding: 6px 8px; min-height: 44px;
            display: inline-flex; align-items: center;
            border-radius: var(--pt-radius-sm); }
.pt-exc-x.mal { color: var(--pt-text-warn); }
.pt-exc-x.avis { color: var(--pt-text-ambre); }
.pt-exc-x:hover, .pt-exc-x:focus-visible { background: var(--pt-soft); }
.pt-exc-calma { color: var(--pt-text-verd); font-size: .95rem; font-weight: 500;
                margin: 4px 0; }
.pt-exc-mes { display: inline-block; margin-top: 10px; font-size: .86rem;
              color: var(--pt-muted); }

/* ── El full de ruta ────────────────────────────────────────────────────── */
.pt-ruta { display: flex; flex-direction: column; gap: 12px; }
.pt-ruta-bloc { border: 1px solid var(--pt-line); border-radius: var(--pt-radius);
                padding: 12px 14px; }
.pt-ruta-bloc.lliure { background: var(--pt-soft); display: flex;
                       justify-content: space-between; align-items: center;
                       gap: 10px; flex-wrap: wrap; }
.pt-ruta-cap { display: flex; justify-content: space-between; align-items: flex-start;
               gap: 10px; margin-bottom: 8px; }
.pt-ruta-obra { margin: 0; font-size: 1rem; font-weight: 600; line-height: 1.3; }
.pt-ruta-sub { margin: 2px 0 0; font-size: .84rem; color: var(--pt-muted); }
.pt-ruta-persona { display: flex; justify-content: space-between; gap: 12px;
                   padding: 6px 0; font-size: .93rem;
                   border-top: 1px solid var(--pt-line); }
.pt-ruta-maq { color: var(--pt-text-verd); text-align: right; }
.pt-ruta-maq.buida { color: var(--pt-muted); font-style: italic; }
.pt-ruta-lliure { font-size: .93rem; font-weight: 600;
                  font-variant-numeric: tabular-nums; }
.pt-ruta-buit { color: var(--pt-muted); margin: 0 0 12px; line-height: 1.5; }

/* ── L'etiqueta d'estat i el títol del detall ───────────────────────────── */
.pt-chip { display: inline-flex; align-items: center; font-size: .78rem;
           font-weight: 500; padding: 3px 9px; border-radius: 999px;
           background: var(--pt-soft); color: var(--pt-muted);
           white-space: nowrap; }
.pt-chip.ok { background: var(--pt-verd-pastel); color: var(--pt-verd-dark); }
/* El detall baixa de lloc, i el títol ho ha de dir sense cridar. */
.pt-detall-t { margin: 26px 0 12px; font-size: .8rem; font-weight: 600;
               text-transform: uppercase; letter-spacing: .06em;
               color: var(--pt-muted); }

@media (max-width: 768px) {
  /* A l'obra, amb una mà: la xifra no s'encongeix i la fila creix. */
  .pt-exc { padding: 14px 2px; }
  .pt-exc-x { min-height: 48px; }
  .pt-ruta-persona { padding: 8px 0; }
  .pt-ruta-cap { flex-direction: column; }
}

/* ── Control econòmic · barres de la cartera per estat ──────────────────
   Una sola tinta: els estats ja porten el nom escrit i codificar-los per to
   afegiria un canal que en protanòpia no diu res (verd i argila de marca es
   diferencien en dE 1,5). La barra només ha de dir la MAGNITUD. */
.ce-barres { display:flex; flex-direction:column; gap:14px; }
.ce-barra-cap { display:flex; align-items:center; gap:10px; margin-bottom:5px; }
.ce-barra-n { color:var(--pt-muted); font-size:.85rem; }
.ce-barra-eur { margin-left:auto; font-weight:600; color:var(--pt-text); }
.ce-barra-solc { background:var(--pt-track); border:1px solid var(--pt-track-vora);
  border-radius:999px; height:10px; overflow:hidden; }
.ce-barra-omplert { background:var(--pt-verd); height:100%; border-radius:999px;
  min-width:3px; }
@media (max-width: 480px) {
  .ce-barra-cap { flex-wrap:wrap; gap:6px; }
  .ce-barra-eur { margin-left:0; width:100%; }
}

/* ── Les PASTILLES del pressupost ───────────────────────────────────────
   Una partida sencera per peca. La CARA la posa .ses-card, que es el patro de
   targeta que ja fa servir el tancament del dia a planificacio: el gerent ja
   el te vist i aprovat, i dues cares diferents per a la mateixa idea nomes
   obliguen a aprendre-se-la dues vegades. Aqui nomes hi ha el que .ses-card
   no sap fer: el SAGNAT per nivell de l'arbre.
   NO es fa servir .ses-grid: es un mosaic de columnes i destruiria l'ordre de
   lectura que l'arbre es guanya recorrent pare-abans-que-fills. */
.pt-pastilles { display:flex; flex-direction:column; gap:10px; }

/* L'ARBRE COM A TAULA (22-08). El patro central del barem: «les linies son UNA
   taula». La sagnia de la jerarquia la posa `style_data_conditional` per
   {nivell} des del Python —es PRESENTACIO i no pot anar enganxada al text del
   codi, o el codi deixa de ser el codi—, aixi que aqui nomes hi ha el que
   diu que una fila es CLICABLE i la cara del panell de la fila triada.
   Sense cap boto a l'arbre, el cursor es l'unica pista que hi ha: sense
   aixo la taula sembla nomes de lectura. */
#pres-arbre .dash-cell { cursor:pointer; }
#pres-arbre .dash-spreadsheet-container .dash-spreadsheet-inner tr:hover td {
  background:var(--pt-verd-pastel); }

/* El panell de la fila triada: les accions i les hores, UNA vegada i a sota.
   Va marcat amb la vora de marca a l'esquerra, la mateixa que du la fila
   seleccionada a la taula: es el que lliga el panell amb la linia de la qual
   parla. Sense el lligam, a un pressupost de 40 linies no se sap de qui es. */
.pt-arbre-tria { margin-top:10px; padding:10px 12px;
  background:var(--pt-soft); border:1px solid var(--pt-line);
  border-left:3px solid var(--pt-verd); border-radius:8px; }
.pt-arbre-tria-cap { display:flex; flex-wrap:wrap; gap:4px; align-items:baseline;
  margin-bottom:6px; }
.pt-arbre-tria-desc { color:var(--pt-muted); }
.pt-past-hores { list-style:none; margin:8px 0 0; padding:0; }
.pt-past-q { font-weight:600; color:var(--pt-text); }
.pt-past-cost { color:var(--pt-text); }
/* Un cost desconegut no es pinta de vermell d'alarma: no es un error, es una
   dada que falta. Pero s'ha de distingir d'un import de debo. */
.pt-past-sensecost { color:var(--pt-text-ambre); font-style:italic; }
.pt-past-btn { margin-top:8px; }
.pt-past-form { margin-top:10px; padding-top:10px;
  border-top:1px dashed var(--pt-line); }
.pt-past-camp { display:flex; flex-direction:column; gap:3px; }
.pt-past-lbl { font-size:.8rem; color:var(--pt-muted); }
/* ── Passar d'estat, per passes ─────────────────────────────────────────
   El gerent (20-08): «no m'agrada el format. Tot junt.» Eren quatre controls
   dins d'un .ses-tr-form, que es un flex que ho ajunta tot. El comportament no
   canvia; el que canvia es que la passa que NO te marxa enrere no s'assembli a
   les que si en tenen. */
.pt-estat { display:flex; flex-direction:column; gap:12px; }
.pt-estat-bloc { display:flex; flex-direction:column; gap:6px;
  padding:10px 12px; border:1px solid var(--pt-line);
  border-radius:var(--pt-radius-sm); background:var(--pt-surface); }
.pt-estat-pas { font-size:.78rem; font-weight:600; letter-spacing:.04em;
  text-transform:uppercase; color:var(--pt-muted); }
/* La vora d'argila NO es l'unica marca: el text del pas ja diu «nomes per
   ACCEPTAR» i la casella diu que no es pot desfer. El color hi afegeix, no
   informa tot sol. */
.pt-estat-greu { border-color:var(--pt-blau); background:var(--pt-blau-pastel); }
.pt-estat-accio { border:0; background:none; padding:0; }
@media (max-width: 480px) { .pt-estat-bloc { padding:10px; } }

/* Corregir una linia d'hores des de la seva pastilla. */
.pt-past-hora-eines { display:inline-flex; gap:6px; margin-left:6px; }
.pt-past-mini { min-height:44px; padding:8px 12px; font-size:.8rem;
  border:1px solid var(--pt-line); border-radius:999px;
  background:var(--pt-soft); color:var(--pt-text); cursor:pointer; }
.pt-past-mini:hover { background:var(--pt-verd-pastel);
  border-color:var(--pt-verd); }

/* 1 · El boto que ESBORRA no es pot veure igual que el que desa. La classe
   s'usava i no existia: «Desa» i «Treu la linia» sortien identics, de costat, i
   treure esborra la fila de debo.
   DS-002 deia ARGILA; el 20-08 va passar a VERMELL, i el motiu esta mesurat:
   l'argila i l'alerta tenien ΔE 7,3 amb visio NORMAL —per sota del terra de 15—
   o sigui que ningu els distingia, i volien dir coses diferents. Destructiu i
   alerta son la mateixa cosa: un sol color. */
.pt-btn-perill, .pt-btn-perill:hover { background:var(--pt-warn);
  border-color:var(--pt-warn); color:#FFFFFF; }
/* El «Corregeix» de cada linia entra al mateix contracte de focus que la resta. */
.pt-past-mini:focus-visible { outline:none; box-shadow:var(--pt-focus); }

/* Els botons d'una pastilla, en fila i amb el target de la casa. */
.pt-past-botons { display:flex; gap:8px; flex-wrap:wrap; margin-top:8px; }
.pt-past-botons .pt-past-btn { margin-top:0; }

/* ── Passada IDUN (20-08): jerarquia de SUPERFICIE ──────────────────────
   El diagnostic: DUAT nomes tenia UN tipus de capsa (.pt-sec, blanca i neutra)
   i UN tipus de boto de pes ple (.pt-btn verd solid), i els aplicava igual al
   contingut i a les eines. En obrir un pressupost es veien capses identiques
   apilades i desenes de botons verds competint entre ells. Les dues peces de
   recanvi ja existien a la casa; nomes no s'havien aplicat aqui. */

/* Una EINA no es veu com una DADA: accent superior als blocs de formulari. */
.pt-sec-eina { border-top: 3px solid var(--pt-verd); }

/* Els botons DINS d'una pastilla son secundaris: n'hi ha ~78 en un pressupost
   real i no poden competir amb el boto de debo de cada formulari. */
.pt-past-btn.pt-past-mini { min-height:44px; padding:8px 12px; }

/* La casella de confirmar i el boto que esborra, junts i separats de la resta. */
.pt-past-perill { display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:8px 10px; border:1px solid var(--pt-blau);
  background:var(--pt-blau-pastel); border-radius:var(--pt-radius-sm); }

/* El formulari d'afegir, amb el tipus a dalt i els camps que en depenen. */
.pt-fila-form { display:flex; flex-direction:column; gap:10px; }

/* ── Com avança l'obra: els mesos a dalt ────────────────────────────────
   Peticio del gerent (20-08). Una peça per periode, en ordre de calendari.
   NO es una graella auto-fill: l'ordre cronologic es la informacio, i un
   mosaic que reflueix per amplada el destruiria. */
.pt-mesos { display:flex; gap:10px; overflow-x:auto; padding-bottom:6px; }
.pt-mes { flex:0 0 190px; background:var(--pt-surface);
  border:1px solid var(--pt-line); border-radius:var(--pt-radius-sm);
  padding:12px 14px; }
.pt-mes-nom { font-size:.8rem; font-weight:600; letter-spacing:.04em;
  color:var(--pt-muted); text-transform:uppercase; }
.pt-mes-import { font-size:1.35rem; font-weight:600; color:var(--pt-text);
  margin:2px 0 4px; }
.pt-mes-acum { font-size:.84rem; color:var(--pt-muted); }
.pt-mes-solc { background:var(--pt-track); border:1px solid var(--pt-track-vora);
  border-radius:999px; height:6px; overflow:hidden; margin:8px 0 4px; }
.pt-mes-omplert { background:var(--pt-verd); height:100%; border-radius:999px;
  min-width:2px; }
.pt-mes-pct { font-size:.8rem; color:var(--pt-muted); }
@media (max-width: 480px) { .pt-mes { flex-basis:82%; } }

/* L'historic, plegat. Reutilitza .ses-config, que ja es el patro de plec de
   la casa; nomes hi cal la capçalera clicable amb target de 44px. */
.pt-hist-cap { cursor:pointer; padding:10px 12px; min-height:44px;
  display:flex; align-items:center; gap:6px; }
.pt-hist-cap:hover { background:var(--pt-verd-pastel); }
.pt-hist[open] .pt-hist-cap { border-bottom:1px solid var(--pt-line); }

/* Una xifra no es parteix mai en dues linies: «11.388 €» sortia com a «11.388»
   i «€» a sota, i una columna de diners partida es fa il·legible d'un cop d'ull
   (vist al navegador amb la certificacio real de Bonmont, 20-08). */
.pt-table td.num, .pt-table th.num, .pt-kpi-val, .pt-mes-import,
.pt-past-import { white-space: nowrap; }

/* L'exces executat i no acreditat: es una xifra que ESPERA, no un error. Ambre
   segur per a text (5,74:1), mai el vermell d'alarma. */
.pt-text-pendent { color: var(--pt-text-ambre); font-weight: 600; }

/* El que s'ha executat i espera un modificat, a la peça del mes. */
.pt-mes-pendent { font-size:.8rem; margin-top:4px; }
/* Un titol de RESUM pesa mes que un de detall: amb set seccions totes iguals,
   l'ull deixa de distingir que importa. */
.pt-sec-resum h3 { font-size:1.2rem; }

/* ── Plegar capítols, enganxar partides i entrar un BC3 (20-08) ───────
   Les tres peces que va demanar el gerent per acabar el pressupost. El botó
   de plegar es diferencia dels altres «mini» a posta: no fa cap canvi al
   pressupost, només canvia el que es veu, i barrejar-lo amb «Edita» faria
   que semblés que toca dades. */
.pt-past-plega { font-variant-numeric: tabular-nums; opacity: .85; }
.pt-past-plega:hover { opacity: 1; }

.pt-eng-text {
  width: 100%; min-height: 120px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; line-height: 1.45; padding: 8px 10px;
  border: 1px solid var(--pt-line); border-radius: 8px;
  background: var(--pt-surface); color: inherit; resize: vertical;
  /* Sense ajust de línia: una fila enganxada d'un Excel s'ha de poder llegir
     sencera, i partida per la meitat no es veu on acaba una columna. */
  white-space: pre; overflow-x: auto;
}
/* `--pt-focus` és un valor de BOX-SHADOW («0 0 0 3px …»), no un color: fer-lo
   servir dins d'un `outline` o d'un `border-color` fa la declaració invàlida i
   el navegador la llença sencera —sense dir res. El patró bo és el de
   `.pt-past-mini:focus-visible`, unes línies més amunt. */
.pt-eng-text:focus { outline: none; box-shadow: var(--pt-focus); }

/* La zona d'arrossegar el fitxer. Ha de semblar una zona i no un botó: un
   botó convida a prémer-lo i aquí també s'hi pot deixar caure un fitxer. */
.pt-puja {
  border: 2px dashed var(--pt-line); border-radius: 10px;
  padding: 18px; text-align: center; cursor: pointer;
  color: var(--pt-muted); background: var(--pt-soft);
}
.pt-puja:hover { border-color: var(--pt-verd); color: inherit; }
.pt-enllac { text-decoration: underline; cursor: pointer; }

.pt-resum { margin: 0 0 10px; padding-left: 18px; line-height: 1.6; }
.pt-resum li { margin: 2px 0; }

/* Treure una partida (20-08). El color del destructiu ja el té decidit la casa
   —ARGILA, DS-002, al bloc de `.pt-btn-perill` de més amunt— i aquí NO es torna
   a decidir: el primer intent redefinia `.pt-btn-perill` amb un vermell i, com
   que guanya l'última regla del fitxer, va canviar de color el botó «Treu la
   línia» que ja existia sense que ho demanés ningú, i va deixar mentint el
   comentari que explica l'argila. La porta FINAL ho va caçar.

   Aquí només s'hi afegeix el que a `.pt-btn-perill` li faltava (l'estat apagat)
   i el to de la versió MINI: l'argila NOMÉS a la vora, i el fons ple al hover.
   El color del text no es toca —l'hereta de `.pt-past-mini`, que ja té el
   contrast ple— i qui separa aquest botó de l'«Edita» que té al costat és el
   RÈTOL («Treu-la» / «Treu-lo»), no el color: és la regla que la casa ja té
   escrita unes línies més amunt. La vora hi afegeix, no informa tot sola. */
.pt-past-treu { border-color: var(--pt-warn); }
.pt-past-treu:hover { background: var(--pt-warn); color: #FFFFFF;
  border-color: var(--pt-warn); }
.pt-btn-perill:disabled { opacity: .45; cursor: not-allowed; }

/* La cua del gasoil (20-08): la feina que hi ha per fer, ordenada pel que pesa.
   La proposta ha de destacar sobre el text de la fila —és el que es llegeix per
   decidir— sense competir amb el botó, que és l'acció. */
.pt-cas-prop { font-weight: 600; }
.pt-cas-grup { color: var(--pt-muted); font-size: .85rem; }
.pt-cas-accio { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.pt-cas-accio .pt-dd { min-width: 220px; }

/* ── L'ajuda del Control econòmic: un «?» per pantalla, amb modal ────────
   Decisió del gerent (20-08). El referent del patró (Odoo) posa el «?» per
   CAMP; això segueix la decisió i queda anotat a docs/baremoteca/INDEX.md. */
/* El «?» va a la fila de la capçalera, no flotant: `.pt-mod` no és un
   contenidor posicionat i un `absolute` hi hauria anat a parar al viewport. */
.pt-mod-capcalera { display:flex; align-items:flex-start;
  justify-content:space-between; gap:12px; }
.pt-mod-capcalera > *:first-child { flex:1 1 auto; min-width:0; }
/* 44 px, no 34: `DESIGN.md` §Layout diu «tot element tocable ≥44 px» i el
   primer tiratge d'aquest botó no ho complia. Ho va caçar la porta de disseny
   el 21-08, citant el document contra el botó mateix. */
.pt-ajuda-boto { flex:0 0 auto; margin-top:10px; width:44px; height:44px;
  border-radius:50%; border:1px solid var(--pt-line); background:var(--pt-surface);
  color:var(--pt-muted); font-size:1rem; font-weight:600; cursor:pointer;
  line-height:1; }
.pt-ajuda-boto:hover { color:var(--pt-verd); border-color:var(--pt-verd); }
/* El focus ha de VEURE'S: qui va amb teclat no sap on és sense això. */
.pt-ajuda-boto:focus-visible { outline:2px solid var(--pt-verd); outline-offset:2px; }

.pt-ajuda { position:fixed; inset:0; z-index:900; display:flex;
  align-items:center; justify-content:center; padding:16px; }
.pt-ajuda-fons { position:absolute; inset:0; background:rgba(38,36,32,0.45); }
.pt-ajuda-panell { position:relative; background:var(--pt-surface);
  border-radius:var(--pt-radius); box-shadow:var(--pt-shadow-hov);
  max-width:720px; width:100%; max-height:82vh; display:flex;
  flex-direction:column; }
.pt-ajuda-cap { display:flex; align-items:center; justify-content:space-between;
  gap:12px; padding:18px 20px 12px; border-bottom:1px solid var(--pt-line); }
.pt-ajuda-cap h2 { margin:0; font-size:1.15rem; color:var(--pt-text); }
/* Scroll DINS del panell: si l'overflow anés al fons, el títol se n'aniria
   amunt i el botó de tancar deixaria de trobar-se. */
.pt-ajuda-cos { overflow-y:auto; padding:6px 20px 20px; }
.pt-ajuda-sec { margin-top:16px; }
.pt-ajuda-sec h3 { font-size:.95rem; color:var(--pt-verd-dark); margin:0 0 6px; }
.pt-ajuda-sec ul { margin:0; padding-left:18px; }
.pt-ajuda-sec li { color:var(--pt-text); font-size:.9rem; line-height:1.55;
  margin-bottom:7px; }
/* min-height 44: mateixa regla que el germà «?», i el mateix defecte. La
   guarda del 21-08 llegia una sola classe pel nom i no el podia veure. */
.pt-ajuda-tanca { flex:0 0 auto; min-height:44px; padding:6px 16px;
  border-radius:999px;
  border:1px solid var(--pt-line); background:transparent; color:var(--pt-muted);
  font-size:.85rem; font-weight:500; cursor:pointer; }
.pt-ajuda-tanca:hover { color:var(--pt-text); border-color:var(--pt-muted); }
.pt-ajuda-tanca:focus-visible { outline:2px solid var(--pt-verd); outline-offset:2px; }

/* Estat d'una FILA, en marca i no en frase. Mesurat el 21-08: «Encara no hi ha
   hores ni màquines assignades» sortia DOTZE vegades a la mateixa pantalla. */
.pt-past-marca { display:inline-block; margin-top:6px; padding:1px 8px;
  border:1px dashed var(--pt-line); border-radius:999px;
  color:var(--pt-muted); font-size:.78rem; cursor:help; }

/* ── La molla d'estat i la barra d'accions ───────────────────────────────
   El patró del barem: l'estat és una molla al capdamunt i les accions són UNA
   fila de botons a dalt que canvien amb l'estat. Abans «Estat» era una capsa
   sencera al final de la pàgina, a ~5.800 px de baixada. */
.pt-molla { display:flex; flex-wrap:wrap; align-items:center; gap:6px;
  margin:10px 0 4px; }
.pt-molla-pas { padding:3px 12px; border-radius:999px; font-size:.8rem;
  color:var(--pt-muted); background:var(--pt-soft);
  border:1px solid var(--pt-line); }
/* El pas fet i el pas d'ara NO es distingeixen només pel to: el d'ara va en
   negreta i amb vora de marca. El color no informa tot sol. */
.pt-molla-fet { color:var(--pt-verd-dark); background:var(--pt-verd-pastel);
  border-color:var(--pt-verd-pastel); }
/* El pas d'ara NO és una tercera pastilla verda plena. La porta de disseny
   (21-08, 2a passada) va comptar tres —el mòdul actiu, la pestanya activa i
   aquest— fent la mateixa feina visual en menys de 400 px, i el `DESIGN.md`
   diu «cada color amb UNA feina». Es distingeix pel PES i per una vora gruixuda
   de marca, que a més el fa llegible per a qui no distingeix el to. */
.pt-molla-ara { color:var(--pt-verd-dark); background:var(--pt-surface);
  border:2px solid var(--pt-verd-dark); font-weight:700; }
.pt-molla-no { color:var(--pt-text-warn); background:var(--pt-surface);
  border:2px solid var(--pt-text-warn); font-weight:700; }

/* El desplegable del document queia a l'anell de focus per defecte del
   navegador —violeta, fora de la paleta de la casa—. Ho va veure la porta de
   disseny a la captura. */
.pt-dd .Select-control:focus-within,
.pt-dd:focus-visible { outline:2px solid var(--pt-verd); outline-offset:2px; }

.pt-barra { display:flex; flex-wrap:wrap; gap:8px; margin:10px 0 14px;
  padding-bottom:12px; border-bottom:1px solid var(--pt-line); }
.pt-bar-btn { min-height:44px; padding:9px 14px; border-radius:var(--pt-radius-sm);
  border:1px solid var(--pt-line); background:var(--pt-surface);
  color:var(--pt-text); font-size:.85rem; font-weight:500; cursor:pointer; }
.pt-bar-btn:hover { border-color:var(--pt-verd); color:var(--pt-verd-dark); }
.pt-bar-btn:focus-visible { outline:2px solid var(--pt-verd); outline-offset:2px; }
/* El que està obert es veu obert, i no només pel color: porta `aria-expanded`
   i el fons de marca. */
.pt-bar-btn-obert { background:var(--pt-verd); color:var(--pt-sobre-marca);
  border-color:var(--pt-verd); font-weight:600; }

/* La línia d'identitat de la certificació del mes («Certificació núm. 1 ·
   revisió 1 · emesa el 20/08/2026 · 42.870 €»). És el text MÉS important del
   bloc i es pintava amb el <p> pelat del navegador: `pt-mes-cap` no existia a
   cap CSS. Mateix parany que `pt-inp`, que el mòdul ja documenta. */
.pt-mes-cap { font-size:1.02rem; font-weight:600; color:var(--pt-text);
  margin:10px 0 4px; line-height:1.45; }


/* ── Filtre de mes de la Flota («Com anem») ──────────────────────────────────
   Quatre classes que el layout feia servir i que no eren definides ENLLOC: el
   desplegable s'estirava de vora a vora de la pagina per a un valor de set
   caracters, i l'ajuda del control sortia en negre a mida de text normal, com
   si fos una frase de contingut. Ho va caçar la porta de gerent. Es l'unica
   peca que el gerent va demanar pel seu nom -«filtrar-ho per mes»- i anava
   sense estil de casa. */
.pt-filtre-mes{
  display:flex; align-items:center; gap:.55rem; flex-wrap:wrap;
  margin:1.1rem 0 .35rem;
}
.pt-filtre-mes .pt-dd{ min-width:11rem; max-width:14rem; flex:0 0 auto; }
.pt-camp-label{
  font-size:.82rem; font-weight:600; letter-spacing:.02em;
  text-transform:uppercase; color:var(--pt-muted);
}
.pt-camp-ajuda{ font-size:.85rem; color:var(--pt-muted); }
.pt-buit-wrap{ padding:1.4rem 0; }

@media (max-width:768px){
  /* El PLEC, mesurat al banc a 767x545 (l'amplada just per sota del punt on la
     navegacio es plega). Amb `flex:0 0 auto` i `min-width:11rem` els dos
     desplegables NO poden encongir, i el camp de cerca es planta a 520 px: el
     bloc del filtre es partia en TRES linies (142 px) i empenyia la primera
     fila de dades a 565 px, per sota d'un plec de 545. Aqui es deixa que
     encongeixin -mai per sota de la mida on el text encara es llegeix- i el
     bloc torna a DUES linies. Nomes per sota del punt de ruptura: a
     l'escriptori les regles d'amunt manen igual que sempre. */
  .pt-filtre-mes .pt-dd{ min-width:0; max-width:14rem; flex:0 1 9rem; }
  .pt-filtre-mes .pt-input{ max-width:14rem; }
  /* I el ritme vertical s'estreny alla on l'alcada es el recurs escas: el
     mateix bloc i el commutador que el segueix. El germa adjacent ho manté
     dins d'aquesta pantalla — `.pt-commut` el fan servir mig DUAT. */
  .pt-filtre-mes{ margin:.4rem 0 .2rem; row-gap:4px; }
  /* Els marges verticals dels dos enllacos (10 px i 4+8 px) no serveixen de
     res dins d'una fila flex centrada: nomes fan alta la linia. El `gap` ja
     separa. Acotats al bloc perque `pt-back-link` el porten dotze pantalles. */
  .pt-filtre-mes .pt-back-link,
  .pt-filtre-mes .pt-cas-mgmt-link{ margin:0; }
  .pt-filtre-mes + .pt-commut{ margin:2px 0 6px; }
}

@media (max-width:480px){
  /* Al telefon el desplegable ocupa l'ample: es el control principal d'aquesta
     pantalla i el dit no es fi. */
  .pt-filtre-mes .pt-dd{ min-width:100%; max-width:none; flex:1 1 100%; }
  /* I la cerca torna a l'ample sencer: el topall de 14rem d'amunt es del
     tram estret amb dues columnes, no del telefon. */
  .pt-filtre-mes .pt-input{ max-width:none; }
}

/* BAIXES DE FLOTA (B2). El MOTIU es el que fa que una baixa es pugui llegir, i
   en text pla queda igual que la familia o l'autor. Una pastilla apagada el
   separa sense cridar: la baixa no es una alarma, es un fet. Tokens EXISTENTS
   nomes; cap color nou es decideix aqui. */
.pt-baixa-motiu{
  display:inline-block; padding:2px 8px; border-radius:10px;
  background:var(--pt-soft); color:var(--pt-text);
  font-size:.82rem; line-height:1.35;
}

/* ══════════════════════════════════════════════════════════════════════════
   AMPLADA D'ESCRIPTORI (02-09-2026)

   El gerent: «a la pantalla de l'ordinador no es veu tot l'ample». Mesurat a
   2560 px: el contingut n'ocupava 920, el 35,9 %, perquè `.pt-mod` portava un
   `max-width: 920px` que vivia al bloc `<style>` en línia d'`app.py` i no aquí.
   Qui el buscava al full d'estil no el trobava.

   El barem és `docs/baremoteca/pantalla-ampla-grafana.png`: el contenidor
   principal d'un tauler de Grafana viu ocupa el 100 % dels 2560 px. El que
   creix és el contingut DENS —taules, mapes, files de panells—; el text manté
   una mida llegible.

   Per això aquí van DUES regles i no una:
     · el contenidor del mòdul s'eixampla fins a 1.800 px i es CENTRA;
     · la PROSA es queda amb una mida de lectura, perquè una línia de text de
       2.500 px no es llegeix: l'ull perd la fila en tornar a l'esquerra.

   Per què un topall i no tota la pantalla: la primera versió el va treure del
   tot i el trio la va tombar 3-0 —el contingut no creixia amb el contenidor,
   creixia el BUIT—. Però amb 1.800 px el van tombar UNA ALTRA vegada, i els
   tres van dir el mateix: 380 px de marge a cada costat es llegeixen com espai
   mort, no com composició. D'aquí els 2.200: deixa 180 px a banda i banda d'una
   pantalla de 2560, prou perquè el contingut no toqui la vora i massa poc
   perquè sembli una pàgina flotant al mig.

   Guanyar el barem del tot demana POSAR-HI contingut dens. A `/flota` s'ha fet
   —el panell de composició al costat de la taula— i els tres jutges el donen
   per bo. A `/economia` no s'ha fet, i el motiu és honest: **la còpia de
   producció té DOS pressupostos**. Aquella pantalla no es veu buida per
   disseny; es veu buida perquè ho està. Omplir-la de mobles no la faria més
   certa.
   ══════════════════════════════════════════════════════════════════════════ */
.pt-mod { max-width: 2200px; margin: 0 auto; }

/* La MIDA DE LECTURA de la prosa no viu aquí: s'afegeix a la definició que cada
   classe ja té més amunt, perquè aquesta casa té una regla —una classe es
   defineix UN cop— i `test_css_una_sola_vegada` la vigila. Redeclarar-les aquí
   hauria fet que la segona guanyés i canviés en silenci el que feia la primera:
   exactament el defecte que aquest tall persegueix. Es va escriure així i el
   guard de la casa ho va caçar.
   Les classes amb mida de lectura: `.pt-datanote` i `.pt-pendent-text`. */


/* ── Contingut al COSTAT, no espai buit (03-09-2026) ────────────────────────
   El trio va tombar 3-0 la primera versió de l'amplada: el contenidor creixia i
   el contingut no. Aquesta graella posa la peça secundària al costat de la
   principal quan hi ha ample, i a sota quan no n'hi ha —mai amagada: el que no
   hi cap al costat baixa, no desapareix. */
/* `minmax(0, 1fr)` i no `1fr`, i aquí és on es decideix si la pàgina es pot
   llegir al telèfon. `1fr` vol dir `minmax(auto, 1fr)`, i aquell `auto` és el
   min-content: una taula ampla estira la columna fins a l'amplada que ella
   necessita i se'n va endavant de la pantalla. Mesurat el 05-09-2026 a 390 px:
   `#flota-cos-llista` sortia a 747 px d'ample i el cos de la pàgina es lliscava
   367 px de costat. Al tram de >=1200 ja hi era el `minmax(0, ...)`; el que
   faltava era al tram petit, que és justament el que el gerent fa servir. */
.pt-amb-costat { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }
.pt-amb-costat > * { min-width: 0; }
@media (min-width: 1200px) {
  .pt-amb-costat { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
}

/* El panell de composició de la flota. Llista compacta: la seva feina és dir
   DE QUÈ està feta la flota que es veu al costat, i per això va densa i no com
   a targetes —36 targetes serien una segona pantalla, no un resum. */
.pt-comp { background: var(--pt-surface); border: 1px solid var(--pt-line);
  border-top: 3px solid var(--pt-verd); border-radius: var(--pt-radius);
  padding: 14px 16px; }
.pt-comp-titol { font-size: .95rem; font-weight: 600; color: var(--pt-text);
  margin: 0 0 2px; }
.pt-comp-total { color: var(--pt-muted); font-size: .8rem; margin: 0 0 10px; }
.pt-comp-fila { display: grid; grid-template-columns: 1fr auto auto;
  gap: 8px; align-items: baseline; padding: 4px 0;
  border-bottom: 1px solid var(--pt-line); }
.pt-comp-fila:last-child { border-bottom: none; }
.pt-comp-nom { font-size: .82rem; color: var(--pt-text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pt-comp-regim { font-size: .72rem; color: var(--pt-muted); }
.pt-comp-n { font-size: .82rem; font-weight: 600; color: var(--pt-text);
  font-variant-numeric: tabular-nums; min-width: 2.5ch; text-align: right; }

/* ── El dia que NO és avui ─────────────────────────────────────────────────
   Petició del gerent (03-09): «potser estaria bé tenir d'un altre color quan
   estàs a un altre dia, per diferenciar quan s'està treballant al dia que
   toca». Amb 25 obres i anant amunt i avall, planificar el dia equivocat és
   fàcil i fins ara només canviava el text d'un botó.
   El to canvia el FONS del quadre sencer, no un detall: ha de ser visible amb
   la vista perifèrica, sense haver de llegir res. */
.ses-avis-dia { background: var(--pt-ambre-pastel); color: var(--pt-text-ambre);
  border-radius: var(--pt-radius); padding: 8px 14px; margin: 0 0 10px;
  font-size: .92rem; }
.ses-altre-dia .ses-tauler { background: var(--pt-ambre-pastel);
  border-radius: var(--pt-radius); padding: 8px; }

/* El peu de l'obra, en dos blocs: la feina del dia sempre a la vista, la
   configuració plegada. Abans hi havia quatre controls amuntegats en un espai
   pensat per a un i es trepitjaven (captura del 03-09). */
.ses-peu-diari { display: flex; flex-direction: column; gap: 6px;
  margin-top: 8px; }
.ses-peu-config { display: block; width: 100%; margin-top: 8px;
  border-top: 1px solid var(--pt-line); padding-top: 6px; }
/* La columna fa 288 px: un camp i un botó a la MATEIXA fila deixen el camp a
   130 px i el text hi surt escapçat («què ha passat avu», «hi caldrà… (un cam»),
   que és el que es veia a la captura del 03-09. Camp a tota l'amplada i botó a
   sota, alineat a la dreta perquè no sembli un altre camp. */
.ses-com-form, .ses-pet-form, .ses-enc-form, .ses-est-form {
  display: flex; flex-direction: column; gap: 4px; align-items: stretch; }
.ses-com-form .ses-inp-h, .ses-pet-form .ses-inp-h,
.ses-enc-form .ses-dd, .ses-est-form .ses-inp-h { width: 100%; min-width: 0; }
.ses-com-form .ses-btn-mini, .ses-pet-form .ses-btn-mini,
.ses-est-form .ses-btn-mini { align-self: flex-end; }
/* 18-09-2026 (ITERAR, terra de 44px al DESIGN.md dins `.ses-oberta`) · el
   `min-height:38px` de `.ses-inp-h`/`.ses-inp-m` NOMÉS pinta l'embolcall que
   Dash genera (`<div class="dash-input-container … ses-inp-h …">`): l'`
   <input class="dash-input-element">` de VERITAT -el que rep el toc i el
   tecleig- viu a DINS d'aquell embolcall, dins d'un `display:inline-flex;
   align-items:center` que Dash ja porta de sèrie (no l'estira: el centra a
   la seva mida NATURAL, 28px). Mesurat: `--oberta-terra-44`
   (sonda_compacitat_planificacio.py) el trobava a 28px als tres camps del
   peu obert (comentari, petició, hores) i a 32x28 als botons +/- del camp
   numèric (`ses-est-inp`, `.dash-input-stepper`, tampoc un `<input>` natiu).
   1r intent (retirat): posar `min-height:44px` a l'`<input>` DIRECTAMENT
   —xocava amb el `padding` de l'embolcall (el `<input>` de Dash ja en porta
   el seu) i li encomanava scroll intern, `--scrolls-dins-oberta` el va
   caçar (0 → 3). La via bona: `align-self:stretch` (el fill OCUPA tota
   l'alçada real de l'embolcall, sense demanar-ne una de pròpia) i treure el
   `padding` DUPLICAT de l'embolcall (el porta l'`<input>`, `--Dash-Spacing`)
   perquè aquella alçada REAL arribi a 44 sencers un cop restada la vora
   d'1px (46 de min-height − 2px de vora = 44 de contingut).
   NOMÉS dins `.ses-tcol-peu` (el peu de la targeta oberta): `.ses-inp-h`/
   `.ses-inp-m` són classes compartides amb altres formularis (`.ses-tr-form`,
   `.ses-tanca-form`) que aquesta tanda no toca ni mesura. */
.ses-tcol-peu .ses-inp-h, .ses-tcol-peu .ses-inp-m {
  min-height: 46px; padding: 0; }
.ses-tcol-peu .dash-input-element, .ses-tcol-peu .dash-input-stepper {
  align-self: stretch; box-sizing: border-box; }
/* El desplegable de l'encarregat (`ses-enc-sel`) és el mateix forat amb un
   altre component: `.pt-dd .Select-control` (més amunt) apuntava al DOM
   d'una versió VELLA de `dcc.Dropdown` (react-select clàssic). La versió
   instal·lada ara renderitza un `<button class="dash-dropdown pt-dd
   ses-dd">` -les classes de la casa cauen DIRECTAMENT sobre el control
   real, ja no calen descendents- a 34px, sense que cap regla existent el
   toqui. Mateixa mida que el terra: aquest forat probablement toca TOTS
   els `.pt-dd` del sistema (`.Select-control` ha quedat mort a tot arreu,
   no només aquí) -queda anotat per a una tanda pròpia-, aquí NOMÉS es tapa,
   escopat, el que calia dins `.ses-oberta`. */
.ses-tcol-peu .pt-dd.dash-dropdown, .ses-tcol-peu .pt-dd .dash-dropdown {
  min-height: 44px; }
/* El Details ha de ser un bloc dins de la columna: en línia se n'anava a la
   dreta i quedava fora del flux (captura del 03-09). `display:block` va a la
   regla de dalt, fusionada — el guard de la casa va caçar que l'havia definida
   DUES vegades, que és el mateix defecte que aquesta tanda va treure de
   `.ses-tcol` al matí. */
.ses-peu-config > summary { display: list-item; }
.ses-com-llista { margin: 4px 0; }
.ses-com-fila { font-size: .86rem; padding: 4px 0;
  border-bottom: 1px solid var(--pt-line); }

/* La REFERÈNCIA d'una taula (mitjana, total): és el que fa comparable la
   columna, i s'ha de veure que NO és una fila de dades. Línia de dalt més
   marcada, fons suau i lletra mitja: prou per separar-la, prou poc per no
   competir amb els números que ha de servir. */
.pt-table tfoot td { border-top: 2px solid var(--pt-line);
  background: var(--pt-soft); color: var(--pt-muted); font-weight: 600;
  padding: 7px 10px; }
.pt-table tfoot td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* ── La barra que recorda què portes a la mà (NOMÉS al telèfon) ─────────────
   Gerent, 05-09-2026, provant-ho amb el mòbil: «al seleccionar una targeta es
   quedés flotant i tot i fer scroll veiessis que has seleccionat».

   APAGADA per defecte i encesa NOMÉS sota els 768 px, i l'ordre és a posta: al
   revés —dibuixar-la sempre i amagar-la al PC— qualsevol pantalla nova que no
   conegui la regla la mostraria, i sortiria on ningú l'ha demanada. Al PC no
   cal: el parc i les obres es veuen alhora en columnes.

   Va a BAIX perquè a dalt ja hi ha `.pt-header` enganxada (`position:sticky`,
   z-index 100) i perquè al telèfon el polze hi arriba. El z-index queda per
   sota del modal d'ajuda (900), que sí que ha de tapar-ho tot. */
.ses-sel-flotant { display:none; }

@media (max-width: 768px) {
  .ses-sel-flotant {
    display:flex; align-items:center; gap:10px;
    position:fixed; left:0; right:0; bottom:0; z-index:120;
    padding:10px 12px calc(10px + env(safe-area-inset-bottom));
    background:var(--pt-surface); border-top:2px solid var(--pt-verd);
    box-shadow:0 -4px 14px rgba(0,0,0,.18);
    font-size:.95rem;
  }
  /* El text va en DUES línies, no en una de sola amb el pas següent amagat
     als 480 px. El telèfon del gerent és de 390: amagar-lo allà volia dir
     amagar-lo SEMPRE, i la regla de la casa és que la marca porta text i el
     text diu què has de fer ara. Dues línies curtes hi caben; una de llarga
     partiria el nom de la màquina, que és el que has de poder llegir. */
  .ses-sel-flotant-txt { flex:1 1 auto; min-width:0;
    display:flex; flex-direction:column; gap:1px; }
  .ses-sel-flotant-que { min-width:0;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ses-sel-flotant-ara { color:var(--pt-muted); font-size:.82rem;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  /* 44 px de zona de toc: la regla de la casa, i la que el trio ja va caçar
     una vegada amb un botó de 34. */
  .ses-sel-flotant-x { flex:0 0 auto; min-height:44px; min-width:44px;
    padding:0 14px; border:1px solid var(--pt-line); border-radius:8px;
    background:var(--pt-bg); color:var(--pt-text); cursor:pointer; }
  /* I el peu de la pàgina deixa lloc, o la barra tapa l'última targeta. El
     lloc reservat ha de créixer amb LA MATEIXA `env()` que fa créixer la
     barra: amb un 72 px fix, en un telèfon amb osca (`safe-area-inset-bottom`
     ~34 px) la barra fa ~98 px i torna a tapar la targeta de sota — el
     defecte que aquesta regla existeix per evitar. El navegador de proves ho
     dona a 0 i per això la comprovació a 390x844 NO ho podia veure. */
  .ses-pagina { padding-bottom:calc(76px + env(safe-area-inset-bottom)); }
}

/* ── EL BOTO QUE AMAGA LA PROSA (09-09-2026) ─────────────────────────────────
   Historia curta, perque el text d'aqui va descriure un pla que ja no existeix:
   el boto va nEixer amagant `.pt-datanote`, la porta CONTROL va mesurar que
   aixi deixava SIS grafics sense periode —i el peu honest i l'avis de frescor
   muts—, es va retirar del tall desplegat, i la solucio de fons va acabar sent
   una altra: **partir la classe pel SIGNIFICAT**.
   `pt-procedencia` = que NO es aquesta xifra (periode, taula retallada, dada
   que no es d'avui, limits). No s'amaga MAI.
   `pt-datanote`    = com s'ha de llegir el dibuix. Aquesta si.
   La regla de sota nomes toca la segona. Si algu hi afegeix una classe, que es
   pregunti: amagant-la, algu pot llegir el numero com una altra cosa? */
.pt-prosa-wrap { display: flex; justify-content: flex-end; margin: -4px 0 6px; }
.pt-prosa-label { font-size: .82rem; color: var(--pt-muted); cursor: pointer;
                  display: inline-flex; align-items: center; gap: 6px;
                  /* DS-S10: target tactil >=44px (WCAG 2.5.8). La porta CONTROL
                     va mesurar que el meu control nou en feia 15 i era l'unic
                     tocable del delta que incomplia la regla de la casa. */
                  min-height: 44px; padding: 0 6px; }
.pt-prosa-input { accent-color: var(--pt-verd); width: 20px; height: 20px;
                  cursor: pointer; }
/* Tancat (per defecte): NOMES la prosa. `pt-procedencia` no hi es i no hi pot
   entrar mai. I `:not([id]):not(:has(a))` perque una `datanote` pot portar
   l'Output d'un callback o l'unic enllaç d'una seccio: amagar un node amb
   identificador o amb enllaç no es amagar text, es trencar una sortida. */
.pt-mod:has(#pt-prosa input:not(:checked)) .pt-datanote:not([id]):not(:has(a)),
.pt-mod:has(#pt-prosa input:not(:checked)) .pt-sec-sub:not([id]):not(:has(a)),
.pt-mod:has(#pt-prosa input:not(:checked)) .pt-mod-lead { display: none; }

/* ── LA FLOTA, per categories (Fitxes) ────────────────────────────────────
   La forma ve de `.ses-maq-fila` (Planificació), que ja tenia resolts els 44 px
   de target tàctil i el `touch-action`. No es reutilitza aquella classe perquè
   allà la fila és un `<button>` de tria i aquí és un enllaç a la fitxa: mateixa
   mida i mateix gest, semàntica diferent.

   El que hi havia abans i era el defecte: els noms de les màquines anaven dins
   d'un `.pt-datanote` —la classe de NOTA AL PEU, cursiva i grisa a .875rem— o
   sigui que la llista del parc es pintava amb l'estil d'un aclariment. I el
   contenidor era una classe de graella el selector de la qual no casava amb
   res aquí dins; el detall és al docstring de `_fila_de_flota`. */
.pt-flota-files { display:flex; flex-direction:column; }
.pt-flota-fila { display:flex; align-items:center; gap:8px; width:100%;
  flex-wrap:wrap; row-gap:2px;
  min-height:44px; padding:6px 10px;
  border:1px solid transparent; border-radius:var(--pt-radius);
  color:inherit; text-decoration:none;
  touch-action:manipulation; }
.pt-flota-fila:hover { background:var(--pt-soft); }
.pt-flota-fila:focus-visible { outline:2px solid var(--pt-verd);
  outline-offset:-2px; }
.pt-flota-nom { font-weight:500; }
.pt-flota-mat { font-size:.78rem; color:var(--pt-muted);
  font-variant-numeric:tabular-nums; }
/* La marca porta TEXT, mai un color sol: «categoria deduïda» diu per què
   aquella fila no és igual de fiable que la del costat. */
.pt-flota-ded { font-size:.72rem; color:var(--pt-muted);
  border:1px solid var(--pt-line); border-radius:999px; padding:0 6px; }
/* El recompte del calaix. `.pt-muted` NO existeix —ho vaig escriure de memoria
   i el navegador s'hauria quedat amb el color heretat sense dir res. */
.pt-flota-n { color:var(--pt-muted); font-size:.86rem; }
.pt-flota-cap { min-height:44px; display:flex; align-items:center; gap:6px;
  cursor:pointer; padding:4px 2px; }
.pt-flota-emoji { font-size:1.05rem; }
.pt-flota-lead { margin:0 0 4px; }

/* ══════════════════════════════════════════════════════════════════════
   SESHAT 2.0 · S3 — mitja jornada, descombinar i color per obra
   (PLA-2026-09-16-planificacio-completa.md). Bloc AUTOCONTINGUT: cap
   selector d'aquí es defineix a cap altre lloc del full. Amo: S3.
   ══════════════════════════════════════════════════════════════════════ */

/* Vora «mitja»: la fitxa porta EXACTAMENT mitja jornada, a l'obra i al parc
   (decisió del gerent, 16-09-2026: «les dues targetes»). El color mai va
   sol: sempre acompanyat del text «N h» que ja pinta qui construeix la
   targeta. Token `--pt-blau` — família reservada a posta per a aquesta vora:
   ambre i warn ja diuen «sense màquina»/«alerta» i no es reutilitzen. */
.ses-tcard-mitja { border:2px solid var(--pt-blau); }
.ses-tcard-mitja:hover { border-color: var(--pt-blau); }
.ses-tcard-mitja.ses-tcard-sel { box-shadow:0 0 0 3px var(--pt-blau-pastel); }

/* Barra d'accions sobre la fitxa triada («Mitja jornada» / «Treure la
   màquina» / «Treure el treballador»). SEMPRE al DOM (botons reals,
   ≥44 px); `.ses-accions-buida` (clientside a app.py, segons `ses-sel`) NOMÉS
   atenua — mai `display:none`, perquè un botó net a la vista i inert diu
   més la veritat que un que apareix i desapareix sol. */
/* 18-09-2026 · en FILA, no apilats. Apilats eren 3x44px = 132px dins d'una
   columna de 618px que nomes en deixava 140 per a les dues llistes. Segueixen
   sent botons REALS de 44px (terra del DESIGN.md) i amb TEXT: a 236px
   d'amplada en caben dos per fila, o sigui dues files en lloc de quatre. */
.ses-accions-barra { display:flex; flex-direction:row; flex-wrap:wrap;
  gap:4px; margin-top:4px; }
.ses-accions-barra > * { flex:1 1 calc(50% - 2px); min-width:0; }
.ses-accio-btn { min-height:44px; font-size:.78rem; width:100%;
  padding:2px 6px; white-space:nowrap; overflow:hidden;
  text-overflow:ellipsis; }
.ses-accions-buida .ses-accio-btn { opacity:.4; pointer-events:none; }
/* 19-09-2026 · correcció del gerent: `_accions_targeta` baixa de la
   capçalera estreta del parc (236px, el disseny de dalt) a la barra AMPLA
   del tauler. Aquí els botons prenen l'ample del seu text: forçar-los al
   50% d'una barra de tot l'ample del quadre els faria enormes i buits. */
.ses-tauler-barra .ses-accions-barra { flex-wrap:wrap; margin-top:0;
  gap:6px; }
.ses-tauler-barra .ses-accions-barra > * { flex:0 0 auto; }
.ses-tauler-barra .ses-accio-btn { width:auto; padding:2px 12px; }

/* Selector de color per obra (dins «⚙️ L'obra», `_peu_columna`). Pastilles
   amb el patró `.ses-chip` de la casa; el to REAL de cada pastilla és
   `--pt-obra-N` que encara no existeix (paleta de S1, rere la fusió): valors
   LITERALS aquí a posta —`test_cap_variable_de_color_inventada` refusa un
   `var(--pt-…)` que no es declari enlloc— i no un `var(..., fallback)`, que
   a la prova li sembla exactament la mateixa orfandat. Quan aparegui
   `--pt-obra-N`, es substitueixen aquests 8 valors pel `var()` real; és
   l'ÚNIC canvi pendent d'aquest bloc. Van DESPRÉS de `.ses-chip` a posta:
   mateixa especificitat, i qui ve després mana. */
.ses-color-selector { display:flex; align-items:center; gap:6px;
  flex-wrap:wrap; margin-top:6px; }
/* CP4 · 19-09-2026. Aquí vivien `.ses-color-tria`, `.ses-color-chip` i les
   vuit pastilles de color per `data-option-index`: la fulla d'estils del
   SELECTOR DE COLOR LLIURE, retirat amb el seu Python. Cap fitxer del repo
   emet ja aquestes classes (comprovat amb `rg` sobre els layouts i el JS).
   `.ses-color-selector` i `.ses-color-fb` es queden: els segueix fent
   servir el selector de CATEGORIA, que és qui n'ha pres el lloc. */
.ses-color-fb { font-size:.78rem; color: var(--pt-muted); }

/* ── LA CAPÇALERA COMPRIMIDA · fins on la GRAN hi cap de veritat ───────────
   20-09-2026. Aquestes regles vivien dins del `@media (max-width: 1366px)`
   de sobre, i el 1366 no era el seu número: era el número de l'ALTRA decisió
   d'aquell bloc (quin ORDRE té la pàgina, quadre primer a la tauleta i al
   portàtil petit). Barrejades, la compressió s'aturava a 1366 i entre 1367 i
   1559 tornava la capçalera gran... que NO hi cap.

   Mesurat al banc, amb els tres grups reals de la navegació:

       grups       «El meu dia» 172 + «Control» 763 + «Planificació» 525
       + separadors i marges                              = 1.577 px
       amplada     nav       files de grups   capçalera    carril comença a
       ≤1366       61px      1 (comprimida)      110px       323
       1400-1536   156px     2  ← s'embolica     209px       592
       ≥1560       75px      1 (hi cap)          128px       511

   O sigui que 1440x900 i 1536x864 —dos portàtils de tots els dies— tenien
   la capçalera MÉS ALTA que 1366 i que 1920, i el carril del parc es quedava
   a 260-296px amb els calaixos per sota del seu propi rètol de 44. El número
   no seguia l'amplada perquè no era una qüestió de créixer: era que a mitja
   franja la navegació passava a DUES files de grups.

   El 1559 és el mesurat: a 1560 la capçalera gran ja hi cap en una fila. És
   un número que depèn del CONTINGUT de la navegació (tres grups, nou
   enllaços): si algú n'hi afegeix un, deixa de ser cert. Per això no es
   confia a aquest comentari — ho vigila
   `sonda_compacitat_planificacio.py --nav-una-fila`, que escombra amplades i
   cau si la navegació agafa més d'una fila de grups a qualsevol d'elles.

   Segueix acotat amb `body:has(.ses-pagina)`: les altres onze pantalles no
   tenen aquesta pressió d'espai i el gerent no les ha demanat. */
@media (max-width: 1559px) {
  /* El tractament és el mateix que ja fa el telèfon: una fila que llisca,
     títols de grup fora i un filet entre grups. L'àrea de toc es queda als
     44px — escurçar-la seria arreglar una cosa trencant-ne una altra. */
  body:has(.ses-pagina) .pt-nav { flex-wrap:nowrap; overflow-x:auto;
    -webkit-overflow-scrolling:touch; scrollbar-width:none; gap:6px;
    padding:8px 14px; align-items:center; }
  body:has(.ses-pagina) .pt-nav::-webkit-scrollbar { display:none; }
  body:has(.ses-pagina) .pt-nav-group { flex-direction:row; flex-shrink:0;
    gap:4px; align-items:center; }
  body:has(.ses-pagina) .pt-nav-group-title { display:none; }
  body:has(.ses-pagina) .pt-nav-group-links { flex-wrap:nowrap; gap:4px; }
  body:has(.ses-pagina) .pt-nav-group + .pt-nav-group::before { content:"";
    display:block; width:1px; height:20px; background:var(--pt-line);
    flex-shrink:0; margin-right:2px; }
  body:has(.ses-pagina) .pt-nav-link { padding:10px 14px; font-size:.82rem;
    white-space:nowrap; flex-shrink:0; min-height:44px; }
  /* La barra de marca i el marge de la pàgina, el mateix tracte que al telèfon:
     el «Hola,» i la pastilla de rol no són feina, i 24 px de marge a dalt són
     una fila d'obra. */
  body:has(.ses-pagina) .pt-topbar { padding:8px 14px; }
  body:has(.ses-pagina) .pt-hello-lead { display:none; }
  body:has(.ses-pagina) .pt-role-badge { display:none; }
  body:has(.ses-pagina) .pt-main { padding:14px 14px; }
}

/* ── EL CALAIX ───────────────────────────────────────────────────────────
   El detall d'una màquina, un vehicle, un treballador o una obra, obert
   DAMUNT la pàgina on ets. Decisió del gerent (20-09-2026): «perfecte fem B,
   calaix». La pàgina sencera no s'enterra: queda com a sortida de dins.

   És una DIVISIÓ posicionada i no un `<dialog>` amb `showModal()`, i això no
   és estil. Els navegadors imposen un `max-width` propi a `dialog:modal`: el
   20-09 ens va deixar un calaix de 358 px en una pantalla de 390 px, i a les
   captures d'escriptori no es veia. El modal d'ajuda (`.pt-ajuda`) ja ho fa
   així des de l'agost i per la mateixa raó.

   El `z-index` va per sobre de la capçalera apegalosa (100) i de la barra
   inferior del mòbil (120), i per sota del modal d'ajuda (900): l'ajuda
   s'ha de poder llegir amb el calaix obert. */
.pt-calaix { position:fixed; inset:0; z-index:400; display:flex;
  justify-content:flex-end; }
.pt-calaix-fons { position:absolute; inset:0; background:rgba(38,36,32,0.45); }
.pt-calaix-panell { position:relative; background:var(--pt-surface);
  box-shadow:var(--pt-shadow-hov); width:min(680px, 100%); height:100%;
  display:flex; flex-direction:column; }
.pt-calaix-cap { display:flex; align-items:flex-start; justify-content:space-between;
  gap:12px; padding:16px 20px 12px; border-bottom:1px solid var(--pt-line); }
.pt-calaix-cap h2 { margin:0; font-size:1.1rem; color:var(--pt-text); }
/* D'ON VE, escrit: el calaix tapa la pàgina i sense això no se sap què hi ha
   a sota. És la mateixa feina que fa la molla de pa a la pàgina sencera. */
.pt-calaix-de { display:block; margin-top:3px; font-size:.8rem;
  color:var(--pt-muted); }
/* El scroll va DINS del panell: si anés al fons, el títol i el botó de
   tancar se n'anirien amunt. Mateix motiu que a `.pt-ajuda-cos`. */
.pt-calaix-cos { overflow-y:auto; padding:6px 20px 20px; flex:1 1 auto; }
/* La sortida a la pàgina sencera, a la vista i no amagada al final: és la
   meitat de la decisió del gerent, la que permet enviar-la o imprimir-la. */
.pt-calaix-peu { flex:0 0 auto; display:flex; flex-wrap:wrap; gap:8px;
  align-items:center; justify-content:space-between;
  padding:12px 20px; border-top:1px solid var(--pt-line);
  background:var(--pt-soft); }
/* Cada classe, definida UNA sola vegada i sencera: la guarda de la casa
   (`test_css_una_sola_vegada`) prohibeix partir-la en una regla compartida
   més una de pròpia, perquè llavors la segona guanya i canvia en silenci el
   que feia la primera. M'ho acaba de caçar. Els 44 px són de `DESIGN.md`. */
.pt-calaix-tanca { min-height:44px; padding:6px 16px; border-radius:999px;
  font-size:.85rem; font-weight:500; cursor:pointer; display:inline-flex;
  align-items:center; border:1px solid var(--pt-line); background:transparent;
  color:var(--pt-muted); }
.pt-calaix-tanca:hover { color:var(--pt-text); border-color:var(--pt-muted); }
.pt-calaix-sencera { min-height:44px; padding:6px 16px; border-radius:999px;
  font-size:.85rem; font-weight:500; cursor:pointer; display:inline-flex;
  align-items:center; border:1px solid var(--pt-verd);
  background:var(--pt-surface); color:var(--pt-verd-dark);
  text-decoration:none; }
.pt-calaix-sencera:hover { background:var(--pt-verd-pastel); }
/* El focus ha de VEURE'S. `--pt-focus` NO serveix aquí: és un valor de
   `box-shadow`, i dins d'un `outline` la declaració és invàlida i el focus
   desapareix en silenci (m'hi vaig deixar una estona el 20-09). */
.pt-calaix-tanca:focus-visible, .pt-calaix-sencera:focus-visible {
  outline:2px solid var(--pt-verd); outline-offset:2px; }

/* Al telèfon és un full que puja per baix, no un calaix lateral: a 390 px un
   panell de costat deixa una franja de fons inútil i el polze no arriba a
   dalt. Es queda a 92vh perquè es vegi que hi ha pàgina a sota. */
@media (max-width:720px) {
  .pt-calaix { align-items:flex-end; justify-content:center; }
  .pt-calaix-panell { width:100%; height:92vh;
    border-radius:var(--pt-radius) var(--pt-radius) 0 0; }
}

/* ── Les tres preguntes de /gasoil, en graella ───────────────────────────
   Mesurat al banc el 21-09-2026 (1366x768): apilades, la primera gràfica
   començava a 672 px i la segona i la tercera a 960 i 1159 px — cap de les
   tres es veia en obrir la pantalla. La proporció és la de la maqueta
   `gasoil3-v2.html` (`.charts{grid-template-columns:1.4fr 1fr 1fr}`): la
   primera porta dotze mesos a l'eix i necessita l'amplada. */
.pt-tres-graelles { display:grid; grid-template-columns:1.4fr 1fr 1fr;
                    gap:12px; align-items:start; }
.pt-graella-cel { min-width:0; }
/* `min-width:0` no és decoració: sense ell una cel·la de graella no baixa
   mai de l'amplada del seu contingut i el `dcc.Graph` desborda la fila. */

@media (max-width:1050px) {
  .pt-tres-graelles { grid-template-columns:1.3fr 1fr; }
}
@media (max-width:760px) {
  .pt-tres-graelles { grid-template-columns:1fr; }
}

/* El títol de cada gràfica dins d'una secció. Fins al 21-09-2026 `pt-sub`
   no tenia cap regla enlloc: no es notava perquè heretava de `.pt-sec h3`,
   i per això hauria durat anys com a promesa d'estil buida. */
.pt-sub { font-size:13px; margin:0 0 4px; }

/* D4/D5 (26-09-2026) · «Qui és qui»: una fila per persona (nom · règim · nom per
   als avisos · carnet). Sense aquesta graella cada camp ocupava una línia
   sencera i 44 persones feien ~6.600px. A mòbil passa a dues línies. */
.ses-qq-fila {
  display: grid;
  grid-template-columns: minmax(140px, 1.2fr) minmax(150px, 1fr) minmax(140px, 1fr) auto;
  align-items: center;
  column-gap: var(--pt-space-2);
  row-gap: var(--pt-space-1);
  padding: var(--pt-space-1) 0;
}
.ses-qq-fila.ses-qq-cap { font-size: .8rem; font-weight: 600; color: var(--pt-muted); }
.ses-qq-fila .ses-qq-nomav input { width: 100%; box-sizing: border-box; }
.ses-qq-fila .ses-qq-carnet { white-space: nowrap; }
/* Zona tàctil de 44 px, el mateix patró que `.ses-radio label`. */
.ses-qq-fila .ses-qq-carnet label { min-height: 44px; display: inline-flex;
  align-items: center; gap: var(--pt-space-1); }
@media (max-width: 768px) {
  .ses-qq-fila { grid-template-columns: 1fr 1fr; }
  .ses-qq-fila.ses-qq-cap { display: none; }
}
