/* =============================================================================
   public/css/estils.css — Estils generals i compartits de Laboral V2.

   Conté:
     1. Variables CSS dels colors de marca (com a fallback i per a animacions /
        gradients que Tailwind no expressa amb classes utility).
     2. Components reutilitzables: btn, card, input, pill, eyebrow, match-ring,
        brand-stripe.
     3. Fallbacks de classes brand-* (safety net si tailwind.css es desincronitza
        amb input.css).

   Tailwind és el primer recurs (vegeu /public/css/README.md). Aquí només
   viu el que no es pot expressar net amb classes utility o el que es
   repeteix tantes vegades que mereix un component CSS dedicat.
   ========================================================================== */


/* ───────────────────────────────────────────────────────────────────────────
   1. Variables (paleta brand)
   ─────────────────────────────────────────────────────────────────────────── */
:root {
  color-scheme: light;
  --c-orange:        #f39200;
  --c-orange-dark:   #d97f00;
  --c-orange-light:  #ffeed1;
  --c-orange-faint:  #fff6e6;
  --c-green:         #00b187;
  --c-green-dark:    #008c6c;
  --c-green-light:   #d6f3ea;
  --c-red:           #d4423a;
  --c-red-light:     #fde2df;
  --c-amber:         #e9a23b;
  --c-amber-light:   #fff0d2;

  /* ── Tons de TEXT sobre el fons clar del mateix color ──────────────────
     Els xips d'estat (`.pill-*`, `.abx-stat-*`, `.lvl-*`…) pinten text de
     color sobre el fons clar del mateix to. Amb els tons de dalt, aquella
     combinació no arriba al mínim de contrast de la WCAG AA (4,5:1 per a
     text petit) — mesurat, ho fallaven TOTS, també el verd:

       verd    #008c6c sobre #d6f3ea → 3,60:1
       vermell #d4423a sobre #fde2df → 3,69:1
       taronja #f39200 sobre #ffeed1 → 2,06:1
       ambre   #e9a23b sobre #fff0d2 → 1,92:1   ← el pitjor

     Aquests quatre són els mateixos colors amb la lluminositat abaixada
     fins a passar de 4,5:1, conservant to i saturació: segueixen sent
     «el verd» i «el taronja», només que ara es llegeixen.

     ⚠️ Només per a `color:` (text i icones) sobre el fons clar germà. Les
     VORES no s'hi toquen: una vora fosca canvia el pes visual del component
     i no és el que aquí es vol arreglar — per a vores, botons i enllaços,
     els tons de dalt es queden com estan. */
  --c-green-text:    #007a5d;   /* 4,53:1 sobre --c-green-light  */
  --c-red-text:      #c1322a;   /* 4,56:1 sobre --c-red-light    */
  --c-amber-text:    #976111;   /* 4,62:1 sobre --c-amber-light  */
  --c-orange-text:   #995c00;   /* 4,74:1 sobre --c-orange-faint */
  --c-ink:           #2a251f;
  --c-text:          #3b342c;
  /* Quatre unitats més fosc que el #7a6f63 que hi havia, i el canvi no es veu.
     Amb l'anterior, el text secundari passava just sobre blanc (4,90:1) però es
     quedava curt sobre els fons de secció, que és on més surt: 4,32:1 sobre
     --c-line-soft i 4,36:1 sobre --c-warm, per sota del 4,5:1 de la WCAG AA.
     Amb aquest passa sobre els quatre fons del projecte (blanc 5,14 · cream
     4,85 · warm 4,57 · line-soft 4,53), i arregla d'un cop la vintena de llocs
     que ho fallaven per poc, inclòs el xip `.pill-muted`. */
  --c-muted:         #766c60;
  --c-faint:         #a89e92;
  --c-line:          #ece6dc;
  --c-line-soft:     #f5f0e7;
  --c-cream:         #fbf8f2;
  --c-warm:          #f7f1e4;

  /* ── Radis ──────────────────────────────────────────────────────────────
     Hi havia botons a 9, 10, 11, 12, 13 i 18 px segons quina pantalla, i es
     notava: dos botonets de la mateixa mida un al costat de l'altre amb les
     cantonades diferents. L'escala és aquesta i no n'hi ha cap més:

       --r-btn      12px · qualsevol botó amb text, pestanyes, enllaços de menú
                           i camps de formulari (= `rounded-xl` de Tailwind).
       --r-btn-sm   10px · botons quadrats d'icona (≤ 36 px) i paginació: a
                           12 px una caixa de 32 px queda quasi rodona.
       --r-card     18px · targetes i el que flota (la barra inferior fa 22 px,
                           que és aquesta escala i no la dels botons).
       --r-pill    999px · píndoles i botons flotants rodons (paleta de
                           l'horari, «Desa» flotant, «Finalitzar jornada»…).
                           És una FAMÍLIA a part, no un descuit.

     Si necessites un radi que no hi és, el que falla és el component. */
  --r-btn:     12px;
  --r-btn-sm:  10px;
  --r-card:    18px;
  --r-pill:   999px;
}


/* ───────────────────────────────────────────────────────────────────────────
   2. Components reutilitzables
   ─────────────────────────────────────────────────────────────────────────── */

/* Tira gradient taronja → verda. Apareix al damunt de cada capçalera de la
   variant "Refinat" del disseny. Interpolació directa orange→green (el
   degradat passa per ambre de forma natural; no posem `via` per ser fidel
   al disseny original). */
.brand-stripe {
  background: linear-gradient(90deg, var(--c-orange), var(--c-green));
}

/* Logotip de marca (wordmark SVG via <img>). El Preflight de Tailwind aplica
   `img { max-width: 100%; height: auto }`; com que el SVG només porta viewBox
   (sense width/height intrínsecs), dins d'un contenidor que s'ajusta al
   contingut (inline-block) l'amplada col·lapsa a 0 i el logo no es veu.
   Neutralitzem el max-width i deixem que l'atribut `width` de cada <img> mani;
   l'alçada es deriva de la proporció del viewBox. */
.brand-logo {
  display: block;
  height: auto;
  max-width: none;
}

/* Card amb radius 18px i shadow suau. */
.card-soft {
  background: #fff;
  border-radius: 18px;
  box-shadow:
    0 1px 0 rgba(60, 40, 20, 0.04),
    0 6px 18px -10px rgba(60, 40, 20, 0.18);
}

/* Card d'oferta on l'usuari ja s'ha apuntat: tinta verda + anell, perquè es
   distingeixi de cop d'ull al llistat i no s'hi torni a entrar. */
.card-soft.is-applied {
  background: var(--c-green-light);
  box-shadow:
    inset 0 0 0 1.5px var(--c-green),
    0 6px 18px -10px rgba(0, 140, 108, 0.35);
}
/* Sobre la card verda, un .pill-green es confondria amb el fons; el passem
   a blanc perquè el chip d'estat continuï llegint-se. */
.card-soft.is-applied .pill-green {
  background: #fff;
}

/* ── LA FORMA DE QUALSEVOL BOTÓ ──────────────────────────────────────────────
   Les quatre classes de sota (.btn-primary, .btn-secondary, .btn-ghost i
   .btn-danger) només PINTEN: color, ombra i transició. La forma —el padding, el
   radi, la lletra— l'havia de posar cada pantalla amb utilitats de Tailwind, i
   qui no ho feia es trobava un rectangle de color sense marges ni cantonades.
   Al 21 d'agost de 2026 n'hi havia 22 d'aquests repartits per l'aplicació
   («Pujar-ho tot a S3», «Configura els passos», el desa d'Absències…), i cada
   un s'havia d'anar trobant mirant pantalles.

   Això els dona la forma de sèrie. Va dins de :where() a posta, que té
   ESPECIFICITAT ZERO: qualsevol utilitat de Tailwind (`px-4`, `rounded-full`,
   `text-xs`…) o qualsevol classe de component (.bfil-btn, .abx-btn-nou…) hi
   guanya sense haver de tocar res. O sigui que els 269 botons que ja portaven
   la seva forma es queden EXACTAMENT igual i només canvien els que no en
   tenien cap.

   ⚠️ VA DINS DE `@layer components`, I AIXÒ ÉS EL QUE HO FA FUNCIONAR.
   Aquest Tailwind és la v4 i posa les utilitats dins de `@layer utilities`; en
   CSS, QUALSEVOL regla sense capa guanya a TOTES les que en tenen, tingui
   l'especificitat que tingui. O sigui que la resta d'aquest fitxer —que no té
   capa— passa per sobre de Tailwind sempre, i és el que fa que `.btn-primary
   { background }` mani sobre qualsevol `bg-*`.
   Aquí volem justament el CONTRARI: que `px-5` o `rounded-full` d'un botó
   concret manin sobre aquesta forma per defecte. Com que l'ordre de capes que
   declara el build és `properties, theme, base, components, utilities`, posar
   això a `components` deixa que les utilitats hi guanyin. El `:where()` s'hi
   queda com a segona xarxa per a les classes de component d'aquest mateix
   fitxer (.bfil-btn, .abx-btn-nou…), que no tenen capa i guanyen igualment.
   Es va provar primer amb `:where()` sol i no servia de res: amb capes pel
   mig, l'especificitat ja no decideix.

   ⚠️ El `display` no fa reaparèixer res amagat: el preflight de Tailwind porta
   `[hidden] { display: none !important }`, que hi passa per sobre. Comprovat
   abans d'escriure-ho, que era l'única manera que això trenqués alguna cosa. */
@layer components {
  :where(.btn-primary, .btn-secondary, .btn-ghost, .btn-danger) {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 16px;
    border: 0;
    border-radius: var(--r-btn);
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.2;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
  }
}
/* Un botó apagat s'ha de veure apagat, i no ha de convidar a prémer-lo. Aquí
   fora del :where() perquè guanyi als colors de sota. */
.btn-primary:disabled, .btn-secondary:disabled,
.btn-ghost:disabled,   .btn-danger:disabled,
.btn-primary[aria-disabled="true"], .btn-secondary[aria-disabled="true"],
.btn-ghost[aria-disabled="true"],   .btn-danger[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
  filter: none;
  transform: none;
}

/* CTA primari amb gradient vertical. */
.btn-primary {
  background: linear-gradient(180deg, var(--c-orange), var(--c-orange-dark));
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(243, 146, 0, 0.55);
  transition: filter 0.15s, transform 0.15s;
}
.btn-primary:hover  { filter: brightness(1.04); }
.btn-primary:active { transform: translateY(1px); filter: brightness(0.96); }

/* CTA secundari (ghost) — fons blanc, només ring. */
.btn-ghost {
  background: #fff;
  color: var(--c-ink);
  box-shadow: inset 0 0 0 1px var(--c-line);
  transition: background 0.15s;
}
.btn-ghost:hover { background: var(--c-warm); }

/* Botó QUADRAT d'icona (≤ 36 px). Poseu-hi això en comptes d'un `rounded-*`
   de Tailwind: `rounded-xl` deixa una caixa de 32 px quasi rodona i
   `rounded-lg` no lliga amb els botonets d'icona que ja porten `--r-btn-sm`
   des del seu component (.doc-act, .abs-del, .ctrl-btn…). Un sol radi per a
   tots. */
.btn-ico { border-radius: var(--r-btn-sm); }

/* CTA alternatiu verd (per a admin tools secundaris: logs, migracions, ...). */
.btn-secondary {
  background: linear-gradient(180deg, var(--c-green), var(--c-green-dark));
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(0, 177, 135, 0.55);
  transition: filter 0.15s, transform 0.15s;
}
.btn-secondary:hover  { filter: brightness(1.04); }
.btn-secondary:active { transform: translateY(1px); filter: brightness(0.96); }

/* CTA destructiu (red flags, deletes confirmats). */
.btn-danger {
  background: linear-gradient(180deg, var(--c-red), #b53129);
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(212, 66, 58, 0.55);
  transition: filter 0.15s, transform 0.15s;
}
.btn-danger:hover  { filter: brightness(1.04); }
.btn-danger:active { transform: translateY(1px); filter: brightness(0.96); }

/* Hero card amb gradient diagonal taronja (dashboard, busques-algu, etc.). */
.hero-orange {
  background: linear-gradient(135deg, var(--c-orange) 0%, var(--c-orange-dark) 100%);
  color: #fff;
}

/* Input estàndard amb focus orange.
   font-size 16px: imprescindible perquè iOS Safari NO faci zoom automàtic
   en enfocar el camp (passa sempre amb mides < 16px). El padding generós
   dona una zona tàctil còmoda (~46px d'alçada) a mòbil. */
.input-base {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 12px;
  padding: 12px 14px;
  font-size: 16px;
  line-height: 1.4;
  color: var(--c-ink);
  width: 100%;
  /* min-height fixa garanteix que input[type=date], select i textarea
     d'una sola línia tinguin la mateixa altura que els text inputs —
     sense això, el date picker natiu queda 2-4px més baix i trenca
     l'alineació de les files del grid. */
  min-height: 46px;
  box-sizing: border-box;
  transition: border-color 0.15s, box-shadow 0.15s;
}
/* Evita que el botó natiu de calendari/hora redueixi l'altura aparent
   del camp en iOS i alguns Chrome desktop. */
.input-base[type="date"],
.input-base[type="time"],
.input-base[type="datetime-local"] {
  -webkit-appearance: none;
  appearance: none;
}
.input-base::placeholder { color: var(--c-faint); }
.input-base:focus {
  outline: none;
  border-color: var(--c-orange);
  box-shadow: 0 0 0 3px rgba(243, 146, 0, 0.15);
}
.input-error {
  border-color: var(--c-red) !important;
  box-shadow: 0 0 0 3px rgba(212, 66, 58, 0.12);
}

/* Desplegables: mateixa caixa que un input de text, amb una fletxa nostra en
   comptes de la del sistema (que canvia de forma, de mida i de color segons
   el navegador i deixa un formulari amb camps que no s'assemblen entre ells).
   Va aquí, al costat de `.input-base`, i no a perfil.css com abans: la
   carreguen totes les pantalles i la classe ja s'usava a mitja app. */
.input-base.input-select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none'><path d='M3 6l5 5 5-5' stroke='%237a6f63' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  background-repeat: no-repeat;
  background-position: right 14px center;
  padding-right: 36px;
}

/* Checkboxes i radios — mida tàctil clara i color de marca. No fem servir
   el plugin de forms de Tailwind; per això els estilem aquí amb accent-color
   (abans es veien minúsculs i amb el color gris natiu del sistema).
   Els radios/checkboxes .sr-only (UI personalitzada a valoracions i
   red-flags) en queden exclosos perquè han de continuar amagats. */
input[type="checkbox"]:not(.sr-only),
input[type="radio"]:not(.sr-only) {
  width: 18px;
  height: 18px;
  accent-color: var(--c-orange);
  cursor: pointer;
  flex-shrink: 0;
}

/* Captcha anti-robots (ALTCHA) del registre i del login. El component viu dins
   d'un shadow DOM: no s'hi pot entrar amb selectors i només accepta les
   variables CSS que exposa. Les lliguem a la paleta de marca perquè el quadre
   es llegeixi com un `.input-base` més i no com una peça enganxada de fora.
   El markup el pinta captcha_camp() (funcions/captcha.php). */
.captcha-camp altcha-widget {
  --altcha-color-base: #fff;
  --altcha-color-border: var(--c-line);
  --altcha-color-border-focus: var(--c-orange);
  --altcha-color-text: var(--c-text);
  --altcha-color-error-text: var(--c-red);
  --altcha-color-footer-bg: var(--c-line-soft);
  --altcha-border-width: 1px;
  --altcha-border-radius: 12px;
  --altcha-max-width: 100%;
  /* `accent-color` s'hereta i travessa el shadow DOM: és l'única via per
     arribar a la casella de verificació de dins i pintar-la de taronja. */
  accent-color: var(--c-orange);
  display: block;
  font-size: 13px;
}

/* Sense JavaScript el widget no es pinta mai i el formulari no es podrà
   enviar: val més dir-ho que deixar la persona clicant el botó sense resposta. */
.captcha-noscript {
  margin-top: 6px;
  font-size: 12px;
  color: var(--c-red);
}

/* Eyebrow (subtítol over-line). */
.eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--c-muted);
}

/* Eyebrow sobre fons taronja: crema de marca opac (el blanc es veia rentat). */
.eyebrow-cream {
  color: var(--c-amber-light);
}

/* Pills (etiquetes rodones). */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
}
/* ⚠️ Un pill amagat amb la utilitat `hidden` de Tailwind s'ha de veure amagat.
   Tailwind es carrega ABANS que aquest full (elements/header.php) i `.hidden`
   té exactament la mateixa especificitat que `.pill`: sense aquesta línia,
   `display:inline-flex` guanya per ordre de càrrega i el pill es veu igualment.
   Passava de debò a «El meu horari» (/disponibilitat.php), que s'obria dient
   «Canvis sense desar» sense que ningú hagués tocat res. */
.pill.hidden { display: none; }
.pill-orange { background: var(--c-orange-faint); color: var(--c-orange-text); }
.pill-green  { background: var(--c-green-light);  color: var(--c-green-text); }
.pill-red    { background: var(--c-red-light);    color: var(--c-red-text); }
.pill-amber  { background: var(--c-amber-light);  color: var(--c-amber-text); }
.pill-muted  { background: var(--c-line-soft);    color: var(--c-muted); }
/* Pill verd sòlid — destaca sobre fons clars i sobre les cards .is-applied. */
.pill-applied { background: var(--c-green); color: #fff; }
/* Distintiu DESPATX de la pàgina d'inici (permís de grup `despatx.distintiu`).
   Taronja sòlid i amb espaiat entre lletres: no és un estat més d'una fila,
   és una etiqueta de la persona i ha de llegir-se com a tal. */
.pill-despatx { background: var(--c-orange); color: #fff; letter-spacing: 0.06em; }
/* Distintiu DESENVOLUPADOR (`users.is_developer`, funcions/desenvolupador.php).
   Fosc i sòlid, com .pill-despatx: no és un rol més de la llista sinó una marca
   que només es posa des de la base de dades, i s'ha de distingir d'una ullada
   del vermell d'«Administrador» amb què comparteix fila. Tipografia i mides,
   les de sempre — la píndola destaca pel color, no per semblar una altra app. */
.pill-dev {
  background: var(--c-ink);
  color: #fff;
  letter-spacing: 0.06em;
}

/* Switch on/off (toggle) sense dependre de Tailwind. Ús:
     <label class="switch">
       <input type="checkbox" ...>
       <span class="switch-track"><span class="switch-thumb"></span></span>
     </label>
   L'input real queda amagat (accessible via teclat); pinta el track + thumb. */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
}
.switch input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.switch-track {
  position: relative;
  flex-shrink: 0;
  width: 48px;
  height: 28px;
  border-radius: 999px;
  background: var(--c-line);
  transition: background 0.18s ease;
}
.switch-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(60, 40, 20, 0.3);
  transition: transform 0.18s ease;
}
.switch input:checked + .switch-track { background: var(--c-green); }
.switch input:checked + .switch-track .switch-thumb { transform: translateX(20px); }
.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--c-orange);
  outline-offset: 2px;
}

/* Match ring (anell amb % de coincidència) sense JS — només CSS conic-gradient.
   Ús:
     <div class="match-ring" style="--val:87;--col:var(--c-green);">
       <span>87</span>
     </div>
*/
.match-ring {
  --val: 0;
  --col: var(--c-green);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: conic-gradient(var(--col) calc(var(--val) * 1%), #eee5d4 0);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.match-ring::before {
  content: "";
  position: absolute;
  inset: 4px;
  background: #fff;
  border-radius: 50%;
}
.match-ring > span {
  position: relative;
  font-weight: 800;
  font-size: 13px;
  color: var(--col);
  letter-spacing: -0.02em;
}

/* Sub-bars (breakdown del match per dimensió).
   Ús: una llista de files amb label + barra + valor.
   <div class="sub-bars">
     <div class="sub-bar"><span class="sub-bar-label">Horari</span>
       <div class="sub-bar-track"><div class="sub-bar-fill" style="--val:80;"></div></div>
       <span class="sub-bar-value">80</span>
     </div>
   </div>
*/
.sub-bars        { display: flex; flex-direction: column; gap: 6px; }
.sub-bar         { display: flex; align-items: center; gap: 8px; }
.sub-bar-label   { font-size: 11px; color: var(--c-muted); width: 76px; flex-shrink: 0; }
.sub-bar-track   {
  flex: 1; height: 6px; border-radius: 3px; background: #eee5d4; overflow: hidden;
}
.sub-bar-fill    {
  --val: 0;
  height: 100%; border-radius: 3px;
  width: calc(var(--val) * 1%);
  background: var(--c-green);
  transition: width 0.3s ease-out;
}
.sub-bar-fill.amber  { background: var(--c-amber); }
.sub-bar-fill.red    { background: var(--c-red); }
.sub-bar-fill.orange { background: var(--c-orange); }
.sub-bar-value   { font-size: 11px; font-weight: 600; color: var(--c-ink); width: 34px; text-align: right; }

/* QUI HA POSAT CADA NOTA: la taula que va a sota de les sub-bars.
   Una mitjana amaga de qui és cada nota, i a una fitxa de personal això és
   justament el que es ve a mirar («un 2,4 de puntualitat: qui l'hi ha posat i
   quan?»). La pinta /public/treballadors/fitxa.php i la pagina
   /public/js/treballadors/valoracions-fitxa.js (DataTables, cinc per pàgina).

   ⚠️ Fins al 27 d'agost de 2026 n'hi havia UNA PER DIMENSIÓ, plegada dins d'un
   <details> que penjava de cada barra. Amb cinc dimensions, la mateixa
   valoració es pintava cinc vegades —i cinc valoracions ja eren vint-i-cinc
   files—. Ara és una de sola, sempre oberta i paginada: el que canvia entre
   dimensions és només el número, i aquell ja el diu la barra de sobre.

   Va aquí i no a un full de pantalla perquè és una peça de la mateixa família
   que .sub-bar* i s'ha de poder tornar a fer servir allà on hi hagi barres. */
.val-taula-caixa { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--c-line-soft); }
.val-taula       { width: 100%; border-collapse: collapse; font-size: 11.5px; }
.val-taula th {
  text-align: left; font-size: 9.5px; font-weight: 800; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--c-faint);
  padding: 0 6px 3px; border-bottom: 1px solid var(--c-line-soft);
}
.val-taula td {
  padding: 4px 6px; border-bottom: 1px solid var(--c-line-soft);
  color: var(--c-text); vertical-align: top;
}
.val-taula tr:last-child td { border-bottom: 0; }
.val-taula-qui   { font-weight: 700; color: var(--c-ink); }
.val-taula-quan  { color: var(--c-muted); white-space: nowrap; }
.val-taula-feina { color: var(--c-muted); }
/* La nota, amb el mateix codi de colors que la barra de sobre. És un BOTÓ: un
   clic obre, a la fila de sota, el repartiment per dimensió (les «child rows»
   de DataTables; ho lliga /js/treballadors/valoracions-fitxa.js).

   ⚠️ Va ser un `title` durant unes hores i no servia de res: res no deia que
   hi hagués cap cosa a mirar, i a mòbil i a tauleta no hi ha ratolí que hi
   pugui passar per sobre. Per això la fletxeta —és l'única pista—. */
.val-taula-nota  {
  display: inline-flex; align-items: center; gap: 3px;
  min-width: 30px; justify-content: center;
  font: inherit; font-weight: 800; line-height: 1.35;
  border: 0; border-radius: 9999px; padding: 1px 6px 1px 7px;
  background: var(--c-green-light); color: var(--c-green-text);
}
button.val-taula-nota { cursor: pointer; }
button.val-taula-nota:hover { filter: brightness(0.95); }
button.val-taula-nota:focus-visible {
  outline: none; box-shadow: 0 0 0 3px rgba(243, 146, 0, 0.35);
}
.val-taula-nota i { font-size: 7.5px; opacity: 0.75; transition: transform 0.15s; }
.val-taula-nota[aria-expanded="true"] i { transform: rotate(180deg); }
.val-taula-nota.amber { background: var(--c-amber-light); color: var(--c-amber-text); }
.val-taula-nota.red   { background: var(--c-red-light);   color: var(--c-red-text); }

/* El detall per dimensió. Es pinta de PHP dins de la mateixa cel·la de la nota i
   el JS el mou a la fila que s'obre, o sigui que aquí s'amaga a l'origen —però
   NOMÉS quan la taula ja és un DataTables—: sense JS no hi ha ni paginació ni
   fila que obrir, i el detall s'ha de poder llegir igual. */
#valoracionsTable.dataTable .val-taula-dims { display: none; }
.val-taula-dims       { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
tr.val-taula-detall > td { background: var(--c-warm); }
.val-taula-detall-in  { display: flex; flex-wrap: wrap; gap: 4px; padding: 1px 0; }
.val-taula-detall-in .pill { font-size: 10px; padding: 3px 8px; }

/* DataTables la vesteix amb les mides de les taules d'administració (14 px de
   lletra, 0,6 rem de coixinet) i es reserva 30 px a cada capçalera per a la
   fletxa d'ordre: mides d'una taula d'amplada sencera. Aquí viu dins d'una
   targeta que a `lg` ocupa un terç de la pantalla i s'hi ha de quedar amb la
   lletra petita de la fitxa —quatre vegades 30 px de recàrrec no hi caben—.

   ⚠️ Les capçaleres es diuen amb l'ID i no amb la classe perquè estils.css es
   carrega ABANS que el CSS de DataTables (elements/header.php: primer aquest,
   després $extra_css) i, a igualtat d'especificitat, guanyaria el seu. Al cos
   n'hi ha prou amb la classe: allà no hi competím amb cap regla tan concreta. */
#valoracionsTable thead > tr > th {
  font-size: 9.5px; letter-spacing: 0.04em;
  padding: 0 16px 5px 6px;
  border-bottom: 1px solid var(--c-line-soft);
}
#valoracionsTable thead > tr > th span.dt-column-order { right: 2px; width: 10px; }
table.dataTable.val-taula tbody td { font-size: 11.5px; padding: 5px 6px; }
/* ⚠️ Aquí l'ÚNICA fila de controls és el peu (recompte + pàgines): no hi ha ni
   cercador ni tria de mida. /css/admin/datatables.css vesteix la PRIMERA fila
   amb una tira crema perquè allà és la barra de filtres —i aquí la primera fila
   és el peu—, o sigui que se li treu i es dona la forma bona a totes dues, tant
   si DataTables arriba a pintar la de dalt buida com si se la salta. */
#valoracionsTable_wrapper .dt-layout-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; flex-wrap: wrap;
  margin: 8px 0 0; padding: 0; background: none; border: 0;
}
#valoracionsTable_wrapper .dt-info   { font-size: 10.5px; }
#valoracionsTable_wrapper .dt-paging .dt-paging-button { padding: 0.2rem 0.55rem; font-size: 0.78rem; }

@media (max-width: 40rem) {
  /* A mòbil la targeta ja és de l'ample de la pantalla, però quatre columnes
     amb un títol de jornada a dins no hi caben: cau la feina, que és la que es
     pot deduir de la data i de qui l'ha posada. */
  .val-taula-feina,
  .val-taula th:nth-child(3),
  .val-taula td:nth-child(3) { display: none; }
}

/* Avatar amb inicials, mida configurable via --size (default 36px).
   <div class="avatar" style="--size:48px;--bg:var(--c-orange);">AB</div>
*/
.avatar {
  --size: 36px;
  --bg: var(--c-orange);
  width: var(--size);
  height: var(--size);
  border-radius: 50%;
  background: var(--bg);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: calc(var(--size) * 0.38);
  letter-spacing: 0.2px;
  flex-shrink: 0;
}

/* Group d'avatars superposats (com els del disseny). */
.avatar-group           { display: inline-flex; }
.avatar-group .avatar   { border: 2px solid #fff; }
.avatar-group .avatar + .avatar { margin-left: -7px; }


/* ─── Alertes contextuals (elements/alerta.php) ───────────────────────────── */
/* Només els COLORS: la caixa, el padding i el flex els continuen posant les
   classes utility del propi element. Els tons de text són els corregits del
   bloc de variables (`--c-*-text`), que passen el 4,5:1 de la WCAG AA sobre el
   seu fons clar germà; els que hi havia abans —classes de Tailwind
   `text-brand-amber`, `text-brand-red`…— es quedaven entre 1,9:1 i 3,7:1.
   Vegeu la nota llarga a alert_type_styles() (funcions/helpers.php). */
.alerta--success { background: var(--c-green-light);  color: var(--c-green-text);  }
.alerta--error   { background: var(--c-red-light);    color: var(--c-red-text);    }
.alerta--warning { background: var(--c-amber-light);  color: var(--c-amber-text);  }
.alerta--info    { background: var(--c-orange-faint); color: var(--c-orange-text); }
/* Un enllaç dins d'una alerta hereta el to del missatge i se subratlla: en
   aquestes caixes, pintar-lo de taronja no el distingiria de res. */
.alerta a { color: inherit; font-weight: 700; text-decoration: underline; }


/* ─── Guia «Com funciona» (panell plegable) ───────────────────────────────── */
/* El component el pinta elements/guia.php i el fan servir una dotzena llarga de
   pantalles. És un <details> natiu: plega i desplega sense JS (funcions.js
   només en recorda l'estat).

   La capçalera va en TARONJA SUAU (fons `--c-orange-faint`, text
   `--c-orange-text`, filet a l'esquerra) i no en taronja ple, que és com era
   fins al 18 d'agost de 2026. El motiu: la guia ve PLEGADA i és opcional —qui
   la vol, l'obre— i pintada plena era, a totes aquelles pantalles, l'element
   més cridaner de la pàgina, per damunt del botó d'acció i, pitjor, per damunt
   dels avisos de debò (a /control-fitxatge.php, l'avís de «40 fitxades sense
   jornada» pesava menys que l'ajuda que té just a sobre). El taronja ple queda
   reservat a l'acció primària. */
.guia {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 16px;
  overflow: hidden;
  margin-bottom: 16px;
}
/* Dins d'un contenidor que ja separa els fills (flex/grid amb `gap`) el marge
   se sumaria al buit que ja hi ha: `guia--flush` el treu. */
.guia--flush { margin-bottom: 0; }

.guia-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 14px;
  cursor: pointer;
  list-style: none;                    /* amaga el triangle per defecte */
  color: var(--c-orange-text);
  background: var(--c-orange-faint);
  box-shadow: inset 3px 0 0 var(--c-orange);
  user-select: none;
}
.guia-head::-webkit-details-marker { display: none; }
.guia-head:hover { background: var(--c-orange-light); }
.guia[open] .guia-head { border-bottom: 1px solid var(--c-line); }
.guia-ico   { font-size: 15px; flex-shrink: 0; }
.guia-title { font-size: 13.5px; font-weight: 800; letter-spacing: -0.01em; flex-shrink: 0; }
.guia-sub {
  font-size: 12px;
  font-weight: 600;
  color: var(--c-muted);
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* `margin-left:auto` per si no hi ha subtítol (o s'amaga en mòbil): la fletxa
   queda sempre a la dreta. Amb subtítol no fa res — ell ja ocupa el buit. */
.guia-chevron { font-size: 12px; flex-shrink: 0; margin-left: auto; transition: transform 0.18s; }
.guia[open] .guia-chevron { transform: rotate(180deg); }

.guia-body { padding: 16px 18px 18px; }
/* Dues columnes quan hi caben: la guia és llarga i no ha de tapar la pantalla. */
.guia-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px 26px;
}
.guia-h {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}
.guia-h i { color: var(--c-orange); font-size: 12px; width: 15px; text-align: center; flex-shrink: 0; }
.guia-block p { font-size: 12.5px; line-height: 1.6; margin: 0 0 7px; color: var(--c-text); }
.guia-block p:last-child { margin-bottom: 0; }
.guia-block strong { font-weight: 700; color: var(--c-ink); }
.guia-block code {
  font-size: 11.5px;
  padding: 1px 5px;
  border-radius: 5px;
  background: var(--c-cream);
  border: 1px solid var(--c-line);
}
/* Les icones citades enmig del text (fletxes, paleta…) van en to secundari. */
.guia-block p i.fa-solid { color: var(--c-muted); }
/* Els enllaços dins de la guia, en taronja: es distingeixen del text pla. */
.guia-body a { color: var(--c-orange-dark); font-weight: 700; }
.guia-body a:hover { text-decoration: underline; }

.guia-foot {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 12px;
  line-height: 1.6;
  color: var(--c-muted);
  margin: 16px 0 0;
  padding-top: 13px;
  border-top: 1px solid var(--c-line-soft);
}
.guia-foot > i { color: var(--c-muted); margin-top: 3px; flex-shrink: 0; }
.guia-foot strong { color: var(--c-ink); font-weight: 700; }

@media (max-width: 640px) {
  /* Una sola columna; el subtítol de la capçalera sobra (amb el títol i la
     fletxa ja s'entén) i així no menja amplada. */
  .guia-sub  { display: none; }
  .guia-body { padding: 14px; }
  .guia-grid { grid-template-columns: minmax(0, 1fr); gap: 15px; }
  /* Xarxa de seguretat: un títol llarg passa a dues línies en comptes
     d'empènyer la fletxa fora de la capçalera. */
  .guia-title { flex-shrink: 1; min-width: 0; }
}


/* ───────────────────────────────────────────────────────────────────────────
   Mobile drawer (menú lateral per a < lg).
   Es controla amb [data-state="open|closed"] des de funcions.js.
   ─────────────────────────────────────────────────────────────────────────── */

/* ⚠️ LLISCAR DES DE LA VORA OBRE EL MENÚ, NO TIRA ENRERE (31 d'agost de 2026).
   A Chrome i als navegadors de Chromium, el «tirar enrere» amb el dit és un
   OVERSCROLL horitzontal, i això és el que l'apaga. Sense aquesta línia, el gest
   de setupDrawerSwipe() (public/js/funcions.js) competiria amb la navegació del
   navegador i sovint perdria.

   Es posa a l'eix X i prou: `overscroll-behavior-y` mou el «estira per
   recarregar» i el rebot vertical, que aquí no molesten i que treure'ls faria
   que la pàgina es notés encarcarada.

   A Safari/iOS l'«enrere» és un gest del sistema i això no l'atura; vegeu el
   comentari de setupDrawerSwipe(). */
html { overscroll-behavior-x: contain; }

.mobile-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(20, 14, 8, 0.45);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s ease-out;
}
.mobile-drawer-backdrop[data-state="open"] {
  opacity: 1;
  pointer-events: auto;
}

.mobile-drawer {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 51;
  width: 84%;
  max-width: 320px;
  background: #fff;
  display: flex;
  flex-direction: column;
  box-shadow: 0 12px 40px -8px rgba(60, 40, 20, 0.35);
  transform: translateX(-100%);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  will-change: transform;
}
.mobile-drawer[data-state="open"] {
  transform: translateX(0);
}

/* Bloqueja l'scroll del body quan el drawer està obert. */
body.drawer-open {
  overflow: hidden;
}


/* ───────────────────────────────────────────────────────────────────────────
   Engagement prompt — modal bloquejant de jornades proposades.
   Estat via [data-state="open|min"] des de elements/engagement-prompt.php.
   ─────────────────────────────────────────────────────────────────────────── */

.eng-prompt {
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none; /* deixa passar els clics excepte al backdrop/modal/bar */
}

.eng-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 14, 8, 0.55);
  backdrop-filter: blur(3px);
  pointer-events: auto; /* bloqueja la interacció amb la pàgina de sota */
}

.eng-modal {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(92vw, 440px);
  max-height: 92vh;
  overflow-y: auto;
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 24px 60px -12px rgba(60, 40, 20, 0.5);
  pointer-events: auto;
  animation: engModalIn 0.2s ease-out;
}
@keyframes engModalIn {
  from { transform: translate(-50%, -46%); opacity: 0; }
  to   { transform: translate(-50%, -50%); opacity: 1; }
}

/* Píndola minimitzada (fixa a baix). Ampla i centrada perquè el text es
   llegeixi bé; si en pantalles estretes no hi cap tot en una línia, el
   "Respon →" baixa de línia en lloc de sortir de la pantalla. */
.eng-bar {
  position: absolute;
  left: 50%;
  bottom: 18px;
  transform: translateX(-50%);
  pointer-events: auto;
  width: min(92vw, 460px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px 12px;
  background: linear-gradient(180deg, var(--c-orange), var(--c-orange-dark));
  color: #fff;
  font-weight: 700;
  font-size: 13.5px;
  line-height: 1.35;
  text-align: center;
  padding: 13px 22px;
  border: none;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 10px 26px -8px rgba(243, 146, 0, 0.7);
}
.eng-bar-txt {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.eng-bar-cta {
  background: rgba(255, 255, 255, 0.22);
  border-radius: 999px;
  padding: 4px 11px;
  white-space: nowrap;
}
/* L'animació d'entrada només quan és l'usuari qui minimitza (classe posada
   des del JS); si la pàgina ja arriba minimitzada, la píndola no rebota. */
.eng-prompt.eng-anim-bar .eng-bar {
  animation: engBarIn 0.25s ease-out;
}
@keyframes engBarIn {
  from { transform: translate(-50%, 24px); opacity: 0; }
  to   { transform: translate(-50%, 0);    opacity: 1; }
}

/* Estats: open mostra backdrop+modal; min mostra només la barra. */
.eng-prompt[data-state="open"] .eng-bar    { display: none; }
.eng-prompt[data-state="min"]  .eng-backdrop,
.eng-prompt[data-state="min"]  .eng-modal  { display: none; }

/* Missatge de benvinguda de l'oferta (HTML del TinyMCE, ja sanejat). Mateixa
   feina que .mur-body a /mur.php: retornar la tipografia que el reset de
   Tailwind treu a <p>, <ul> i companyia, que aquí ve escrita per una persona i
   no per l'app. */
.eng-benvinguda {
  margin-top: 6px;
  font-size: 13px;
  line-height: 1.65;
  color: var(--c-text);
  overflow-wrap: break-word;
}
.eng-benvinguda p { margin: 0 0 0.7em; }
.eng-benvinguda p:last-child { margin-bottom: 0; }
.eng-benvinguda a { color: var(--c-orange-dark); text-decoration: underline; }
.eng-benvinguda img { max-width: 100%; height: auto; border-radius: 8px; }
.eng-benvinguda ul, .eng-benvinguda ol { padding-left: 1.4em; margin: 0.4em 0; }
.eng-benvinguda ul { list-style: disc; }
.eng-benvinguda ol { list-style: decimal; }
.eng-benvinguda h1, .eng-benvinguda h2, .eng-benvinguda h3, .eng-benvinguda h4 {
  font-size: 14px; font-weight: 800; letter-spacing: -0.01em;
  margin: 0.8em 0 0.3em; color: var(--c-ink);
}
.eng-benvinguda table { max-width: 100%; border-collapse: collapse; }
.eng-benvinguda th, .eng-benvinguda td {
  border: 1px solid var(--c-line); padding: 4px 8px; font-size: 12px;
}
.eng-benvinguda blockquote {
  border-left: 3px solid var(--c-line);
  margin: 0.6em 0; padding: 0.2em 0 0.2em 0.9em;
  color: var(--c-muted);
}


/* ───────────────────────────────────────────────────────────────────────────
   Profile prompt — popup d'avís de perfil incomplet (< 60%). No és
   bloquejant: hi ha creu, "Més tard" i clic al fons per a tancar-lo.
   Visualment molt similar a eng-prompt però amb z-index inferior (55) perquè
   si engagement-prompt arriba a sortir alhora, té prioritat (60).
   ─────────────────────────────────────────────────────────────────────────── */

.prof-prompt {
  position: fixed;
  inset: 0;
  z-index: 55;
  pointer-events: none;
}

.prof-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 14, 8, 0.45);
  backdrop-filter: blur(2px);
  pointer-events: auto;
  cursor: pointer;
}

.prof-modal {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(92vw, 440px);
  max-height: 92vh;
  overflow-y: auto;
  background: #fff;
  border-radius: 20px;
  box-shadow: 0 24px 60px -12px rgba(60, 40, 20, 0.5);
  pointer-events: auto;
  animation: profModalIn 0.2s ease-out;
}
@keyframes profModalIn {
  from { transform: translate(-50%, -46%); opacity: 0; }
  to   { transform: translate(-50%, -50%); opacity: 1; }
}

.prof-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--c-warm);
  color: var(--c-muted);
  border: none;
  cursor: pointer;
  z-index: 1;
  transition: background 0.12s, color 0.12s;
}
.prof-close:hover {
  background: var(--c-line);
  color: var(--c-ink);
}


/* ───────────────────────────────────────────────────────────────────────────
   Tabs de perfil — barra compartida entre "Les meves dades" i "El meu horari".
   La pestanya de la pàgina on ets va destacada (gradient taronja).
   La classe base .profile-tab la reaprofiten altres pantalles amb pestanyes
   (quilometratges-i-extres.php, control-km-extres.php) amb .is-active.
   ─────────────────────────────────────────────────────────────────────────── */

/* El CONTENIDOR va aqui i no a perfil.css, encara que hi va neixer. Viure alla
   volia dir que nomes el tenien les pagines que carreguen perfil.css, i
   control-km-extres.php —que la capcalera d'aqui dalt ja diu que reaprofita
   aquestes pestanyes— no el carrega: carrega control.css, extres.css i
   fitxatge.css. Sense aquesta regla el contenidor no era cap flex, i com que
   .profile-tab es inline-flex les pestanyes sortien enganxades, separades
   nomes pel blanc entre etiquetes en lloc dels 10px del gap. Una regla que
   fa servir mes d'una pantalla ha de viure al full global. */
.profile-tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 24px;
}
@media (max-width: 640px) {
  .profile-tabs { gap: 8px; margin-bottom: 20px; }
}

.profile-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 10px 15px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  background: #fff;
  color: var(--c-ink);
  box-shadow: inset 0 0 0 1px var(--c-line), 0 1px 4px rgba(60, 40, 20, 0.07);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, box-shadow 0.12s, filter 0.12s;
}
.profile-tab:hover {
  background: var(--c-cream);
  box-shadow: inset 0 0 0 1px var(--c-orange), 0 1px 4px rgba(60, 40, 20, 0.07);
}
.profile-tab.is-active {
  background: var(--c-ink);
  color: #fff;
  box-shadow: 0 5px 14px -5px rgba(42, 37, 31, 0.55);
}


/* ── Nav compartit "Les meves dades ↔ El meu horari" ───────────────────────
   Només dos tabs, un per pàgina: el d'on ets (taronja, amb «Ets aquí») i el de
   l'altra (clar, amb fletxa). Vegeu elements/perfil-nav.php. Abans hi havia
   també un tab per apartat del perfil, amb grups i divisor; sis tabs es
   menjaven mitja pantalla de mòbil abans d'arribar a la graella de l'horari. */
.profile-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 22px;
}
@media (max-width: 640px) {
  .profile-nav { margin-bottom: 16px; }
  /* Dos tabs hi caben; si el text creix (o la lletra del sistema és més
     gran), que baixin un sota l'altre en comptes de sortir per la dreta. */
  .profile-tab { flex: 1 1 auto; justify-content: center; }
}

/* "Ets aquí" — tab actiu, no clicable. Degradat taronja sense :hover (no és un enllaç). */
.profile-tab.is-active-page {
  background: linear-gradient(180deg, var(--c-orange), var(--c-orange-dark));
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(243, 146, 0, 0.55);
  cursor: default;
}
.profile-tab.is-active-page:hover {
  background: linear-gradient(180deg, var(--c-orange), var(--c-orange-dark));
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(243, 146, 0, 0.55);
  filter: none;
}

/* Etiqueta dins del tab actiu. Amb només dos tabs el color ja distingeix,
   però dir-ho amb lletres estalvia haver-ho de deduir. */
.profile-tab-here {
  font-size: 9.5px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: rgba(255, 255, 255, 0.24);
  border-radius: 999px;
  padding: 2px 7px;
  line-height: 1.35;
}

/* "Pots anar-hi" — tab d'una altra pàgina. Fons cream (no blanc pur) +
   icona de fletxa al final per indicar que es marxa. */
.profile-tab.is-other-page {
  background: var(--c-warm);
  color: var(--c-text);
  box-shadow: inset 0 0 0 1px var(--c-line);
}
.profile-tab.is-other-page:hover {
  background: #fff;
  color: var(--c-ink);
  box-shadow: inset 0 0 0 1px var(--c-orange), 0 1px 4px rgba(60, 40, 20, 0.07);
}


/* ───────────────────────────────────────────────────────────────────────────
   Capçalera sticky — la capçalera (mòbil i desktop) es queda enganxada a
   dalt. En fer scroll cap avall es compacta (versió reduïda): amaga
   l'eyebrow, encongeix el títol i retalla el padding per guanyar espai
   vertical. La classe .is-compact la posa setupStickyHeader() (funcions.js).
   ─────────────────────────────────────────────────────────────────────────── */
.app-header {
  position: sticky;
  top: 0;
  z-index: 30;
  transition: box-shadow 0.2s ease, padding 0.2s ease;
}
.app-header.is-compact {
  box-shadow: 0 6px 20px -12px rgba(20, 14, 8, 0.45);
}

/* Transicions suaus en compactar/expandir. */
.app-header-row,
.app-header-title {
  transition: padding 0.2s ease, font-size 0.2s ease, margin 0.2s ease;
}

/* Amaga l'eyebrow (text petit sobre el títol) quan la capçalera es compacta. */
.app-header.is-compact .eyebrow { display: none; }

/* Capçalera mòbil compacta: menys padding vertical i títol més petit. */
.app-header.is-compact .app-header-row    { padding-top: 7px; padding-bottom: 7px; }
.app-header.is-compact .app-header-title  { font-size: 14px; }

/* Capçalera desktop compacta: menys padding i títol més petit. */
@media (min-width: 1024px) {
  .app-header.is-compact                  { padding-top: 10px; padding-bottom: 10px; }
  .app-header.is-compact .app-header-title { font-size: 19px; margin-top: 0; }
}


/* ───────────────────────────────────────────────────────────────────────────
   PWA / safe areas — quan l'app s'instal·la a la pantalla d'inici (mode
   standalone) cal respectar el notch (dalt) i l'indicador d'inici (baix) de
   l'iPhone. env(safe-area-inset-*) val 0 en un navegador normal, així que és
   segur aplicar-ho sempre.
   ─────────────────────────────────────────────────────────────────────────── */

/* Capçalera mòbil: aparta el contingut de sota el notch / barra d'estat. */
.mobile-topbar {
  padding-top: env(safe-area-inset-top);
}

/* ── Pila flotant inferior (elements/bottom-nav.php) ─────────────────────────
   La caixa fixa que porta la barra de navegació. Es va fer pila perquè a sobre
   de la barra hi havia el botó de fitxatge ràpid; des del 5 d'agost de 2026
   allò ja no hi és (el fitxatge viu a l'inici i a /fitxatge.php, no sota totes
   les pantalles) i la pila té un sol fill. Es manté perquè és qui posiciona:
   la barra només és la pastilla blanca, i la pila creix cap amunt tota sola si
   demà hi torna a haver res. La separació de la vora respecta l'indicador
   d'inici de l'iPhone. */
.bnav-stack {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: calc(12px + env(safe-area-inset-bottom));
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Només mòbil. Va explícit i no amb la utilitat `lg:hidden`: estils.css es
   carrega DESPRÉS de tailwind.css i el `display:flex` de sobre li guanyaria. */
@media (min-width: 1024px) { .bnav-stack { display: none; } }

.bottom-nav {
  background: #fff;
  border-radius: 22px;
  box-shadow: 0 10px 30px -10px rgba(60, 40, 20, 0.25);
  padding: 10px 8px;
}

.bnav-grid { display: grid; gap: 4px; }

/* Cada cel·la: icona a sobre i etiqueta a sota, TOT centrat. L'etiqueta és un
   bloc d'amplada sencera amb text-align:center — amb `align-items:center` sol,
   una etiqueta de dues paraules («Borsa completa») s'ajusta a l'amplada de la
   cel·la i les seves línies queden alineades a l'esquerra. */
.bnav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  color: var(--c-muted);
  font-weight: 500;
  text-decoration: none;
}
.bnav-ico {
  position: relative;
  width: 34px;
  height: 28px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  transition: background 0.15s, color 0.15s;
}
.bnav-txt {
  width: 100%;
  text-align: center;
  font-size: 10px;
  line-height: 1.15;
  /* Fins a dues línies; el que no hi càpiga, punts suspensius. Una etiqueta
     llarga no ha de fer créixer la barra sense fre. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

/* ON ETS: pastilla taronja plena sota la icona i etiqueta en negreta. Abans
   només hi havia un fons molt clar i, amb la barra blanca, no es veia. */
.bnav-item.is-active { color: var(--c-orange-dark); font-weight: 800; }
.bnav-item.is-active .bnav-ico {
  background: var(--c-orange);
  color: #fff;
  box-shadow: 0 4px 12px -4px var(--c-orange);
}
/* L'accés automàtic a Emotium destaca també a la mostra de configuració. */
.bnav-item.is-emotium {
  background: #00b187;
  color: #fff;
  font-weight: 700;
  border-radius: 14px;
  padding: 4px 2px;
}
.bnav-item.is-emotium .bnav-ico,
.bnav-item.is-emotium.is-active .bnav-ico {
  background: #fff;
  box-shadow: none;
  width: 28px;
  height: 28px;
  border-radius: 50%;
}
.emotium-icon { display: block; width: 22px; height: 22px; object-fit: contain; }
/* La intranet de Pesem i Transformem (4 d'octubre de 2026): el mateix destacat
   que Emotium, en el taronja de Pesem (#f39c12) enfosquit perquè el text blanc
   es llegeixi. A la barra de baix només es pinta la icona: Pesem no hi té lloc
   reservat, i un bloc de color sencer hi faria més soroll que Emotium. */
.bnav-item.is-pesem .bnav-ico,
.bnav-item.is-pesem.is-active .bnav-ico {
  background: #d9730d;
  color: #fff;
}

.bnav-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 15px;
  height: 15px;
  padding: 0 3px;
  border-radius: 999px;
  background: var(--c-red);
  color: #fff;
  font-size: 8.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── Triador de la barra mòbil (/configuracio.php) ───────────────────────────
   On cadascú tria quins cinc botons vol a la barra de sobre. Fins a l'11 d'agost
   de 2026 era una llista plana de caselles: amb els permisos d'un administrador
   passava de trenta ítems i la pantalla era una tirallonga on ningú no trobava
   res. Ara va per seccions plegades del menú i en graella de dues columnes, de
   manera que d'entrada només s'hi veuen les capçaleres i la previsualització.

   La previsualització reutilitza les classes de la barra de debò (.bottom-nav,
   .bnav-*) a posta: si un dia canvia com es veu la barra, la mostra canvia
   sola. L'única cosa que no s'agafa és .bnav-stack, que és qui la fixa a baix
   de la pantalla — aquí ha de quedar-se dins de la targeta. */
/* ── Accés ràpid de /configuracio.php cap a «Les meves dades» ────────────────
   Un .btn-ghost encongit. Va amb CSS i no amb utilitats de Tailwind perquè les
   que caldrien (`py-1.5`, `gap-1.5`, `text-[12px]`) NO són al build, que està
   purgat: hi serien al marcatge i no farien res (../../CLAUDE.md §CSS).
   Aquí, sense capa, guanya a la forma per defecte dels .btn-* de dalt. */
.cfg-rapid {
  padding: 6px 12px;
  gap: 6px;
  font-size: 12px;
  color: var(--c-muted);
}
.cfg-rapid:hover { color: var(--c-orange-dark); }
.cfg-rapid-fletxa { font-size: 9px; opacity: .7; }

.navpick-preview {
  background: var(--c-cream);
  border: 1px solid var(--c-line-soft);
  border-radius: 16px;
  padding: 13px 12px 15px;
  margin-bottom: 16px;
}
.navpick-preview-cap {
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--c-faint);
  text-align: center;
  margin-bottom: 10px;
}
/* Amplada de mòbil encara que la targeta sigui ampla: la barra només existeix
   allà, i estirada a tot l'ample no s'assemblaria al que es veurà. */
.navpick-preview .bottom-nav { max-width: 360px; margin: 0 auto; }
/* Sense cap botó triat: la barra no es pinta i es diu per què. */
.navpick-buit {
  font-size: 12px;
  color: var(--c-muted);
  text-align: center;
  padding: 12px 8px;
}

/* Cada secció del menú, plegable. És un <details> natiu: plega i desplega
   sense JS. S'obren soles les que porten algun botó triat (ho decideix el PHP a
   /configuracio.php), que és l'únic que interessa mirar en entrar-hi. */
.navpick-grup {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 14px;
  overflow: hidden;
  margin-bottom: 8px;
}
.navpick-head {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 10px 12px;
  cursor: pointer;
  list-style: none;                    /* amaga el triangle per defecte */
  user-select: none;
}
.navpick-head::-webkit-details-marker { display: none; }
.navpick-head:hover { background: var(--c-cream); }
.navpick-head-ico { color: var(--c-orange); font-size: 12.5px; width: 16px; text-align: center; flex-shrink: 0; }
.navpick-head-txt {
  font-size: 13px;
  font-weight: 800;
  letter-spacing: -0.01em;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* «2 de 9»: quants n'hi ha triats d'aquesta secció. Amb la secció plegada és
   l'única pista que hi tens res, i per això s'encén en taronja quan no és zero. */
.navpick-head-n { font-size: 11.5px; font-weight: 700; color: var(--c-faint); flex-shrink: 0; }
.navpick-head-n.is-on { color: var(--c-orange-dark); }
.navpick-chevron { font-size: 11px; color: var(--c-faint); flex-shrink: 0; transition: transform 0.18s; }
.navpick-grup[open] .navpick-chevron { transform: rotate(180deg); }

/* Dues columnes a partir d'uns 320 px d'amplada útil, que és el que dona la
   targeta al mòbil més estret. */
.navpick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 6px;
  padding: 2px 10px 11px;
}

/* La casella de cada ítem. El <input> hi és de debò (només amagat a la vista)
   perquè el formulari, el teclat i els lectors de pantalla continuïn funcionant
   com amb qualsevol checkbox: aquí només se'n canvia el vestit. */
.navpick { display: block; position: relative; cursor: pointer; min-width: 0; }
.navpick input { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }

.navpick-box {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  padding: 7px 9px;
  border: 1px solid var(--c-line-soft);
  border-radius: var(--r-btn);
  background: #fff;
  transition: border-color 0.15s, background 0.15s;
}
.navpick:hover .navpick-box { background: var(--c-cream); }
.navpick-ico { font-size: 12px; color: var(--c-faint); width: 15px; text-align: center; flex-shrink: 0; }
.navpick-txt {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--c-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.navpick-tick {
  display: none;
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  border-radius: var(--r-pill);
  background: var(--c-orange);
  color: #fff;
  font-size: 9px;
  align-items: center;
  justify-content: center;
}

.navpick input:checked + .navpick-box { border-color: var(--c-orange); background: var(--c-orange-faint); }
.navpick input:checked + .navpick-box .navpick-ico { color: var(--c-orange); }
.navpick input:checked + .navpick-box .navpick-txt { font-weight: 800; color: var(--c-ink); }
.navpick input:checked + .navpick-box .navpick-tick { display: flex; }
/* El focus del teclat s'ha de veure: l'input real és invisible i sense això no
   se sabria mai on ets navegant amb el tabulador. */
.navpick input:focus-visible + .navpick-box { outline: 2px solid var(--c-orange); outline-offset: 2px; }
/* Ja hi ha els cinc botons triats: la resta queden apagades fins que en treguis
   una. El cursor va a la caixa i no a l'etiqueta perquè és qui l'omple sencera. */
.navpick input:disabled + .navpick-box { opacity: 0.45; cursor: not-allowed; }


/* ═══════════════════════════════════════════════════════════════════════════
   FITXATGE RÀPID DE L'INICI (elements/fitxatge-rapid.php)

   /fitxatge.php RESUMIT en una targeta ampla a dalt de tot de /index.php: a
   l'esquerra quin dia i quina hora és i com estàs, a la dreta l'acció. En
   mòbil s'apila i el botó passa a ocupar tota l'amplada, que és on hi va el
   dit.

   Des del 5 d'agost de 2026 aquest és l'ÚNIC fitxatge fora de la pantalla
   sencera —el botó que flotava sobre la barra inferior a TOTES les pantalles
   ja no hi és— i per això s'hi assembla tant: mateix rellotge, mateix xip
   d'estat, mateix botó rodó verd per entrar i mateixa pastilla vermella per
   plegar. Els estils viuen aquí i no a fitxatge.css perquè l'inici no carrega
   aquell full: són una còpia curta, no el mateix codi. Si allà canvia el
   llenguatge visual, aquí també.

   Mateix codi de color que /fitxatge.php: VERD per començar la jornada,
   VERMELL per plegar-la. El color el porta la targeta (`is-fora` / `is-dins`)
   i el reparteix a la vora i al botó.
   ═══════════════════════════════════════════════════════════════════════════ */
.fitxr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 18px;
  margin-top: 12px;
  padding: 18px 20px;
  background: #fff;
  border-radius: var(--r-card);
  border-left: 4px solid var(--fitxr-c, var(--c-green));
  box-shadow:
    0 1px 0 rgba(60, 40, 20, 0.04),
    0 6px 18px -10px rgba(60, 40, 20, 0.18);
}
.fitxr.is-fora { --fitxr-c: var(--c-green); }
.fitxr.is-dins { --fitxr-c: var(--c-red); }

.fitxr-info { min-width: 0; flex: 1 1 240px; }
.fitxr-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.fitxr-ara { min-width: 0; }

/* Data i rellotge: els de /fitxatge.php a escala d'inici. Tots dos els repinta
   cada segon public/js/fitxatge-rapid.js amb l'hora del SERVIDOR. */
.fitxr-date {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--c-muted);
}
.fitxr-clock {
  font-variant-numeric: tabular-nums;
  font-size: 32px;
  line-height: 1.05;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--c-ink);
  margin-top: 2px;
}
.fitxr-clock small {
  font-size: 16px;
  font-weight: 700;
  color: var(--c-faint);
  margin-left: 2px;
}

/* Xip d'estat: les mateixes tres variants que .fitx-status (fitxatge.css). */
.fitxr-status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: var(--r-pill);
  font-size: 11.5px;
  font-weight: 800;
  white-space: nowrap;
}
.fitxr-status-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.fitxr-status.is-working { background: var(--c-green-light); color: var(--c-green-text); }
.fitxr-status.is-working .fitxr-status-dot {
  background: var(--c-green);
  animation: fitxrPulse 1.8s infinite;
}
.fitxr-status.is-paused  { background: var(--c-amber-light); color: var(--c-amber-text); }
.fitxr-status.is-paused .fitxr-status-dot { background: var(--c-amber); }
.fitxr-status.is-off     { background: var(--c-line-soft); color: var(--c-muted); }
.fitxr-status.is-off .fitxr-status-dot    { background: var(--c-faint); }

@keyframes fitxrPulse {
  0%   { box-shadow: 0 0 0 0 rgba(0, 177, 135, 0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(0, 177, 135, 0); }
  100% { box-shadow: 0 0 0 0 rgba(0, 177, 135, 0); }
}

/* Xips de context: des de quina hora i a quina jornada van les hores. Aquí NO
   hi van els minuts fitxats (ni corrent ni parats): el temps del dia és a
   /fitxatge.php, que és on es va a mirar. */
/* Amb més d'una jornada activa no hi ha cap xip a dir —ho diu el selector— i
   llavors el PHP no pinta ni la fila: aquí no cal preveure-ho. */
.fitxr-chips { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px; }
.fitxr-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  background: var(--c-warm);
  color: var(--c-text);
  border-radius: var(--r-pill);
  padding: 6px 12px;
  font-size: 11.5px;
  font-weight: 600;
  overflow-wrap: anywhere;
}
.fitxr-chip i { color: var(--c-muted); font-size: 11px; flex-shrink: 0; }
.fitxr-chip.is-buit { color: var(--c-muted); }
.fitxr-chip.is-buit i { color: var(--c-faint); }

/* ── Pastilla del CANVI DE JORNADA AUTOMÀTIC ─────────────────────────────────
   La bessona de .fitx-auto (public/css/fitxatge.css): la mateixa pastilla verda
   amb títol i detall petit a sota, i el mateix text. Si allà canvia el
   llenguatge visual, aquí també.

   Va a la SEVA LÍNIA i no dins de cap de les dues columnes: `flex: 1 1 100%`
   dins d'un `.fitxr` que ja té `flex-wrap: wrap` la fa baixar sota de totes
   dues. Ha de sortir en tots els estats —també els dies que s'és fora, quan a
   la dreta no hi ha ni formulari—, i per això no penja de l'acció. */
.fitxr-auto {
  flex: 1 1 100%;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 13px;
  border-radius: 13px;
  background: var(--c-green-light);
  color: var(--c-green-text);
}
.fitxr-auto i { margin-top: 2px; flex-shrink: 0; color: var(--c-green); }
.fitxr-auto-cos { min-width: 0; }
.fitxr-auto-cos strong {
  display: block;
  font-size: 12.5px;
  font-weight: 800;
  margin-bottom: 1px;
}
.fitxr-auto-cos span {
  display: block;
  font-size: 11.5px;
  line-height: 1.5;
  opacity: 0.9;
}

/* Columna de l'acció: selector (si cal), botó i enllaç a la pantalla sencera. */
.fitxr-accio {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 9px;
  flex: 0 1 260px;
  min-width: 0;
}
/* Etiqueta del selector: el «pas 1» de /fitxatge.php, sense el numeret. */
.fitxr-pas {
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--c-muted);
  cursor: pointer;
}
.fitxr-select {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--c-line);
  border-radius: var(--r-btn);
  background: #fff;
  color: var(--c-ink);
  font-size: 13px;
  font-weight: 700;
  text-align: center;
  text-align-last: center;   /* Firefox pinta el text triat a l'esquerra sense això */
  cursor: pointer;
}
.fitxr-select:focus {
  outline: none;
  border-color: var(--c-orange);
  box-shadow: 0 0 0 3px rgba(243, 146, 0, 0.15);
}

/* ── Botó rodó d'entrada ─────────────────────────────────────────────────────
   El .fitx-punch de /fitxatge.php reduït a 132 px. L'anell que batega és un
   ::after i no ocupa lloc al layout: l'espai que necessita per no trepitjar
   l'enllaç de sota es reserva a mà amb el marge. */
.fitxr-punch {
  position: relative;
  width: 132px;
  height: 132px;
  margin: 8px 0 18px;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  color: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  background: radial-gradient(120% 120% at 50% 12%, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0) 55%),
              linear-gradient(180deg, var(--c-green), var(--c-green-dark));
  box-shadow: 0 14px 30px -12px rgba(0, 177, 135, 0.7), inset 0 2px 0 rgba(255, 255, 255, 0.28);
  transition: transform 0.12s ease, filter 0.15s ease;
  -webkit-tap-highlight-color: transparent;
}
.fitxr-punch::before,
.fitxr-punch::after {
  content: "";
  position: absolute;
  inset: -7px;
  border-radius: 50%;
  border: 2px solid var(--c-green);
  opacity: 0.35;
}
.fitxr-punch::after { opacity: 0.5; animation: fitxrRing 2.4s ease-out infinite; }
@keyframes fitxrRing {
  0%   { transform: scale(1);    opacity: 0.5; }
  100% { transform: scale(1.12); opacity: 0; }
}
.fitxr-punch:hover  { filter: brightness(1.04); }
.fitxr-punch:active { transform: scale(0.97); }
.fitxr-punch:focus-visible { outline: 3px solid var(--c-ink); outline-offset: 4px; }
.fitxr-punch-ico   { font-size: 30px; line-height: 1; margin-bottom: 2px; }
.fitxr-punch-label { font-size: 13.5px; font-weight: 800; }
.fitxr-punch-sub {
  max-width: 104px;
  font-size: 10.5px;
  font-weight: 600;
  line-height: 1.3;
  opacity: 0.9;
  font-variant-numeric: tabular-nums;
}

/* ── Pastilla vermella de sortida ─────────────────────────────────────────── */
.fitxr-finish {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  width: 100%;
  min-height: 48px;
  padding: 12px 20px;
  border: none;
  border-radius: var(--r-pill);
  cursor: pointer;
  font-family: inherit;
  font-size: 14px;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(180deg, var(--c-red), #b53129);
  box-shadow: 0 8px 20px -8px rgba(212, 66, 58, 0.6);
  transition: filter 0.15s, transform 0.12s;
}
.fitxr-finish:hover  { filter: brightness(1.05); }
.fitxr-finish:active { transform: translateY(1px); }
.fitxr-finish:focus-visible { outline: 3px solid var(--c-ink); outline-offset: 3px; }
.fitxr-finish-hora { font-size: 11.5px; font-weight: 600; opacity: 0.85; }

/* Mentre s'espera la ubicació (fitxatge-rapid.js). El botó segueix dient què
   passa al seu text petit: aquí només es treu el convit a tornar-hi. */
.fitxr-punch.is-enviant,
.fitxr-finish.is-enviant { cursor: progress; filter: saturate(0.85); }

.fitxr-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--c-muted);
}
.fitxr-link:hover { color: var(--c-orange-dark); }
.fitxr-link i { font-size: 10px; }

@media (max-width: 640px) {
  .fitxr { padding: 16px; }
  .fitxr-accio { flex: 1 1 100%; }
}
@media (prefers-reduced-motion: reduce) {
  .fitxr-punch::after,
  .fitxr-status.is-working .fitxr-status-dot { animation: none; }
}

/* ── --nav-bottom-space: quant amaga la barra inferior ───────────────────────
   ALÇADA REAL de la bottom-nav + la seva separació de la vora (12px), SENSE la
   safe area (que cada consumidor hi suma a part). Val 0 a partir de lg, on la
   barra no existeix.

   Tot el que flota a baix de la pantalla (el candau de l'horari, la paleta de
   pintura, «Tens canvis sense desar», la barra minimitzada de jornades) s'hi ha
   de recolzar en comptes de portar un número màgic a mà: els números màgics
   anaven ajustats a una barra de ~65 px i, en mòbils on l'etiqueta passa a dues
   línies o el sistema puja la mida de lletra, la barra creix i el botó flotant
   li queda a sobre.

   El valor d'aquí és el FALLBACK (els 66 px que fa amb la lletra per defecte);
   setupBottomNavSpace() a funcions.js el mesura de veritat i el reescriu com a
   estil inline a <html>, que guanya sobre aquestes dues regles. */
@media (max-width: 1023px) { :root { --nav-bottom-space: 78px; } }
@media (min-width: 1024px) { :root { --nav-bottom-space: 0px;  } }

/* El contingut principal mòbil ha de deixar espai per la bottom-nav fixa
   + la safe area inferior (no es retalla l'última targeta). */
@media (max-width: 1023px) {
  .app-main {
    padding-bottom: calc(var(--nav-bottom-space, 78px) + 2rem + env(safe-area-inset-bottom));
  }
}

/* Barra minimitzada del modal de jornades: per damunt de l'indicador i, en
   mòbil, per damunt de la bottom-nav (no s'hi ha de solapar). */
.eng-bar {
  bottom: calc(18px + var(--nav-bottom-space, 0px) + env(safe-area-inset-bottom));
}

/* ── .save-float · píndola «Tens canvis sense desar» ─────────────────────────
   Component compartit: apareix quan hi ha canvis pendents i desapareix quan no
   n'hi ha, de manera que el botó de desar només ocupa pantalla quan serveix
   d'alguna cosa. El fan servir /disponibilitat.php, /les-meves-dades.php,
   /admin/notificacions.php i /ofertes/nova.php.

   Aquesta ja és l'ÚNICA còpia: la de `disponibilitat.css` va desaparèixer el 5
   d'agost del 2026 en plegar en un sol dock tot el que hi flotava, i la de
   `perfil.css` —que es carregava després i, per sota de 480 px, deixava la
   píndola esprémuda dins de la meitat dreta de la pantalla— l'endemà.

   Es pinta amb `is-visible` JA POSAT a l'HTML i és el JS qui la treu en
   carregar: sense JavaScript la píndola es queda visible i fa de botó de desar
   normal, en comptes de deixar un formulari que no es pot enviar. */
.save-float {
  position: fixed;
  z-index: 46;
  left: 50%;
  bottom: calc(20px + var(--nav-bottom-space, 0px) + env(safe-area-inset-bottom));
  transform: translateX(-50%) translateY(20px);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 8px 8px 16px;
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 9999px;
  box-shadow: 0 16px 40px -12px rgba(20, 14, 8, 0.42);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.22s ease, opacity 0.22s ease;
}
.save-float.is-visible {
  transform: translateX(-50%) translateY(0);
  opacity: 1;
  pointer-events: auto;
}
.save-float-text {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--c-text);
  white-space: nowrap;
}
.save-float-text i { color: var(--c-amber); }
.save-float-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 0;
  border-radius: 9999px;
  background: var(--c-orange);
  color: #fff;
  font-size: 12.5px;
  font-weight: 800;
  cursor: pointer;
  transition: filter 0.12s;
}
.save-float-btn:hover    { filter: brightness(1.07); }
.save-float-btn:disabled { opacity: 0.6; cursor: default; }
/* Acció secundària dins de la píndola (descartar els canvis). */
.save-float-ghost {
  border: 0;
  background: none;
  padding: 6px 10px;
  border-radius: 9999px;
  font-size: 12px;
  font-weight: 700;
  color: var(--c-muted);
  cursor: pointer;
}
.save-float-ghost:hover { background: var(--c-cream); color: var(--c-ink); }

/* Amb la finestra estreta la píndola no hi cap centrada: es queda de vora a
   vora. Perquè no s'hagi de menjar tres línies de pantalla —que amb la barra
   inferior a sota són massa—, l'etiqueta llarga del botó s'escurça a «Desa»
   (`.save-float-llarg`) i així tot torna a cabre en una línia. */
@media (max-width: 479px) {
  .save-float {
    left: 12px;
    right: 12px;
    transform: translateY(20px);
    border-radius: 18px;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    padding: 10px 12px;
  }
  .save-float.is-visible { transform: translateY(0); }
  .save-float-text { font-size: 12px; }
  .save-float-llarg,
  .save-float-mig { display: none; }
}

/* Drawer lateral mòbil: respecta notch i indicador d'inici. */
.mobile-drawer {
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
}


/* ───────────────────────────────────────────────────────────────────────────
   Sidebar de desktop (elements/sidebar.php)

   Dues coses:
   a) BLOC D'USUARI FIX — la barra és una columna flex d'alçada de pantalla amb
      tres bandes: capçalera (logo + botó), cos (.app-sidebar-scroll, l'única
      amb overflow) i peu (.app-sidebar-user). Així el nom d'usuari, la roda
      dentada i el botó de sortir no marxen mai de la vista encara que el menú
      no hi càpiga.
   b) PLEGABLE estil Gmail — el botó [data-sidebar-toggle] posa
      `sidebar-collapsed` a <html> (setupSidebarToggle() a funcions.js;
      header.php l'aplica abans de pintar llegint localStorage, per evitar el
      salt visual). Plegada, la barra és una tira d'icones: s'amaguen
      etiquetes, títols de secció i xevrons, i tot se centra.

   Va sobre <html> i no sobre l'<aside> perquè l'script anti-salt del <head>
   s'executa quan l'<aside> encara no existeix.

   Tot dins de @media lg: per sota, el menú és el drawer mòbil i l'<aside>
   ni tan sols es mostra (.hidden lg:flex).
   ─────────────────────────────────────────────────────────────────────────── */
@media (min-width: 1024px) {
  /* 208 i no 230: la queixa era que la barra es menjava massa pantalla. Amb
     l'etiqueta més llarga del menú («Quilometratges i extres») encara hi caben
     els 10 px de retall sense partir cap línia. */
  .app-sidebar {
    width: 208px;
    transition: width 0.18s ease;
  }
  html.sidebar-collapsed .app-sidebar { width: 74px; }

  /* a) Les tres bandes. El padding viu a cada banda (i no a l'<aside>) perquè
        el cos pugui fer scroll de vora a vora.

     LES TRES HAN DE QUADRAR, i no quadraven. La del mig fa `overflow-y: auto`:
     la seva barra de scroll es menja 10 px d'amplada, o sigui que els enllaços
     del menú acaben 10 px abans del que sembla. El logo de dalt i la targeta
     d'usuari de baix no en sabien res i anaven amb els seus propis 14 px de
     marge: la targeta crema sobresortia 6 px per la dreta i començava 4 px més
     endins per l'esquerra que els enllaços. Es veia desquadrat (20 d'agost de
     2026).

     La solució, sense JavaScript ni cap número màgic: `overflow: hidden`
     TAMBÉ és un contenidor de scroll, o sigui que `scrollbar-gutter: stable`
     hi reserva el mateix buit que la banda del menú es menja de debò —el
     mateix, perquè el `scrollbar-width` també és el mateix. Les tres bandes
     comparteixen així caixa de contingut EXACTA a qualsevol sistema: a Windows
     el buit són 10 px a totes tres, i a macOS (barres flotants, que no ocupen
     lloc) són 0 px a totes tres. */
  .app-sidebar-top,
  .app-sidebar-foot {
    flex: 0 0 auto;
    overflow: hidden;
    scrollbar-gutter: stable;
    scrollbar-width: thin;
  }
  .app-sidebar-top {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 14px 10px 0;
  }
  .app-sidebar-foot { padding: 0 10px 14px; }
  .app-sidebar-logo { min-width: 0; }

  /* Isotip quadrat: només amb la barra plegada, on el wordmark de 140 px no hi
     cabria. Abans, allà, la marca desapareixia de la pantalla del tot. */
  .app-sidebar-mark { display: none; }
  html.sidebar-collapsed .app-sidebar-mark {
    display: block;
    flex: 0 0 auto;
    line-height: 0;
  }
  html.sidebar-collapsed .app-sidebar-mark img {
    width: 30px;
    height: 30px;
    border-radius: 9px;
  }

  .app-sidebar-toggle {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--c-muted);
    transition: background 0.15s, color 0.15s;
  }
  .app-sidebar-toggle:hover {
    background: var(--c-warm);
    color: var(--c-orange-dark);
  }
  /* Anell de focus PER DINS (`outline-offset` negatiu), com el dels capçals de
     carpeta: la banda que l'envolta reserva el buit de la barra de scroll amb
     `overflow: hidden` i un anell per fora quedaria retallat. */
  .app-sidebar-toggle:focus-visible {
    outline: 2px solid var(--c-orange);
    outline-offset: -2px;
  }

  .app-sidebar-scroll {
    flex: 1 1 auto;
    min-height: 0;          /* sense això un fill flex no encongeix i no hi ha scroll */
    overflow-y: auto;
    /* En arribar al final del menú, la roda del ratolí s'atura aquí: sense
       això el scroll «es passa» a la pàgina de sota i, en desplegar una
       carpeta, sembla que es mogui tot. Només s'ha de moure aquesta banda. */
    overscroll-behavior: contain;
    padding: 0 10px 8px;
    /* El buit de la barra es reserva SEMPRE, també quan el menú hi cap sencer:
       si no, plegar l'última carpeta feia desaparèixer la barra i tot el menú
       saltava 10 px cap a la dreta. I és el que permet que les altres dues
       bandes hi quadrin (vegeu el comentari de .app-sidebar-top). */
    scrollbar-gutter: stable;
    /* La barra clàssica de Windows fa 15 px: en una columna de 208 (i sobretot
       de 74) es menja l'amplada útil i descentra les icones. */
    scrollbar-width: thin;
    scrollbar-color: var(--c-line) transparent;
  }
  .app-sidebar-scroll::-webkit-scrollbar       { width: 6px; }
  .app-sidebar-scroll::-webkit-scrollbar-thumb { background: var(--c-line); border-radius: 999px; }
  .app-sidebar-scroll::-webkit-scrollbar-track { background: transparent; }

  /* El marge exterior el posa .app-sidebar-foot, que és qui sap on acaben els
     enllaços del menú; aquí només queda la caixa. */
  .app-sidebar-user {
    flex-wrap: wrap;
  }
  /* Roda dentada i logout: FILA PRÒPIA, sota l'avatar i el nom.
     Abans anaven a la mateixa fila (display:contents dissolia el wrapper) i,
     dels 156 px útils de la barra, se n'enduien la meitat entre les dues
     icones i els seus buits: al nom li'n quedaven cinquanta i «Artur
     Boladeres» hi sortia com «Artur B…». Amb la fila pròpia el nom té
     l'amplada sencera i els botons hi caben a 32 px, que és el que demana la
     WCAG 2.2 (n'hi havia 18×24).

     I ara la fila L'OMPLEN. Dues icones soltes arraconades a la dreta deixaven
     85 px de no-res a l'esquerra i la targeta es veia escapçada, a més de no
     semblar clicables. La configuració —que és el que s'obre sovint— s'estira i
     porta etiqueta; el sortir es queda quadrat, que la porta ja es llegeix
     sola. Fons blanc sobre el crema de la targeta, com al drawer de mòbil, que
     és el que fa que es vegin com a botons. */
  .app-sidebar-user-actions {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;
    margin-top: 8px;
  }

  /* b) Estat plegat */
  html.sidebar-collapsed .app-sidebar-top    { justify-content: center; padding-left: 12px; padding-right: 12px; }
  html.sidebar-collapsed .app-sidebar-foot   { padding-left: 12px; padding-right: 12px; }
  /* A la tira d'icones no hi ha amplada per a cap barra: s'amaga (l'scroll amb
     roda o teclat continua funcionant) i les icones queden ben centrades. Les
     altres dues bandes han de deixar de reservar-hi el buit alhora, o tornarien
     a quedar desquadrades —ara per l'altra banda. */
  html.sidebar-collapsed .app-sidebar-scroll {
    padding: 10px 12px 8px;
    scrollbar-width: none;
  }
  html.sidebar-collapsed .app-sidebar-top,
  html.sidebar-collapsed .app-sidebar-foot { scrollbar-width: none; }
  html.sidebar-collapsed .app-sidebar-scroll::-webkit-scrollbar { display: none; }

  html.sidebar-collapsed .app-sidebar-logo,
  html.sidebar-collapsed .app-sidebar .nav-label,
  /* L'etiqueta del capçal d'una carpeta, com la dels enllaços: a la tira
     d'icones la substitueix .nav-folder-icon. Sense això el text no marxava,
     només s'encongia —el flex el deixa a 30 px— i quedava un tros de
     «Administració» sortint per sota de la icona, amb la banda del menú
     desplaçant-se en horitzontal. */
  html.sidebar-collapsed .app-sidebar .nav-folder-label,
  html.sidebar-collapsed .app-sidebar .nav-section-title,
  html.sidebar-collapsed .app-sidebar .nav-folder-chevron { display: none; }

  /* Enllaços i capçals de carpeta: només la icona, centrada. */
  html.sidebar-collapsed .app-sidebar .nav-link,
  html.sidebar-collapsed .app-sidebar .nav-folder-btn {
    position: relative;
    justify-content: center;
    padding-left: 0;
    padding-right: 0;
  }
  /* La icona de l'enllaç ja no ha de reservar amplada per alinear etiquetes:
     aquí no n'hi ha cap. */
  html.sidebar-collapsed .app-sidebar .nav-link-icon { width: auto; }
  /* Els fills d'una carpeta oberta se centren igual, però amb una osca a
     l'esquerra que segueixi dient de qui pengen. */
  html.sidebar-collapsed .app-sidebar .nav-folder-inner {
    padding-left: 0;
    border-left: 0;
    margin-left: 0;
  }

  /* Els comptadors no hi cabrien: es redueixen a un punt sobre la icona. */
  html.sidebar-collapsed .app-sidebar .nav-badge,
  html.sidebar-collapsed .app-sidebar .nav-folder-badge {
    position: absolute;
    top: 4px;
    right: 12px;
    margin: 0;
    width: 8px;
    height: 8px;
    min-width: 0;
    padding: 0;
    font-size: 0;
    line-height: 0;
  }

  /* Bloc d'usuari plegat: avatar a dalt, accions a sota. */
  html.sidebar-collapsed .app-sidebar-user {
    flex-direction: column;
    gap: 8px;
    padding: 10px 6px;
  }
  html.sidebar-collapsed .app-sidebar-user-meta { display: none; }
  /* Plegada, els dos botons es posen UN SOBRE L'ALTRE. A la tira de 74 px, al
     bloc d'usuari només li queden 37 px de dins: dos quadrats de 32 en fila no
     hi han cabut mai —la roda dentada sortia 13 px per fora de la barra, per
     sobre del contingut de la pàgina— i és un defecte que ve de lluny.
     L'etiqueta «Configuració» marxa sola: és una `.nav-label`, com les del menú. */
  html.sidebar-collapsed .app-sidebar-user-actions {
    flex-direction: column;
    gap: 4px;
    margin-top: 0;
  }
  /* En columna, el `flex-basis` dels dos botons passa a ser l'ALÇADA: si no se'ls
     torna l'amplada, el de sortir s'encongeix als 17 px de la seva icona. */
  html.sidebar-collapsed .app-sidebar-user-actions > a,
  html.sidebar-collapsed .app-sidebar-user-actions > form > button {
    flex: 0 0 auto;
    width: 32px;
  }
  /* La roda dentada i el logout feien 18×24 px de zona clicable: per sota del
     mínim de 24×24 de la WCAG 2.2 i, a la pràctica, dos objectius que costava
     encertar. Ara fan 32 px d'alt i la de sortir també d'ample; la de
     configuració s'estira per omplir la fila. */
  .app-sidebar-user-actions > a,
  .app-sidebar-user-actions > form > button {
    height: 32px;
    border-radius: var(--r-btn-sm);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    background: #fff;
    font-size: 10.5px;
    font-weight: 700;
  }
  .app-sidebar-user-actions > a            { flex: 1 1 auto; }
  .app-sidebar-user-actions > form > button { flex: 0 0 32px; }
  .app-sidebar-user-actions > a:hover            { background: var(--c-orange-faint); }
  .app-sidebar-user-actions > form > button:hover { background: var(--c-red-light); }

  /* Etiqueta flotant de la tira d'icones (setupNavFlyouts() a funcions.js).
     Penja del <body> i va `fixed` perquè .app-sidebar-scroll fa overflow i
     retallaria qualsevol cosa que sortís dels 74 px de la tira. */
  .nav-flyout {
    position: fixed;
    z-index: 60;
    transform: translateY(-50%) translateX(-4px);
    background: var(--c-ink);
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    padding: 8px 11px;
    border-radius: var(--r-btn-sm);
    box-shadow: 0 8px 20px rgba(42, 37, 31, 0.18);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.12s ease, transform 0.12s ease;
  }
  .nav-flyout.is-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(-50%) translateX(0);
  }
  @media (prefers-reduced-motion: reduce) {
    .nav-flyout { transition: none; }
  }
}


/* ───────────────────────────────────────────────────────────────────────────
   Menú de navegació — enllaços, títols de secció i CARPETES desplegables.

   Un sol joc d'estils per als dos menús: la barra lateral de desktop
   (elements/sidebar.php) i el drawer de mòbil (elements/mobile-drawer.php).
   Les diferències de mida entre els dos són quatre línies al final, no dues
   còpies de tot.

   Les carpetes són l'estructura del menú: «Coordinació», «Administració» i
   «Seguretat», amb la subcarpeta «Extres» a dins d'aquesta última
   (funcions/menu.php → menu_folders(), pintades per elements/nav-folder.php).
   Comportament volgut:

     · El capçal és un botó de debò, amb cursor de mà i fons a l'hover — s'ha de
       veure que s'hi pot clicar sense haver-hi de passar per sobre.
     · Desplegar i plegar és una TRANSICIÓ d'alçada (grid-template-rows 0fr→1fr),
       no un salt. El xevró gira; no es canvia d'icona.
     · Res es mou de lloc en desplegar: setupNavFolders() (funcions.js) recol·loca
       l'scroll de la banda perquè el capçal clicat es quedi exactament on és.
     · Quina neix oberta i quina plegada ho decideix el SERVIDOR
       (menu_folder_oberta(), galeta `nav_folders`), o sigui que l'estat inicial
       ja ve pintat: cap carpeta s'obre ni es tanca sola en carregar la pàgina, i
       la transició només es veu quan la demana l'usuari.
   ─────────────────────────────────────────────────────────────────────────── */

/* Títol de secció («Menú»). */
.nav-list { display: flex; flex-direction: column; gap: 1px; }

/* Enllaç del menú (n'hi ha al menú principal i dins de les carpetes). */
.nav-link {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border-radius: var(--r-btn);
  font-size: 13px;
  /* Les tres etiquetes llargues («Missatgeria amb treballadors», «Control
     d'absències laboral», «Gestió de treballadors») no caben en una línia dins
     d'una carpeta a cap amplada raonable, i tallar-les amb punts suspensius
     deixaria dos «Control d'absències…» idèntics al menú. Es parteixen, doncs,
     però amb l'interlineat just. */
  line-height: 1.3;
  font-weight: 500;
  color: var(--c-text);
  transition: background 0.14s, color 0.14s;
}
.nav-link:hover { background: var(--c-warm); }
.nav-link.is-active {
  background: var(--c-orange-faint);
  color: var(--c-orange-text);
  font-weight: 700;
}
.nav-link-icon {
  width: 18px;
  text-align: center;
  font-size: 13px;
  flex-shrink: 0;
}
.nav-link .nav-label { min-width: 0; }
.nav-link.is-emotium,
.nav-link.is-emotium:hover,
.nav-link.is-emotium.is-active {
  background: #00b187;
  color: #fff;
  font-weight: 700;
}
.nav-link.is-emotium:hover { background: #009b76; }
.nav-link.is-emotium .emotium-icon {
  width: 20px;
  height: 20px;
  background: #fff;
  border-radius: 50%;
}
.nav-link.is-pesem,
.nav-link.is-pesem:hover,
.nav-link.is-pesem.is-active {
  background: #d9730d;
  color: #fff;
  font-weight: 700;
}
.nav-link.is-pesem:hover { background: #bf650b; }
.nav-link.is-pesem .pesem-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  background: #fff;
  color: #d9730d;
  border-radius: 50%;
  font-size: 10px;
}
/* La barra plegada posa `width: auto` a les icones; el cercle s'ha d'aguantar. */
html.sidebar-collapsed .app-sidebar .nav-link.is-pesem .pesem-icon { width: 20px; }

/* Comptador de no llegits (Mur, tiquets, absències pendents). */
.nav-badge {
  margin-left: auto;
  background: var(--c-red);
  color: #fff;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 7px;
  line-height: 16px;
}

/* El nom de qui ha entrat, al peu dels dos menús: SENCER, encara que hi calguin
   dues línies. «Artur Boladeres Fabregat» demana 147 px i a la targeta de la
   barra de desktop n'hi ha 107: tallat amb punts suspensius es llegia «Artur
   Boladeres …», que és no dir el nom de ningú. Dues línies com a màxim, perquè
   un nom molt llarg no faci créixer la targeta sense fre. */
.nav-user-nom {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  line-height: 1.25;
}

.nav-section-title {
  margin: 14px 0 4px;
  padding: 0 10px;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--c-faint);
}

/* ── Carpeta ──────────────────────────────────────────────────────────────── */
.nav-folder { margin-top: 6px; }
/* Una mica més d'aire entre el menú principal i la primera carpeta. */
.nav-list + .nav-folder { margin-top: 12px; }

/* El capçal es pinta com el títol «Menú» (majúscules petites i espaiades) i no
   com un enllaç més: la queixa era que no es veia que «Coordinació», «Laboral»,
   «Administració», «Seguretat» i «Extres» fossin CARPETES amb coses a dins, i
   amb el mateix pes i la mateixa mida que els seus fills semblaven germans seus.
   Continua sent un botó de debò (fons a l'hover, xevró que gira). */
.nav-folder-btn {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-btn);
  background: transparent;
  font-family: inherit;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--c-faint);
  /* El motiu d'existir d'aquesta línia: el Preflight de Tailwind v4 ja no posa
     `cursor: pointer` als <button>, i el capçal d'una carpeta amb la fletxa
     normal del ratolí no sembla clicable. */
  cursor: pointer;
  text-align: left;
  transition: background 0.14s, color 0.14s;
}
.nav-folder-btn:hover {
  background: var(--c-warm);
  color: var(--c-muted);
}
/* La carpeta on ets: el capçal s'encén perquè es vegi d'un cop d'ull de quina
   penja la pantalla oberta, tant si està desplegada com si l'has plegada. */
.nav-folder.has-active > .nav-folder-btn { color: var(--c-orange-text); }
.nav-folder-btn:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: -2px;
}
.nav-folder-label { flex: 1 1 auto; min-width: 0; }

/* Xevró: sempre el mateix `fa-chevron-down`, girat 90° quan la carpeta és
   plegada. Girar és més net que canviar d'icona — i es pot animar. */
.nav-folder-chevron {
  font-size: 9px;
  color: var(--c-faint);
  flex-shrink: 0;
  transition: transform 0.2s ease;
}
/* Amb `>`, i no descendent: si no, una carpeta plegada giraria també els xevrons
   de les seves subcarpetes, que tenen el seu propi estat. */
.nav-folder.is-closed > .nav-folder-btn .nav-folder-chevron { transform: rotate(-90deg); }

/* Icona substituta de l'etiqueta: només es veu amb la barra lateral plegada. */
.nav-folder-icon { display: none; }
@media (min-width: 1024px) {
  html.sidebar-collapsed .app-sidebar .nav-folder-icon {
    display: inline-block;
    font-size: 13px;
  }
}

/* Suma dels pendents de dins. Amb la carpeta oberta sobra (ja es veuen les
   pilotetes de cada ítem) i desapareix. */
.nav-folder-badge {
  margin-left: auto;
  min-width: 17px;
  background: var(--c-red);
  color: #fff;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  line-height: 15px;
  text-align: center;
}
/* Igual que el xevró: cada capçal mira el SEU estat. Amb un selector descendent,
   una carpeta oberta amagaria el comptador d'una subcarpeta plegada de dins. */
.nav-folder:not(.is-closed) > .nav-folder-btn .nav-folder-badge { display: none; }

/* El cos: graella d'una sola fila que passa de 0fr a 1fr. És l'única manera
   d'animar «fins a l'alçada que faci falta» sense mesurar-la amb JS. */
.nav-folder-body {
  display: grid;
  grid-template-rows: 1fr;
  transition: grid-template-rows 0.22s cubic-bezier(0.4, 0, 0.2, 1), visibility 0.22s;
}
/* La barra vertical de l'esquerra és el que diu «això penja d'aquí». Era de
   1,5 px i del to més clar de tots (--c-line-soft): pràcticament no es veia, i
   sense ella els fills d'una carpeta no es distingien del menú de primer nivell.
   Ara fa 2 px i va un to més fosc; a la carpeta activa, taronja. */
.nav-folder-inner {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-height: 0;        /* sense això la fila de 0fr no arriba a col·lapsar */
  overflow: hidden;
  padding-left: 10px;
  margin-left: 10px;
  border-left: 2px solid var(--c-line);
}
/* Amb `>` fins a l'inner: una carpeta que conté l'activa no ha d'encendre també
   el filet de les seves subcarpetes, que tenen la seva pròpia marca. */
.nav-folder.has-active > .nav-folder-body > .nav-folder-inner { border-left-color: var(--c-orange); }
/* La separació de dalt i de baix va als FILLS. Si fos padding del contenidor la
   fila de 0fr no arribaria a col·lapsar —el padding no s'encongeix— i cada
   carpeta plegada deixaria una osca de 8 px amb un tros de la línia vertical. */
.nav-folder-inner > :first-child { margin-top: 4px; }
.nav-folder-inner > :last-child  { margin-bottom: 4px; }
.nav-folder.is-closed > .nav-folder-body {
  grid-template-rows: 0fr;
  /* Amaga't també per al tabulador i el lector de pantalla, no només als ulls. */
  visibility: hidden;
}

/* ── Subcarpeta: una carpeta dins d'una altra («Extres» dins de «Seguretat») ──
   No cal HTML nou —és el mateix partial— i el sagnat ja el dona la línia
   vertical de .nav-folder-inner. L'únic que canvia és el capçal: una mica més
   petit i més apagat que el de fora, perquè es vegi de qui penja. */
.nav-folder-inner > .nav-folder { margin-top: 6px; }
.nav-folder-inner > .nav-folder > .nav-folder-btn {
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
}
.nav-folder-inner > .nav-folder > .nav-folder-btn:hover { color: var(--c-muted); }
/* La barra de la subcarpeta, un to més clara que la de fora: dos nivells de
   fondària s'han de poder distingir sense comptar sagnats. */
.nav-folder-inner > .nav-folder > .nav-folder-body > .nav-folder-inner {
  border-left-color: var(--c-line-soft);
}

@media (prefers-reduced-motion: reduce) {
  .nav-folder-body,
  .nav-folder-chevron { transition: none; }
}

/* ── Mides del drawer de mòbil: una mica més grans, que es toca amb el dit ── */
.mobile-drawer .nav-section-title:first-child { margin-top: 2px; }
.mobile-drawer .nav-link {
  padding: 11px 12px;
  font-size: 14px;
  border-radius: 12px;
}
.mobile-drawer .nav-link-icon { width: 20px; font-size: 14px; }

/* ── Els botons del bloc d'usuari del calaix ─────────────────────────────────
   Els tres quadrats de sota del nom: «Les meves dades», «Configuració» i tancar
   sessió.

   ⚠️ Van amb CSS i no amb utilitats de Tailwind, i el motiu és el de sempre
   (../../CLAUDE.md §CSS): el build està PURGAT. El marcatge portava
   `hover:text-brand-orange-dark` i `hover:bg-brand-orange-light`, i cap de les
   dues hi és —o sigui que aquells botons no tenien CAP efecte en tocar-los, i
   ningú no ho havia notat perquè una classe que falta no dona cap error. Es
   deixen al marcatge (no fan mal i el dia que es recompili el build tornaran a
   valer), però qui pinta de debò és això. */
.mobile-drawer-foot a:hover,
.mobile-drawer-foot a:focus-visible      { background: var(--c-orange-faint); color: var(--c-orange-dark); }
.mobile-drawer-foot button:hover,
.mobile-drawer-foot button:focus-visible { background: var(--c-red-light);    color: var(--c-red-text); }
/* El capçal de carpeta va en majúscules petites com a desktop; aquí una mica
   més gran, que es toca amb el dit i la columna és més ampla. */
.mobile-drawer .nav-folder-btn { padding: 9px 12px; font-size: 11px; border-radius: 12px; }
.mobile-drawer .nav-folder-inner > .nav-folder > .nav-folder-btn { font-size: 10px; }
/* El drawer ja té el seu propi padding a dalt: el títol no n'hi ha d'afegir. */

/* La banda de scroll del drawer, amb la mateixa contenció que la de desktop —i
   el mateix arranjament de quadratura. En un mòbil no es nota: les barres de
   scroll hi són flotants i no ocupen lloc. Però per sota de `lg` també hi ha
   finestres d'escriptori amb ratolí, i allà surt la barra clàssica de 15 px:
   es menja amplada del menú i el peu, que no en sabia res, quedava més ample
   que els enllaços. El perquè del truc, a la secció «Sidebar de desktop». */
.mobile-drawer-scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
  scrollbar-color: var(--c-line) transparent;
}
.mobile-drawer-foot {
  overflow: hidden;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}


/* ───────────────────────────────────────────────────────────────────────────
   Pop-up de notificacions (elements/notif-popup.php)

   Penja de la campaneta i es queda DAMUNT de la pàgina: clicar-la ja no fa
   marxar a /notificacions.php i perdre el que s'estava fent. El JS
   (setupNotifPopup) el situa sota la campaneta que s'ha premut — n'hi ha una a
   la capçalera de mòbil i una altra a la de desktop —, així que aquí no s'hi
   fixa ni `top` ni `right`: només la mida, el color i l'animació.

   z-index 52: per damunt de la capçalera enganxada (30), de la barra inferior
   (40) i del drawer (51); per sota dels dos avisos que sí que han d'aturar-ho
   tot, el de perfil incomplet (55) i el de jornades (60).
   ─────────────────────────────────────────────────────────────────────────── */
.notif-popup {
  position: fixed;
  inset: 0;
  z-index: 52;
  visibility: hidden;
  pointer-events: none;
}
.notif-popup[data-state="open"] {
  visibility: visible;
  pointer-events: auto;
}

.notif-popup-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 14, 8, 0.25);
  opacity: 0;
  transition: opacity 0.18s ease;
}
.notif-popup[data-state="open"] .notif-popup-backdrop { opacity: 1; }

.notif-popup-panel {
  position: absolute;          /* top/left/right: els posa el JS */
  width: min(390px, calc(100vw - 20px));
  max-height: min(72vh, 580px);
  display: flex;
  flex-direction: column;
  background: var(--c-cream);
  border: 1px solid var(--c-line);
  border-radius: 18px;
  box-shadow: 0 22px 54px -16px rgba(20, 14, 8, 0.5);
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 0.16s ease, transform 0.16s ease;
}
.notif-popup[data-state="open"] .notif-popup-panel {
  opacity: 1;
  transform: none;
}

/* Variant CENTRADA — el pop-up que s'obre tot sol a l'inici quan hi ha
   notificacions per llegir. Penjant de la campaneta, un panell que apareix
   sense que ningú l'hagi demanat sembla una errada; al mig de la pantalla es
   llegeix com el que és, un avís. El JS (setupNotifPopup) hi posa
   data-anchor="center" i buida el top/left/right inline de l'ancoratge. */
.notif-popup-panel[data-anchor="center"] {
  top: 50%;
  left: 50%;
  right: auto;
  width: min(440px, calc(100vw - 24px));
  max-height: min(78vh, 640px);
  transform: translate(-50%, calc(-50% - 8px));
}
.notif-popup[data-state="open"] .notif-popup-panel[data-anchor="center"] {
  transform: translate(-50%, -50%);
}
/* Fons una mica més tancat: aquí sí que volem que s'hi miri. El fons és germà
   ANTERIOR del panell, així que la marca per distingir el mode la porta l'arrel
   (data-mode), no el panell. */
.notif-popup[data-mode="auto"] .notif-popup-backdrop {
  background: rgba(20, 14, 8, 0.42);
}

.notif-popup-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 12px 10px 12px 16px;
  border-bottom: 1px solid var(--c-line);
}
.notif-popup-title {
  flex: 1 1 auto;
  font-size: 13.5px;
  font-weight: 800;
  color: var(--c-ink);
}
.notif-popup-title i { color: var(--c-orange); margin-right: 4px; }

.notif-popup-full,
.notif-popup-close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-btn-sm);
  background: transparent;
  color: var(--c-muted);
  font-size: 12px;
  cursor: pointer;
  transition: background 0.14s, color 0.14s;
}
.notif-popup-full:hover,
.notif-popup-close:hover { background: var(--c-warm); color: var(--c-ink); }

.notif-popup-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;   /* que no arrossegui la pàgina de sota */
  padding: 12px;
}

.notif-popup-loading,
.notif-popup-error {
  padding: 26px 12px;
  text-align: center;
  font-size: 12.5px;
  color: var(--c-muted);
}
.notif-popup-error a { color: var(--c-orange-dark); font-weight: 700; text-decoration: underline; }

@media (prefers-reduced-motion: reduce) {
  .notif-popup-backdrop,
  .notif-popup-panel { transition: none; }
}


/* ───────────────────────────────────────────────────────────────────────────
   Seguretat anti-overflow horitzontal

   Les graelles (.grid) sense `grid-template-columns` explícit —el cas típic
   d'una graella responsiva que es plega a 1 columna en mòbil perquè només
   porta `lg:grid-cols-*`— generen una columna IMPLÍCITA. Per defecte
   `grid-auto-columns: auto`, i una pista `auto` creix fins al `max-content`
   del contingut: si el contingut és més ample que la pantalla, la columna
   (i tota la pàgina) sobreeixen horitzontalment.

   minmax(0, 1fr) lliga la columna implícita a l'amplada del contenidor i mai
   la deixa créixer més enllà. El selector :where() té especificitat 0, així
   que qualsevol utility `auto-cols-*` de Tailwind hi continua tenint prioritat.
   ─────────────────────────────────────────────────────────────────────────── */
:where(.grid) {
  grid-auto-columns: minmax(0, 1fr);
}

/* ⚠️ I EL <fieldset>, QUE ÉS EL CAS QUE NO ES VEU VENIR (29 d'agost de 2026).
   El full d'estils del NAVEGADOR li dona `min-inline-size: min-content`, i el
   preflight de Tailwind no el toca: un fieldset, doncs, NO ES POT ENCONGIR per
   sota de l'amplada mínima del seu contingut. Si a dins hi ha qualsevol cosa
   que no es pot partir —una fila de casella + etiqueta + comptador, un botó
   llarg—, el fieldset es fa més ample que la pantalla i s'endú tota la pàgina:
   els paràgrafs de dins passen a embolcallar-se a AQUELLA amplada i el text
   surt tallat per la dreta.

   És el que passava a Comunicacions en un mòbil de 375 px: el <fieldset> dels
   destinataris feia 357 px dins d'una targeta de 295 i la pàgina en demanava
   397. Amb aquesta línia, 375 clavats.

   Va a l'element i no a una classe perquè el problema és del <fieldset> com a
   etiqueta, vingui d'on vingui: aquí n'hi ha a tres pantalles i el dia que se'n
   posi un de nou ningú no se'n recordarà. */
fieldset { min-width: 0; }


/* ───────────────────────────────────────────────────────────────────────────
   3. Fallbacks per a classes brand-*
       Redundants si tailwind.css està compilat amb input.css, però són un
       safety-net útil si algú edita input.css i oblida regenerar el CSS.
   ─────────────────────────────────────────────────────────────────────────── */
.bg-brand-orange-light  { background-color: var(--c-orange-light)  !important; }
.bg-brand-orange-faint  { background-color: var(--c-orange-faint)  !important; }
.bg-brand-green-light   { background-color: var(--c-green-light)   !important; }
.bg-brand-red           { background-color: var(--c-red)           !important; }
.bg-brand-red-light     { background-color: var(--c-red-light)     !important; }
.bg-brand-amber         { background-color: var(--c-amber)         !important; }
.bg-brand-amber-light   { background-color: var(--c-amber-light)   !important; }
.bg-brand-line          { background-color: var(--c-line)          !important; }
.bg-brand-line-soft     { background-color: var(--c-line-soft)     !important; }
.bg-brand-warm          { background-color: var(--c-warm)          !important; }
.text-brand-orange-dark { color: var(--c-orange-dark) !important; }
.text-brand-green-dark  { color: var(--c-green-dark)  !important; }
.text-brand-red         { color: var(--c-red)         !important; }
.text-brand-amber       { color: var(--c-amber)       !important; }
.text-brand-faint       { color: var(--c-faint)       !important; }
.text-brand-text        { color: var(--c-text)        !important; }
.border-brand-line      { border-color: var(--c-line) !important; }
.border-brand-line-soft { border-color: var(--c-line-soft) !important; }


/* ───────────────────────────────────────────────────────────────────────────
   4. Graella d'horari de lectura (.hgrid)
       Taula setmanal només-lectura per mostrar jornades i horaris d'ofertes.
       Files = hores · columnes = dies. Mateixa tècnica responsiva que #grid
       (width:100% + table-layout:fixed → s'ajusta al mòbil sense scroll).
   ─────────────────────────────────────────────────────────────────────────── */
.hgrid {
  width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 3px;
}
.hgrid th {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--c-muted);
  text-align: center;
  padding-bottom: 6px;
}
.hgrid td { padding: 0; vertical-align: middle; }
.hgrid th:first-child,
.hgrid td:first-child { width: 48px; }
.hgrid-hour {
  font-size: 10.5px;
  font-weight: 700;
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  color: var(--c-faint);
  text-align: right;
  padding-right: 8px;
  white-space: nowrap;
}
/* Etiqueta de mitja hora (:30): més apagada perquè destaquin les hores en punt. */
.hgrid-hour-half { opacity: 0.45; }
.hgrid-cell {
  position: relative;
  height: 28px;
  border-radius: 5px;
  border: 1px solid var(--c-line);
  background: #fff;
  overflow: hidden;
}
/* Cel·la partida en dues mitges (slot de 30 min de dalt i de baix). */
.hgrid-cell-split { display: flex; flex-direction: column; }
.hgrid-cell-split > span { flex: 1; display: block; }
/* «No disponible»: trama diagonal a sobre del vermell. Aquesta graella diu
   tota la seva informació amb verd i vermell, que és exactament el parell que
   un ull deuteranop (~6 % dels homes) no separa; amb la textura, la franja
   bloquejada es reconeix encara que els dos colors es vegin iguals. El fons
   de color el posa un `style` inline des d'elements/horari-jornades.php, i
   per això aquí només s'hi afegeix la imatge. */
.hgrid-cell-split > span.es-off,
.hgrid-legend-dot.es-off {
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.45) 0,
    rgba(255, 255, 255, 0.45) 2px,
    transparent 2px,
    transparent 5px
  );
}
/* Píndola petita amb el color de la jornada: marca l'hora sense omplir la
   cel·la, així es continua veient la disponibilitat pintada de sota. */
.hgrid-pin {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 52%;
  min-width: 12px;
  max-width: 26px;
  height: 8px;
  border-radius: 9999px;
  box-shadow: 0 0 0 1.5px #fff, 0 1px 2px rgba(20, 14, 8, 0.25);
}

/* Variant compacta (fitxes de perfil, llistes). */
.hgrid.is-compact { border-spacing: 2px; }
.hgrid.is-compact th { font-size: 9px; padding-bottom: 4px; }
.hgrid.is-compact th:first-child,
.hgrid.is-compact td:first-child { width: 42px; }
.hgrid.is-compact .hgrid-hour { font-size: 9.5px; padding-right: 6px; }
.hgrid.is-compact .hgrid-cell { height: 22px; }

/* Llegenda de jornades sota la graella. */
.hgrid-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-top: 10px;
}
.hgrid-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 11.5px;
  color: var(--c-text);
}
.hgrid-legend-dot {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  flex-shrink: 0;
}
.hgrid-legend-meta { color: var(--c-muted); }

/* Capçalera amb el número del dia i el dia d'AVUI remarcat. Només surt quan la
   graella es pinta sobre una setmana real (i, per tant, sap de dates). */
.hgrid-dia-num {
  display: block;
  font-size: 11px;
  font-weight: 800;
  color: var(--c-text);
  line-height: 1.15;
}
.hgrid th.hgrid-avui {
  color: var(--c-orange-dark);
  border-bottom: 2px solid var(--c-orange);
}
.hgrid th.hgrid-avui .hgrid-dia-num { color: var(--c-orange-dark); }

/* ─────────────────────────────────────────────────────────────────────────────
   4bis. Pestanyes de SETMANA (horaris de dues setmanes)
       Les fa servir qui té dues setmanes a mostrar o a editar: el bloc de camps
       d'una feina (Setmana 1 / Setmana 2), la graella de lectura .hgrid i «El
       meu horari» (aquesta setmana / la vinent). Sempre visibles i grosses a
       propòsit: qui té horari alternat ha de veure d'un cop d'ull que allò que
       està mirant és NOMÉS una de les dues setmanes.
   ─────────────────────────────────────────────────────────────────────────── */
.setmana-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}
.setmana-tab {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--c-line);
  border-radius: 12px;
  background: #fff;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--c-muted);
  cursor: pointer;
  /* També s'usa amb <a> (navegació de setmanes a «El meu horari»). */
  text-decoration: none;
  transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.setmana-tab:hover { background: var(--c-warm); color: var(--c-text); }
.setmana-tab.is-active {
  background: var(--c-orange-faint);
  border-color: var(--c-orange);
  color: var(--c-orange-dark, var(--c-orange));
}
.setmana-tab:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 1px;
}
/* Segona línia de la pestanya: el rang de dates o «matí / tarda». */
.setmana-tab-sub {
  display: block;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--c-faint);
  letter-spacing: 0;
}
.setmana-tab.is-active .setmana-tab-sub { color: inherit; opacity: 0.75; }

/* Avís gros de «la teva feina té horari de dues setmanes». No és una nota al
   peu: és la primera cosa que ha de veure qui el té, perquè no doni per fet que
   la setmana que veu és l'única que hi ha. */
.avis-dues-setmanes {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 16px;
  border: 1px solid var(--c-orange);
  background: var(--c-orange-faint);
}
.avis-dues-setmanes .avis-icona {
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 11px;
  background: #fff;
  color: var(--c-orange);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 15px;
}

/* Visor de DOCX (mammoth.js converteix el .docx a HTML pelat — aquí li
   donem un mínim de tipografia perquè es llegeixi bé dins la fitxa). */
.docx-preview {
  font-size: 13px;
  line-height: 1.55;
  color: var(--c-text);
}
.docx-preview h1, .docx-preview h2, .docx-preview h3,
.docx-preview h4, .docx-preview h5, .docx-preview h6 {
  font-weight: 700;
  margin: 1em 0 0.4em;
  line-height: 1.3;
}
.docx-preview h1 { font-size: 1.6em; }
.docx-preview h2 { font-size: 1.35em; }
.docx-preview h3 { font-size: 1.15em; }
.docx-preview h4, .docx-preview h5, .docx-preview h6 { font-size: 1em; }
.docx-preview p { margin: 0.5em 0; }
.docx-preview ul, .docx-preview ol { margin: 0.5em 0; padding-left: 1.4em; }
.docx-preview li { margin: 0.2em 0; }
.docx-preview a { color: var(--c-orange-dark); text-decoration: underline; }
.docx-preview table {
  border-collapse: collapse;
  margin: 0.8em 0;
  width: 100%;
}
.docx-preview th, .docx-preview td {
  border: 1px solid var(--c-line);
  padding: 6px 8px;
  text-align: left;
}
.docx-preview img { max-width: 100%; height: auto; }
.docx-preview strong { font-weight: 700; }
.docx-preview em { font-style: italic; }


/* ───────────────────────────────────────────────────────────────────────────
   Llistes col·lapsables de jornades acabades

   <details class="jornades-acabades"> amaga les jornades en estat 'ended' per
   defecte a la fitxa del treballador i a "Les meves jornades". El triangle
   natiu del browser es treu (sense ::-webkit-details-marker / list-style:none)
   i es fa servir un chevron de Font Awesome dins del <summary> que rota 90°
   en obrir-se.
   ─────────────────────────────────────────────────────────────────────────── */
.jornades-acabades > summary {
  list-style: none;
}
.jornades-acabades > summary::-webkit-details-marker {
  display: none;
}
.jornades-acabades[open] > summary > .fa-chevron-right {
  transform: rotate(90deg);
}

/* ───────────────────────────────────────────────────────────────────────────
   Comarques desplegables (admin · Geografia, public/admin/geografia.php)

   <details class="geo-comarca"> revela els municipis de la comarca en obrir-se.
   Mateix patró que .jornades-acabades: s'amaga el marcador natiu del <summary>
   i el chevron de Font Awesome rota 90° en obrir. El llistat de municipis es
   disposa en columnes amb CSS multi-column (que el Tailwind purgat no inclou).
   Els colors venen de les variables --color-brand-* que defineix tailwind.css.
   ─────────────────────────────────────────────────────────────────────────── */
.geo-comarca > summary {
  list-style: none;
}
.geo-comarca > summary::-webkit-details-marker {
  display: none;
}
.geo-comarca > summary:hover {
  background: var(--color-brand-line-soft);
}
.geo-comarca[open] > summary .fa-chevron-right {
  transform: rotate(90deg);
}
.geo-comarca-body {
  padding: 0.5rem 0.75rem 0.75rem;
  border-top: 1px solid var(--color-brand-line-soft);
}
.geo-munis {
  columns: 2;
  column-gap: 1.25rem;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--color-brand-text);
}
@media (min-width: 640px)  { .geo-munis { columns: 3; } }
@media (min-width: 1024px) { .geo-munis { columns: 4; } }
.geo-munis > li {
  break-inside: avoid;
  padding: 2px 0;
}

/* ───────────────────────────────────────────────────────────────────────────
   Utilitats que el build PURGAT de Tailwind NO inclou però que els overlays de
   modal necessiten. Els modals de Rols i Categoria (public/admin/usuaris.php)
   fan `hidden fixed inset-0 z-[60] items-center justify-center` i, en obrir-se,
   commuten `hidden`→`flex`. Com que `inset-0` i `z-[60]` no són al tailwind.css
   purgat, el modal s'obria a la seva posició estàtica (molt avall) i sense
   z-index → quedava fora de pantalla i semblava que el botó "no funcionava".
   Mateix problema que ja es va resoldre amb un overlay propi a documentacio.css.
   ─────────────────────────────────────────────────────────────────────────── */
.inset-0 { top: 0; right: 0; bottom: 0; left: 0; }
.z-\[60\] { z-index: 60; }

/* Fons (backdrop) dels overlays de modal. `bg-black/40` tampoc és al build purgat,
   així que el fons quedava gairebé transparent i el popup es confonia amb el
   contingut de sota. Aquest backdrop propi enfosqueix i desenfoca (com el
   .doc-modal-backdrop de documentacio.css) perquè el modal destaqui. */
.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 14, 8, 0.55);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}


/* ───────────────────────────────────────────────────────────────────────────
   Tiquets d'ajuda (public/tiquets-ajuda/ i public/coordinacio/tiquets.php)

   Dos components: la FILA d'un tiquet als llistats i el FIL de la conversa.
   Van aquí i no amb classes utility perquè el fil és un patró de xat (bombolla
   + avatar + alineació segons qui parla) que en Tailwind demanaria una vintena
   de classes repetides a cada branca del if — i, sobretot, perquè el build de
   Tailwind d'aquest projecte és PURGAT: qualsevol classe nova no hi seria.
   ─────────────────────────────────────────────────────────────────────────── */

/* Fila d'un tiquet als llistats. `.is-nou` marca els que tenen missatges sense
   llegir amb una barra taronja a l'esquerra: es veu d'una passada quins
   demanen atenció sense haver de llegir els comptadors. */
.tiquet-fila {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--c-line);
  color: var(--c-text);
  transition: background .15s ease, box-shadow .15s ease;
}
.tiquet-fila:hover {
  background: var(--c-cream);
  box-shadow: inset 0 0 0 1px var(--c-orange-light);
}
/* LA SAFATA ÉS UNA DATATABLES (5 d'octubre de 2026, /coordinacio/tiquets.php):
   una taula d'una columna on cada cel·la és una `.tiquet-fila`. Es despulla la
   taula —ni capçalera, ni vores, ni el fons del hover de datatables.css— perquè
   es vegi la llista de targetes de sempre, amb el mateix espai entre files. */
table.dataTable.tiquets-dt thead { display: none; }
table.dataTable.tiquets-dt tbody td {
  padding: 4px 0;
  border: 0;
  font-size: inherit;
}
table.dataTable.tiquets-dt tbody tr:hover td { background: transparent; }

.tiquet-fila.is-nou {
  border-left: 3px solid var(--c-orange);
  padding-left: 11px;
}

/* ÉS MEU: el tinc jo, com a referent o com a persona encomanada (8 de setembre
   de 2026). Qui veu la safata SENCERA —administració— hi té els fils de tothom,
   i el que necessita d'un cop d'ull és quins ha de contestar ELL.

   Va amb el fons i un anell, i no amb una barra a l'esquerra, perquè aquella ja
   és de `.is-nou` i les dues coses són INDEPENDENTS: un fil pot ser meu i no
   tenir res nou, i pot tenir novetats i no ser meu. Amb les dues alhora es
   veuen totes dues. */
.tiquet-fila.is-meu {
  background: var(--c-orange-faint);
  box-shadow: inset 0 0 0 1.5px var(--c-orange);
}
.tiquet-fila.is-meu:hover {
  background: var(--c-orange-light);
  box-shadow: inset 0 0 0 1.5px var(--c-orange-dark);
}

/* Qui ha de respondre el fil, a la fila mateixa: no cal obrir-lo per saber-ho.
   Les xapes van a la segona línia, amb el nom de qui demana i la data, perquè
   la primera és de l'assumpte i és la que s'ha de poder llegir sencera. */
.tiquet-respon {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
.tiquet-respon-jo { color: var(--c-orange-text); font-weight: 800; }


/* ── DE QUI ÉS AQUESTA FEINA PENDENT ──────────────────────────────────────
   La línia que pinta elements/qui-ho-resol.php a les pantalles de Coordinació:
   absències, quilòmetres i extres, hores de calendari, peticions de fitxatge.

   Va aquí i no a cada full de pantalla perquè el fan servir QUATRE llistats i
   ha de dir-se igual a tots: és la regla de /public/css/README.md —a la tercera
   pantalla, el component surt a un full compartit—. `.is-meu` no és decoració:
   en un control amb quaranta files pendents, la pregunta de qui l'obre és quines
   són seves, i el color és el que ho respon d'una passada. */
.qui-resol {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 5px;
  margin-top: 6px;
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--c-muted);
}
.qui-resol i { font-size: 10px; color: var(--c-muted); }
.qui-resol > span { font-weight: 700; }
.qui-resol-ningu { font-style: italic; }

/* La meva: es llegeix de lluny i no cal buscar el nom entre els altres. */
.qui-resol.is-meu {
  color: var(--c-orange-text);
  font-weight: 600;
}
.qui-resol.is-meu i { color: var(--c-orange); }
.qui-resol-jo {
  color: var(--c-orange-text);
  font-weight: 800;
}

/* A la safata de coordinació la fila porta una acció pròpia («Tanca») al costat
   de l'enllaç, i un <form> no pot anar DINS d'un <a>: allà la fila és un <div>
   i qui enllaça al fil és aquest cos, que s'ho queda tot menys el botó. La
   resta de llistats (/tiquets-ajuda/index.php) continuen sent un <a> pelat. */
.tiquet-fila-cos {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
  min-width: 0;
  color: inherit;
  text-decoration: none;
  /* Es menja el padding de la fila per les seves tres bandes: així clicar a la
     vora de la fila continua obrint el fil, com quan la fila sencera era un
     <a>. La banda dreta no, que és on hi ha el botó. */
  margin: -12px 0 -12px -14px;
  padding: 12px 0 12px 14px;
}
.tiquet-fila.is-nou .tiquet-fila-cos {   /* la barra taronja menja 3px de padding */
  margin-left: -11px;
  padding-left: 11px;
}

/* Tancar un tiquet resolt sense entrar al fil. Separat per una línia perquè es
   llegeixi com el que és —una acció, no part de l'enllaç— i en VERD, no en
   vermell: tancar és donar la consulta per resolta, no esborrar res; el fil es
   queda sencer a la pestanya «Tancats». */
.tiquet-fila-accio {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  padding-left: 10px;
  border-left: 1px solid var(--c-line-soft);
}
/* «Me'l quedo» sense entrar al fil (27 de setembre de 2026): en blau, el color
   de l'estat «En curs» al qual porta. */
.tiquet-agafa-rapid {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-btn-sm);
  background: #e8f0fe;
  color: #1f56c9;
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: filter 0.15s ease, box-shadow 0.15s ease;
}
.tiquet-agafa-rapid:hover  { filter: brightness(0.97); box-shadow: inset 0 0 0 1px #1f56c9; }
.tiquet-agafa-rapid:active { transform: translateY(1px); }
.tiquet-tanca-rapid {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-btn-sm);
  background: var(--c-green-light);
  color: var(--c-green-text);
  font-family: inherit;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: filter 0.15s ease, box-shadow 0.15s ease;
}
.tiquet-tanca-rapid:hover  { filter: brightness(0.96); box-shadow: inset 0 0 0 1px var(--c-green-dark); }
.tiquet-tanca-rapid:active { transform: translateY(1px); }

/* A mòbil la fila ja va justa d'amplada: cau l'etiqueta i queda la icona, amb
   la zona tàctil igual de gran. */
@media (max-width: 640px) {
  .tiquet-fila-accio { padding-left: 8px; }
  .tiquet-tanca-rapid,
  .tiquet-agafa-rapid { padding: 11px 12px; font-size: 13px; }
  .tiquet-tanca-rapid span,
  .tiquet-agafa-rapid span { display: none; }
}

/* El fil de la conversa. */
.tiquet-fil {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Un missatge: avatar + bombolla. Els propis van a la dreta i amb l'avatar a
   l'altra banda (row-reverse), com a qualsevol missatgeria. */
.tiquet-msg {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  max-width: 100%;
}
.tiquet-msg.is-meu { flex-direction: row-reverse; }

.tiquet-msg-avatar {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  object-fit: cover;
  flex-shrink: 0;
  box-shadow: inset 0 0 0 1px var(--c-line);
}
.tiquet-msg-inicials {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-warm);
  color: var(--c-muted);
  font-size: 11px;
  font-weight: 700;
}

.tiquet-msg-cos { min-width: 0; max-width: 78%; }

.tiquet-msg-meta {
  display: flex;
  align-items: baseline;
  gap: 7px;
  font-size: 11px;
  color: var(--c-muted);
  margin-bottom: 3px;
}
.tiquet-msg-meta strong { color: var(--c-ink); font-weight: 700; }
.tiquet-msg.is-meu .tiquet-msg-meta { flex-direction: row-reverse; }

/* La bombolla. `overflow-wrap` perquè una URL llarga enganxada no eixampli la
   columna; `white-space: normal` perquè el salt de línia ja arriba com a <br>
   (el cos es pinta amb nl2br(h(...)), mai com a HTML de l'usuari). */
.tiquet-msg-bombolla {
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--c-line);
  border-radius: 14px 14px 14px 4px;
  padding: 10px 13px;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--c-text);
  overflow-wrap: anywhere;
}
.tiquet-msg.is-meu .tiquet-msg-bombolla {
  background: var(--c-orange-faint);
  box-shadow: inset 0 0 0 1px var(--c-orange-light);
  border-radius: 14px 14px 4px 14px;
}

/* Esdeveniment de sistema (s'ha derivat, s'ha tancat): centrat, discret i
   sense bombolla — no és ningú parlant, és el rastre del que ha passat. */
.tiquet-sistema {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 7px;
  padding: 7px 12px;
  margin: 2px auto;
  border-radius: 999px;
  background: var(--c-warm);
  color: var(--c-muted);
  font-size: 11.5px;
  text-align: center;
}
.tiquet-sistema i { font-size: 10px; color: var(--c-amber); }
.tiquet-sistema-data { color: var(--c-faint); font-size: 10.5px; }

/* ─── Estats, qui el porta i notes internes (27 de setembre de 2026) ────────
   Tot el que va néixer amb funcions/tiquets_estats.php i tiquets_cues.php. El
   blau de «En curs» no té variable de marca: és el mateix de les àrees
   d'Estructura, amb el text una mica més fosc perquè passi el contrast AA. */

/* La xapa de l'ESTAT (tiquet_estat_classe()). Quatre colors i prou: taronja el
   que no porta ningú (demana atenció), blau el que algú porta, groc el que
   espera la persona i verd el resolt. */
.tiq-estat {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
}
.tiq-estat--nou      { background: var(--c-orange-faint); color: var(--c-orange-text); box-shadow: inset 0 0 0 1px var(--c-orange-light); }
.tiq-estat--en_curs  { background: #e8f0fe; color: #1f56c9; }
.tiq-estat--esperant { background: var(--c-amber-light); color: var(--c-amber-text); }
.tiq-estat--resolt   { background: var(--c-green-light); color: var(--c-green-text); }

/* QUI EL PORTA, a dalt del fil: el que evita que dues persones contestin el
   mateix. Tres colors segons de qui és: meu (blau), d'una altra (groc: compte,
   que no us trepitgeu) o de ningú (taronja, com l'estat «Nou»). */
.tiquet-porta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--c-line);
  font-size: 13px;
  color: var(--c-text);
}
.tiquet-porta strong { color: var(--c-ink); }
.tiquet-porta-sub { display: block; margin-top: 2px; font-size: 11.5px; color: var(--c-muted); }
.tiquet-porta-ico {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--c-warm);
  color: var(--c-muted);
}
.tiquet-porta.is-meu   { background: #e8f0fe; box-shadow: inset 0 0 0 1px #c6d7fb; }
.tiquet-porta.is-meu .tiquet-porta-ico   { background: #fff; color: #1f56c9; }
.tiquet-porta.is-altra { background: var(--c-amber-light); box-shadow: inset 0 0 0 1px #f3d9a4; }
.tiquet-porta.is-altra .tiquet-porta-ico { background: #fff; color: var(--c-amber-text); }
.tiquet-porta.is-ningu .tiquet-porta-ico { background: var(--c-orange-faint); color: var(--c-orange); }

/* L'avís dins del quadre de respondre quan el porta una altra persona. */
.tiquet-avis-porta {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 8px;
  padding: 7px 10px;
  border-radius: 10px;
  background: var(--c-amber-light);
  color: var(--c-amber-text);
  font-size: 12px;
}

/* El selector «Després d'enviar», al costat del botó. */
.tiquet-despres {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: 600;
  color: var(--c-muted);
}
.tiquet-despres .input-base { width: auto; padding-top: 8px; padding-bottom: 8px; font-size: 13px; }

/* L'avatar de l'EQUIP D'AJUDA: des de fora, ni la foto ni les inicials de
   ningú. */
.tiquet-msg-equip {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--c-orange-faint);
  color: var(--c-orange);
  font-size: 14px;
}

/* ACÚS DE REBUT AUTOMÀTIC (tiquet_acusos_rebut()): una resposta de l'equip,
   però més discreta, perquè no sembli que algú ja hi ha respost de debò. */
.tiquet-msg-auto .tiquet-msg-bombolla {
  background: transparent;
  box-shadow: none;
  border: 1px dashed var(--c-line);
  font-style: italic;
  color: var(--c-muted);
}

/* NOTA INTERNA: groga, amb vora discontínua i un cadenat, perquè no es
   confongui mai amb una resposta. Només la veuen l'equip de la cua i
   administració. */
.tiquet-nota {
  margin: 2px 6%;
  padding: 9px 13px;
  border-radius: 12px;
  background: #fffbe6;
  border: 1px dashed #e6c980;
  font-size: 13px;
  line-height: 1.55;
  color: var(--c-text);
  overflow-wrap: anywhere;
}
.tiquet-nota-meta {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 3px;
  font-size: 11px;
  color: #8a5a00;
}
.tiquet-nota-meta strong { color: #6b4600; }
.tiquet-nota-form {
  padding: 16px 18px;
  border-radius: 16px;
  background: #fffbe6;
  border: 1px dashed #e6c980;
}

/* Reobrir des de fora: un quadre que s'obre, amb el missatge obligatori. */
.tiquet-reobre { margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--c-line-soft); }
.tiquet-reobre > summary { list-style: none; cursor: pointer; }
.tiquet-reobre > summary::-webkit-details-marker { display: none; }
.tiquet-reobre[open] > summary { opacity: .7; }
.tiquet-reobre:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

/* Els títols dels dos blocs de la safata: «Els que porto jo» i «La resta». */
.tiquet-bloc-tit {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--c-muted);
}
.tiquet-bloc-tit i { font-size: 11px; color: var(--c-orange); }

/* ACTIVITAT DE L'EQUIP (/coordinacio/tiquets-activitat.php): les xifres de
   l'equip, amb el color de l'estat que compten, i la taula persona per persona. */
.tiq-act-xifres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}
.tiq-act-xifra {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 12px 14px;
  border-radius: 14px;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--c-line);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--c-muted);
}
.tiq-act-xifra span { font-size: 22px; font-weight: 800; line-height: 1.1; color: var(--c-ink); }
.tiq-act-xifra.is-nou span      { color: var(--c-orange-text); }
.tiq-act-xifra.is-en_curs span  { color: #1f56c9; }
.tiq-act-xifra.is-esperant span { color: var(--c-amber-text); }
.tiq-act-xifra.is-resolt span   { color: var(--c-green-text); }

.tiq-act-taula { width: 100%; border-collapse: collapse; font-size: 13px; color: var(--c-text); }
.tiq-act-taula th {
  padding: 10px 14px;
  text-align: left;
  font-size: 10.5px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--c-muted);
  border-bottom: 1px solid var(--c-line);
  white-space: nowrap;
}
.tiq-act-taula td { padding: 10px 14px; border-bottom: 1px solid var(--c-line-soft); vertical-align: middle; }
.tiq-act-taula tr:last-child td { border-bottom: 0; }
.tiq-act-taula .num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.tiq-act-taula tr.is-jo td { background: var(--c-orange-faint); }
.tiq-act-taula td.buit { padding: 24px 14px; text-align: center; color: var(--c-muted); }
.tiq-act-taula .pill { margin-left: 6px; }

/* ─── Adjunts dins la bombolla ───────────────────────────────────────────────
   Un missatge pot ser només text, només fitxers o totes dues coses. El marge
   només apareix quan hi ha text a sobre; així una foto sola queda enganxada a
   la vora de la bombolla i no sembla que hi falti res. */
.tiquet-adjunts {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.tiquet-msg-text + .tiquet-adjunts { margin-top: 9px; }

/* Miniatura d'una imatge. Mida fixa i `object-fit: cover` perquè una captura
   apaïsada i una foto vertical no descol·loquin la conversa; clicar-hi obre
   l'original. */
.tiquet-adjunt-img {
  display: block;
  width: 108px;
  height: 108px;
  border-radius: var(--r-btn-sm);
  overflow: hidden;
  background: var(--c-warm);
  box-shadow: inset 0 0 0 1px var(--c-line);
  transition: box-shadow .15s ease, transform .15s ease;
}
.tiquet-adjunt-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.tiquet-adjunt-img:hover { box-shadow: inset 0 0 0 2px var(--c-orange); transform: translateY(-1px); }

/* Fitxer que no és imatge: icona + nom + pes, i es baixa en clicar-hi. */
.tiquet-adjunt {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--r-btn-sm);
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--c-line);
  color: var(--c-text);
  transition: background .15s ease, box-shadow .15s ease;
}
.tiquet-adjunt:hover { background: var(--c-cream); box-shadow: inset 0 0 0 1px var(--c-orange-light); }
.tiquet-adjunt-ico {
  width: 30px;
  height: 30px;
  border-radius: var(--r-btn-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--c-warm);
  color: var(--c-orange);
  font-size: 13px;
}
.tiquet-adjunt-txt { min-width: 0; flex: 1; display: flex; flex-direction: column; }
.tiquet-adjunt-nom {
  font-size: 12.5px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tiquet-adjunt-mida { font-size: 10.5px; color: var(--c-muted); }
.tiquet-adjunt-baixa { font-size: 11px; color: var(--c-muted); flex-shrink: 0; }


/* ─── Quadre per adjuntar (elements/tiquet-adjunts.php i qui en copia el
       marcatge: /absencies.php i /comunicacions.php) ─────────────────────────
   L'<input type=file> està amagat i tot el quadre fa de botó i de zona de drop,
   com a Documentació i al perfil. Aquells estils viuen a documentacio.css i
   perfil.css, que en aquestes pantalles no es carreguen: per això aquí hi ha un
   component propi i no una còpia de `.upload-box`. */
.tiq-adjunts { margin-top: 12px; }

.tiq-adjuntar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 11px 13px;
  border: 1.5px dashed var(--c-line);
  border-radius: var(--r-btn);
  cursor: pointer;
  transition: border-color .13s ease, background .13s ease;
}
.tiq-adjuntar:hover { border-color: var(--c-orange); background: #fbf8f3; }
.tiq-adjuntar input[type=file] {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
/* L'input és d'1px i invisible, però amb el tabulador s'hi arriba igualment:
   sense això, qui navega amb teclat no veu on és. */
.tiq-adjuntar:has(input[type=file]:focus-visible) {
  outline: 2px solid var(--c-orange);
  outline-offset: 2px;
  border-color: var(--c-orange);
}
.tiq-adjuntar-ico {
  width: 34px;
  height: 34px;
  border-radius: var(--r-btn-sm);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--c-orange-faint);
  color: var(--c-orange-text);
  font-size: 14px;
}
.tiq-adjuntar-txt { display: flex; flex-direction: column; min-width: 0; }
.tiq-adjuntar-cta { font-size: 12.5px; font-weight: 700; }
.tiq-adjuntar-ajuda { font-size: 11px; color: var(--c-muted); }

.tiq-adjuntar.is-dragover { border-color: var(--c-orange); background: var(--c-orange-faint); }
.tiq-adjuntar.has-file    { border-color: var(--c-green); background: var(--c-green-light); }
.tiq-adjuntar.has-file .tiq-adjuntar-ico { background: var(--c-green-light); color: var(--c-green-text); }

/* Xips del que s'ha triat (els pinta tiquets.js). */
.tiq-tria {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
  list-style: none;
  padding: 0;
}
.tiq-xip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 100%;
  padding: 5px 8px 5px 10px;
  border-radius: var(--r-pill);
  background: var(--c-warm);
  font-size: 11.5px;
}
.tiq-xip > i { font-size: 11px; color: var(--c-muted); flex-shrink: 0; }
.tiq-xip-nom {
  font-weight: 600;
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tiq-xip-mida { color: var(--c-muted); flex-shrink: 0; }
.tiq-xip-x {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: var(--r-pill);
  background: transparent;
  color: var(--c-muted);
  font-size: 10px;
  cursor: pointer;
  flex-shrink: 0;
}
.tiq-xip-x:hover { background: var(--c-red-light); color: var(--c-red-text); }
/* Fitxer que ja se sap que el servidor rebutjarà (massa gran). */
.tiq-xip.is-error { background: var(--c-red-light); color: var(--c-red-text); }
.tiq-xip.is-error > i, .tiq-xip.is-error .tiq-xip-mida { color: var(--c-red); }

.tiq-adjunts-error {
  margin-top: 6px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--c-red);
}

@media (max-width: 640px) {
  .tiquet-msg-cos { max-width: 85%; }
  .tiquet-adjunt-img { width: 92px; height: 92px; }
  .tiq-xip-nom { max-width: 130px; }
}


/* ───────────────────────────────────────────────────────────────────────────
   Franja de login ràpid (suplantació d'identitat)

   Quan un administrador entra com una altra persona (/admin/usuaris.php →
   botó de la dreta), elements/header.php pinta aquesta franja a dalt de tot i
   posa `has-imp-bar` a <html>. Tota la franja és el botó de tornar.

   És sticky i va en flux normal (ocupa el seu espai), així que el que ja hi
   havia enganxat a dalt —la capçalera de la pàgina i la barra lateral, totes
   dues amb top:0— hi quedaria a sota. Per això, quan hi és, se'ls baixa el
   `top` l'alçada de la franja i se'ls retalla l'alçada de pantalla.
   z-index 40: per damunt de la capçalera (30) i per sota del drawer mòbil (50)
   i dels modals, que sí que l'han de poder tapar.
   ─────────────────────────────────────────────────────────────────────────── */
:root { --imp-bar-h: 38px; }

.imp-bar {
  position: sticky;
  top: 0;
  z-index: 40;
}

.imp-bar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  height: var(--imp-bar-h);
  padding: 0 14px;
  border: 0;
  background: var(--c-ink);
  color: #fff;
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}
.imp-bar-btn:hover { background: #1b1712; }

.imp-bar-icon { color: var(--c-orange); font-size: 13px; flex: 0 0 auto; }

/* Una sola línia sempre: si el nom és llarg es retalla, però l'alçada de la
   franja no creix mai —si creixés, el desplaçament de sota ja no quadraria. */
.imp-bar-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.imp-bar-text strong { font-weight: 800; }

.imp-bar-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  font-size: 11.5px;
  font-weight: 700;
  white-space: nowrap;
}
.imp-bar-btn:hover .imp-bar-back { background: rgba(255, 255, 255, 0.28); }

/* A mòbil només hi cap el nom: la frase llarga es queda pel camí (la píndola
   «Torna» i el títol del botó ja diuen què passa si s'hi clica). */
@media (max-width: 640px) {
  .imp-bar-long { display: none; }
}

html.has-imp-bar .app-header { top: var(--imp-bar-h); }
html.has-imp-bar .app-shell  { min-height: calc(100vh - var(--imp-bar-h)); }
@media (min-width: 1024px) {
  html.has-imp-bar .app-sidebar {
    top: var(--imp-bar-h);
    height: calc(100vh - var(--imp-bar-h));
  }
}

/* ───────────────────────────────────────────────────────────────────────────
   Franja de LES DADES QUE FALTEN A «LES MEVES DADES» (7 de setembre de 2026;
   generalitzada el 8 de setembre de 2026)

   Va néixer reclamant NOMÉS el número de la Seguretat Social, i d'aquí venen
   els noms `--nss-bar-h`, `.nss-bar` i `has-nss-bar`, que s'han quedat: són
   identificadors, i canviar-los volia dir tocar aquestes vint regles, la
   capçalera i el desplaçament de tota l'aplicació per guanyar-hi un nom més
   bonic. Avui reclama TOT el que va marcat OBLIGATORI a «Les meves dades»
   —les dades personals, aquell número i, a qui ja treballa, el compte
   bancari, les dues cares del DNI i el certificat de delictes sexuals—, i qui
   fa la llista és pend_llista() (funcions/perfil_pendents.php).

   Surt a TOTES les pantalles i no es pot tancar: mentre falti res, hi és. Per
   això és PRIMA —hi ha de poder ser molts dies sense fer-se insuportable— i
   per això la llista sencera va en un PANELL a part (`.pend-panell`), que
   s'obre i es tanca: en una franja de 28 píxels no hi caben dotze coses.

   Mateix funcionament que la franja de login ràpid d'aquí sobre: sticky, en
   flux normal, i `has-nss-bar` a <html> perquè el que ja hi havia enganxat a
   dalt (capçalera i barra lateral) hi baixi l'alçada de la franja. Poden
   sortir TOTES DUES alhora —un administrador entrant com una altra persona a
   qui li falten dades—, i llavors el desplaçament és la suma i aquesta va
   sota de l'altra (la de suplantació diu qui ets, i això mana).
   z-index 39: per sota de la de suplantació (40) i per damunt de la
   capçalera (30). El panell, en canvi, va a 41: per damunt de totes dues, o
   sortiria tallat per la franja de suplantació.
   ─────────────────────────────────────────────────────────────────────────── */
:root { --nss-bar-h: 28px; }

.nss-bar {
  position: sticky;
  top: 0;
  z-index: 39;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--nss-bar-h);
  padding: 0 12px;
  background: var(--c-red);
  color: #fff;
  font-size: 11.5px;
  font-weight: 600;
  line-height: 1;
}

html.has-imp-bar .nss-bar { top: var(--imp-bar-h); }

/* La meitat esquerra: l'enllaç directe a la pantalla. Té el `min-width: 0` per
   poder-se encongir i deixar el botó de la dreta sencer —sense això, un text
   llarg empeny el botó fora de la franja en comptes de retallar-se ell. */
.nss-bar-main {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}
.nss-bar-main:hover .nss-bar-text { text-decoration: underline; }

.nss-bar-icon { font-size: 11px; flex: 0 0 auto; }

/* Una sola línia sempre: si no hi cap es retalla, però l'alçada de la franja
   no creix mai —si creixés, el desplaçament de sota ja no quadraria. */
.nss-bar-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.nss-bar-text strong { font-weight: 800; }

/* La meitat dreta: el botó que obre la llista sencera. */
.nss-bar-cta {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  flex: 0 0 auto;
  padding: 3px 9px;
  border: 0;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  color: inherit;
  font: inherit;
  font-size: 10.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s ease;
}
.nss-bar-cta:hover { background: rgba(255, 255, 255, 0.34); }
.nss-bar-cta i { font-size: 8.5px; transition: transform 0.15s ease; }
.nss-bar-cta.is-obert i { transform: rotate(180deg); }

/* ── El panell de «Veure-ho tot» ──────────────────────────────────────────
   Ha de semblar que SURT DEL BOTÓ de la franja, i és el que fan les quatre
   coses d'aquí sota juntes: la vora de dalt vermella (el color de la franja),
   la fletxeta que apunta al botó, l'animació que el desplega des de dalt i que
   neixi enganxat a la franja i no surant al mig de la pantalla.

   `position: fixed` i no `absolute`: la franja és `sticky` i un fill absolut
   hi quedaria enganxat al flux, no a la pantalla. El `top` és la suma de les
   franges que hi hagi, igual que el desplaçament de la capçalera.

   ⚠️ La `right` i la posició de la fletxeta les acaba de posar el JS de la
   capçalera, que mesura on ha quedat el botó: la franja centra el seu contingut
   i el botó, per tant, no és mai al mateix lloc —depèn de quantes dades falten
   i de l'ample de la finestra—. Els valors d'aquí són el que es veu mentre el
   JS no hi arriba, i el que es veu si no n'hi ha.

   ⚠️ I el que fa scroll és la LLISTA, no el panell: si el desbordament fos del
   panell, la fletxeta —que li surt per fora— quedaria retallada, i a més el
   botó gros de baix marxaria de la vista amb dotze línies.

   z-index 41: per damunt de la franja de suplantació (40), que és la més alta
   de totes —si no, el panell sortiria per sota d'ella i es veuria tallat. */
.pend-panell {
  position: fixed;
  top: calc(var(--nss-bar-h) + 7px);
  right: 10px;
  z-index: 41;
  width: min(360px, calc(100vw - 20px));
  padding: 14px 15px 15px;
  background: #fff;
  border: 1px solid var(--c-line);
  border-top: 2px solid var(--c-red);
  border-radius: 4px 4px 14px 14px;
  box-shadow: 0 18px 44px rgba(20, 14, 8, 0.22);
  transform-origin: top right;
  animation: pend-desplega 0.16s ease-out;
}
html.has-imp-bar .pend-panell { top: calc(var(--imp-bar-h) + var(--nss-bar-h) + 7px); }

/* La fletxeta cap amunt, sota el botó que l'obre. És un quadrat girat 45°: les
   vores que queden a la vista són l'esquerra i la de dalt, i per això són les
   dues que porten el vermell de la franja. El cos blanc tapa el tros de vora
   del panell que li queda a sota. */
.pend-panell::before {
  content: '';
  position: absolute;
  top: -7px;
  right: var(--pend-fletxa, 26px);
  width: 12px;
  height: 12px;
  background: #fff;
  border-left: 2px solid var(--c-red);
  border-top: 2px solid var(--c-red);
  border-radius: 3px 0 0 0;
  transform: rotate(45deg);
}

@keyframes pend-desplega {
  from { opacity: 0; transform: translateY(-7px) scaleY(0.94); }
  to   { opacity: 1; transform: none; }
}
/* Qui ha demanat al sistema que no li moguin les coses, no se li mouen. */
@media (prefers-reduced-motion: reduce) {
  .pend-panell { animation: none; }
}

.pend-panell-cap {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 6px;
}
.pend-panell-titol {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 13.5px;
  font-weight: 800;
  color: var(--c-ink);
  line-height: 1.3;
}
.pend-panell-titol i { color: var(--c-red); font-size: 12px; }
.pend-panell-x {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--c-muted);
  cursor: pointer;
}
.pend-panell-x:hover { background: var(--c-warm); color: var(--c-ink); }

.pend-panell-ajuda {
  font-size: 11.5px;
  color: var(--c-muted);
  line-height: 1.45;
  margin-bottom: 10px;
}

.pend-panell-llista {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: min(46vh, 320px);
  overflow-y: auto;
  /* És un <ul>: sense això el navegador hi posa el seu punt, i al costat del
     nostre en surten dos. */
  list-style: none;
  margin: 0;
  padding: 0;
}
.pend-panell-llista a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 9px;
  border-radius: 9px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--c-ink);
  text-decoration: none;
}
.pend-panell-llista a:hover { background: var(--c-warm); }
.pend-panell-nom { flex: 1; min-width: 0; }

/* El pic de la llista. Un rodó ple i no cap icona: hi havia un
   `fa-regular fa-square` i es veia com un quadrat buit, indistingible d'un
   glif que no ha carregat (8 de setembre de 2026). */
.pend-panell-punt {
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--c-red);
}

/* La fletxa només surt en passar-hi per sobre: amb dotze línies, dotze fletxes
   sempre visibles fan soroll i no ajuden a llegir-les. */
.pend-panell-fletxa { font-size: 10px; color: var(--c-muted); opacity: 0; transition: opacity 0.12s; }
.pend-panell-llista a:hover .pend-panell-fletxa { opacity: 1; }

.pend-panell-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin-top: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--c-orange);
  color: #fff;
  font-size: 12.5px;
  font-weight: 800;
  text-decoration: none;
}
.pend-panell-cta:hover { background: var(--c-orange-dark); }

html.has-nss-bar .app-header { top: var(--nss-bar-h); }
html.has-nss-bar .app-shell  { min-height: calc(100vh - var(--nss-bar-h)); }
@media (min-width: 1024px) {
  html.has-nss-bar .app-sidebar {
    top: var(--nss-bar-h);
    height: calc(100vh - var(--nss-bar-h));
  }
}

/* Les dues franges alhora: el desplaçament és la suma. Va DESPRÉS de les dues
   regles simples i amb una classe més, o guanyaria la que toqués l'ordre. */
html.has-imp-bar.has-nss-bar .app-header { top: calc(var(--imp-bar-h) + var(--nss-bar-h)); }
html.has-imp-bar.has-nss-bar .app-shell  { min-height: calc(100vh - var(--imp-bar-h) - var(--nss-bar-h)); }
@media (min-width: 1024px) {
  html.has-imp-bar.has-nss-bar .app-sidebar {
    top: calc(var(--imp-bar-h) + var(--nss-bar-h));
    height: calc(100vh - var(--imp-bar-h) - var(--nss-bar-h));
  }
}

/* ───────────────────────────────────────────────────────────────────────────
   EMOTIUM DINS DE LABORAL  (public/emotium/entra.php)

   Una franja a dalt i el CMS d'Emotium en un iframe a sota, ocupant la resta.
   La pàgina NO fa scroll —el fa el marc—: si en fes, tindries dues barres de
   desplaçament, una dins de l'altra, i la franja marxaria amunt just quan la
   necessites.

   Mateix llenguatge que la franja de suplantació (fons `--c-ink`, píndoles
   translúcides) perquè les dues diuen la mateixa mena de cosa: «ara mateix no
   estàs on et penses».
   ─────────────────────────────────────────────────────────────────────────── */
:root { --emo-bar-h: 44px; }

.emo-body {
  margin: 0;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--c-ink);
}

.emo-bar {
  flex: 0 0 var(--emo-bar-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0 10px;
  background: var(--c-ink);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
}
.emo-bar a { color: inherit; text-decoration: none; }

.emo-bar-back,
.emo-bar-out {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.16);
  white-space: nowrap;
  transition: background 0.15s ease;
}
.emo-bar-back:hover,
.emo-bar-out:hover { background: rgba(255, 255, 255, 0.28); }
.emo-bar-back { font-weight: 700; }
.emo-bar-out  { font-weight: 600; font-size: 11.5px; }

.emo-bar-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  overflow: hidden;
}
.emo-bar-icon { color: var(--c-orange); font-size: 13px; flex: 0 0 auto; }
.emo-bar-text {
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.emo-bar-text strong { font-weight: 800; }

/* Apareix en el mateix clic i continua sobre el marc fins al load. */
.emotium-loading {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  background: #fff;
  color: var(--c-ink);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
}
.emotium-loading[hidden] { display: none; }
.emotium-loading-spinner {
  display: block;
  width: 42px;
  height: 42px;
  border: 4px solid #bceee1;
  border-top-color: #00b187;
  border-radius: 50%;
  animation: emotium-spin .75s linear infinite;
}
@keyframes emotium-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .emotium-loading-spinner { animation-duration: 2s; }
}
.emotium-frame-loading { top: var(--emo-bar-h); }

.emo-frame {
  flex: 1 1 auto;
  display: block;
  width: 100%;
  border: 0;
  background: #fff;
}

/* A mòbil hi cap poca cosa. El que no pot faltar MAI és el botó de tornar:
   és l'única sortida, perquè aquí no hi ha ni menú ni capçalera de Laboral. */
@media (max-width: 640px) {
  .emo-bar-title    { display: none; }
  .emo-bar-out span { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL RÈTOL DEL CONSENTIMENT  (elements/consentiment.php)
   ═══════════════════════════════════════════════════════════════════════════
   Una franja a baix, no una capa que prengui la pantalla: qui no vulgui
   contestar ha de poder seguir treballant, i mentre no contesti no es mesura.
   Els dos botons van junts i amb el mateix pes visual —dir que no ha de
   costar el mateix que dir que sí, que és el que l'AEPD demana. */
.consent-franja {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 60;
  background: #fff;
  border-top: 1px solid var(--c-line);
  box-shadow: 0 -8px 24px rgba(42, 37, 31, .10);
  padding: 14px 16px;
  /* Respecta la barra d'inici dels mòbils i la barra inferior de navegació. */
  padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  transition: transform .2s ease, opacity .2s ease;
}
.consent-franja.is-fora { transform: translateY(100%); opacity: 0; }

.consent-cos {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.consent-text {
  flex: 1 1 320px;
  font-size: 12.5px;
  line-height: 1.55;
  color: var(--c-muted);
}
.consent-text strong { color: var(--c-ink); display: block; font-size: 13.5px; }
.consent-text a      { color: var(--c-green-dark); font-weight: 600; text-decoration: underline; }

.consent-botons { display: flex; gap: 8px; flex: 0 0 auto; }
.consent-btn {
  border-radius: 12px;
  padding: 9px 18px;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  border: 1px solid transparent;
  white-space: nowrap;
}
.consent-btn--si  { background: var(--c-green); color: #fff; }
.consent-btn--si:hover  { background: var(--c-green-dark); }
.consent-btn--no  { background: transparent; color: var(--c-ink); border-color: var(--c-line); }
.consent-btn--no:hover  { background: var(--c-cream); }

/* A mòbil, la segona frase és matís i el que compta és la pregunta i els dos
   botons: amagant-la, la franja no es menja mitja pantalla. */
@media (max-width: 640px) {
  .consent-fi     { display: none; }
  .consent-botons { width: 100%; }
  .consent-btn    { flex: 1; }
}

/* Amb el moviment reduït, la franja se'n va de cop en lloc de lliscar. */
@media (prefers-reduced-motion: reduce) {
  .consent-franja { transition: none; }
}

/* ───────────────────────────────────────────────────────────────────────────
   Avisos flotants (toasts) — els flashos de sessió
   ───────────────────────────────────────────────────────────────────────────
   Fins al 17 d'agost de 2026, els flashos es pintaven com un bloc inline a
   dalt de tot del <main> (elements/header.php). El problema era real i es
   veia sobretot a «Les meves dades»: aquella pantalla redirigeix amb àncora
   (`...#documents`, `...#estudis`), o sigui que el navegador et deixa a mig
   scroll — i el missatge de «Desat» o l'error de validació es quedava amunt,
   fora de la vista. Feies l'acció i semblava que no havia passat res.

   Ara van aquí: fixos, per damunt de tot, es tanquen sols i amb creueta.
   El marcatge el pinta elements/toasts.php i el comportament viu a
   setupToasts() de /js/funcions.js.

   z-index 120: per damunt de la capçalera enganxosa (30), la barra inferior
   (40), el drawer mòbil (50), la franja de login ràpid (52) i els rètols
   emergents (55/60). Un avís no l'ha de tapar mai res.

   La pila NO intercepta clics (pointer-events: none) — només els toasts, o
   una cantonada buida de la pantalla es quedaria morta mentre dura l'avís. */
/* Valor de sortida de --header-space: el mateix que hi havia abans que la pila
   es recolzés a la capçalera. setupHeaderSpace() (funcions.js) el reescriu com
   a estil inline a <html> amb la mida de veritat, i aquell guanya. */
:root { --header-space: max(12px, env(safe-area-inset-top, 0px)); }

.toast-stack {
  position: fixed;
  z-index: 120;
  /* SOTA la capçalera, no a sobre. `--header-space` és la vora inferior real de
     .app-header mesurada al navegador (setupHeaderSpace(), funcions.js).
     A mòbil la capçalera porta el botó del menú i la campaneta, i un avís de
     vora a vora a `top: 12px` els tapava tots dos: sortia un missatge i, mentre
     durava, no es podia obrir el menú. Al fallback dels 12 px hi torna només si
     el JS no s'executa, que és el comportament d'abans i no és pitjor.

     Es mesura la vora INFERIOR i no l'alçada a posta: així ja hi va inclosa la
     barra de suplantació quan hi és (que empeny la capçalera cap avall), i no
     cal cap regla a part per a `html.has-imp-bar`.

     El valor de sortida és a :root (aquí sota) i no com a segon argument de
     var(): així el fallback pot ser una expressió amb la safe area, que és el
     que feia abans i no s'ha de perdre si el JS no arriba a córrer. */
  top: calc(var(--header-space) + 12px);
  left: 12px;
  right: 12px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  pointer-events: none;
}

/* A partir de sm, ancorat a la dreta i amb amplada pròpia (no ocupa tota
   la capçalera). A mòbil es queda de vora a vora, que és on hi ha lloc. */
@media (min-width: 640px) {
  .toast-stack {
    left: auto;
    right: 20px;
    width: min(400px, calc(100vw - 40px));
  }
}

.toast {
  pointer-events: auto;
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  overflow: hidden;
  background: #fff;
  border-radius: var(--r-card, 18px);
  border-left: 5px solid var(--toast-accent, var(--c-orange));
  box-shadow: 0 12px 32px rgba(30, 26, 20, 0.18), 0 2px 6px rgba(30, 26, 20, 0.08);
  padding: 14px 42px 14px 14px;
  animation: toastIn 0.28s cubic-bezier(.2, .9, .3, 1.25);
}
.toast.is-closing { animation: toastOut 0.2s ease-in forwards; }

.toast-ico {
  flex-shrink: 0;
  width: 34px; height: 34px;
  border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px;
  background: var(--toast-bg, var(--c-orange-faint));
  color: var(--toast-fg, var(--c-orange-text));
}

/* white-space: pre-line — algun avís porta salts de línia a posta (el de la
   ubicació bloquejada del fitxatge, per exemple, que explica on desbloquejar-la).
   overflow-wrap: qualsevol paraula llarga (una ruta, un correu) parteix en lloc
   de desbordar la capsa. */
.toast-msg {
  margin: 6px 0 0;
  flex: 1;
  min-width: 0;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  color: var(--c-ink);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

.toast-close {
  position: absolute;
  top: 10px; right: 10px;
  width: 28px; height: 28px;
  border: 0;
  border-radius: 999px;
  background: var(--c-line-soft);
  color: var(--c-muted);
  font-size: 12px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s;
}
.toast-close:hover { background: var(--c-red-light); color: var(--c-red-text); }
.toast-close:focus-visible { outline: 2px solid var(--c-orange); outline-offset: 2px; }

/* Barra de temps: ensenya quant li queda a l'avís abans de marxar sol. La
   durada la posa el JS (--toast-dur) i s'atura en passar-hi el ratolí o en
   tenir-hi el focus (setupToasts), perquè no se'n vagi mentre el llegeixes. */
.toast-bar {
  position: absolute;
  left: 0; bottom: 0;
  height: 3px;
  width: 100%;
  transform-origin: left center;
  background: var(--toast-accent, var(--c-orange));
  opacity: 0.5;
  animation: toastBar var(--toast-dur, 5s) linear forwards;
}
.toast:hover .toast-bar,
.toast:focus-within .toast-bar { animation-play-state: paused; }

.toast[data-kind="success"] { --toast-accent: var(--c-green); --toast-bg: var(--c-green-light);  --toast-fg: var(--c-green-text); }
.toast[data-kind="error"]   { --toast-accent: var(--c-red);   --toast-bg: var(--c-red-light);    --toast-fg: var(--c-red-text); }
.toast[data-kind="warning"] { --toast-accent: var(--c-amber); --toast-bg: var(--c-amber-light);  --toast-fg: var(--c-amber-text); }
.toast[data-kind="info"]    { --toast-accent: var(--c-orange);--toast-bg: var(--c-orange-faint); --toast-fg: var(--c-orange-text); }

@keyframes toastIn  { from { opacity: 0; transform: translateY(-12px) scale(0.97); } to { opacity: 1; transform: none; } }
@keyframes toastOut { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateY(-10px) scale(0.97); } }
@keyframes toastBar { from { transform: scaleX(1); } to { transform: scaleX(0); } }

/* Amb el moviment reduït, els avisos apareixen i marxen de cop. La barra de
   temps es queda quieta i plena: segueix sent la pista visual que l'avís és
   temporal, però sense animació. */
@media (prefers-reduced-motion: reduce) {
  .toast, .toast.is-closing { animation: none; }
  .toast-bar { animation: none; }
}

/* ─── Editor HTML (TinyMCE), public/js/editor-html.js ────────────────────────
   Qualsevol <textarea class="html-editor">: el missatge de benvinguda d'una
   oferta i la descripció de la feina (elements/jornada-camps.php) totes dues
   en fan servir un. El <textarea> neix amagat perquè no es vegi el
   pampallugueig mentre TinyMCE arrenca; si TinyMCE no hi arriba a ser
   (.sense-editor, afegida pel JS), es torna a ensenyar i el camp segueix
   servint —s'hi escriu l'HTML a pèl. */
.html-editor { display: none; }
.html-editor.sense-editor { display: block; min-height: 180px; font-family: ui-monospace, monospace; font-size: 12.5px; }
.tinymce-error + .tox-tinymce,
.tox-tinymce.has-error      { border-color: #dc2626 !important; }
.tox-tinymce                { border-radius: 12px !important; border-color: #e8e2da !important; }
.tox .tox-toolbar__primary,
.tox .tox-toolbar,
.tox .tox-toolbar__overflow { background: #faf8f5 !important; }
.tox:not(.tox-tinymce-inline) .tox-editor-header {
  box-shadow: none !important;
  border-bottom: 1px solid #f0ece5 !important;
}
.tox .tox-statusbar { border-top: 1px solid #f0ece5 !important; background: #faf8f5 !important; }


/* ─── Antiguitat a la capçalera d'una fitxa (/treballadors/fitxa.php) ─────────
   «Treballa des del 3 d'octubre de 2022» i, per a qui la pot escriure, el camp
   per posar-la o corregir-la. Va aquí i no amb Tailwind perquè el build està
   purgat i el camp de data compacte no hi surt amb cap classe que hi sigui:
   `.input-base` fa 46 px d'alt i ocupa tota l'amplada, que és el que volem als
   formularis de debò i no en una tira d'una sola línia. */
.antig-bloc {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 16px;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--c-line-soft);
}
.antig-frase {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--c-ink);
}
.antig-frase i { color: var(--c-orange); }
/* Sense data encara: es diu, però no crida. */
.antig-frase.is-buida { font-weight: 600; color: var(--c-muted); }
.antig-frase.is-buida i { color: var(--c-faint); }

/* ── La frase, quan a més és el BOTÓ que obre el camp ──────────────────────
   Només la porta qui pot escriure l'antiguitat (antig_pot_editar()). Ha de
   convidar a clicar-hi sense semblar un botó de debò: aquí no s'hi fa cap
   acció, s'obre un camp.

   El reset del principi no és decoratiu: un <button> hereta la tipografia del
   navegador i no la de la pàgina, i sense `font: inherit` la frase sortiria
   amb una lletra diferent de la mateixa frase de qui no la pot editar —que és
   just al costat a l'altra fitxa—. */
.antig-frase--edita {
  font: inherit;
  font-size: 12.5px;
  font-weight: 700;
  background: none;
  border: 0;
  padding: 2px 4px;
  margin: -2px -4px;              /* que el marge de clic no desplaci el text */
  border-radius: 8px;
  cursor: pointer;
  text-align: left;
  color: var(--c-ink);
  /* El puntejat diu «això es pot canviar» sense fer-ne un botó. */
  text-decoration: underline dotted var(--c-line);
  text-underline-offset: 3px;
  transition: background-color .15s ease, text-decoration-color .15s ease;
}
.antig-frase--edita:hover,
.antig-frase--edita:focus-visible {
  background: var(--c-cream);
  text-decoration-color: var(--c-orange);
}
.antig-frase--edita:focus-visible {
  outline: 2px solid var(--c-orange);
  outline-offset: 1px;
}
/* El llapis apareix en passar-hi per sobre; a tauleta i mòbil, on no hi ha cap
   ratolí que hi passi, hi és sempre (vegeu la consulta de sota). */
.antig-llapis {
  font-size: 9.5px;
  opacity: 0;
  transition: opacity .15s ease;
}
.antig-frase--edita:hover .antig-llapis,
.antig-frase--edita:focus-visible .antig-llapis { opacity: .75; }
@media (hover: none) {
  .antig-llapis { opacity: .55; }
}
.antig-cancella {
  background: none;
  border: 0;
  padding: 6px 4px;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--c-muted);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.antig-cancella:hover { color: var(--c-ink); }
.antig-form {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
}
.antig-form label {
  font-size: 11.5px;
  font-weight: 700;
  color: var(--c-muted);
}
.antig-input {
  background: #fff;
  border: 1px solid var(--c-line);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.3;
  color: var(--c-ink);
  min-height: 34px;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
}
.antig-input:focus {
  outline: none;
  border-color: var(--c-orange);
  box-shadow: 0 0 0 3px rgba(243, 146, 0, 0.15);
}
@media (max-width: 640px) {
  .antig-form { margin-left: 0; width: 100%; }
  .antig-input { flex: 1; min-width: 0; }
}

/* ─── «Sense salt»: mentre una acció va i torna (public/js/sense-salt.js) ────
   Una acció que no recarrega la pàgina no té el senyal que donava el navegador
   —la barra de càrrega, la pàgina en blanc—, i sense cap altre senyal sembla que
   el clic no hagi fet res i es torna a prémer. Dues pistes discretes i prou: el
   cursor de tota la pàgina i el botó que s'ha premut, que a més queda
   deshabilitat perquè no s'hi pugui insistir.

   ⚠️ `.is-enviant` és la classe que ja fa servir el fitxatge per a això mateix
   (extres.css, fitxatge.css i, aquí mateix, .fitxr-punch) i es reaprofita a
   posta: és la paraula del projecte per «s'està enviant». El que va dins de
   `[data-salt]` i no solt és perquè aquelles tres ja tenen el seu aspecte i
   una regla global els canviaria la cara sense que ningú ho hagi demanat. */
html.salt-ocupat { cursor: progress; }
html.salt-ocupat [data-salt] { cursor: progress; }
[data-salt] .is-enviant {
  opacity: .6;
  pointer-events: none;
}
/* El botó que espera: un puntet que batega al davant, que es veu igual amb
   qualsevol dels colors de botó de l'app. */
[data-salt] .is-enviant::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: 50%;
  background: currentColor;
  animation: salt-bateg 900ms ease-in-out infinite;
}
@keyframes salt-bateg {
  0%, 100% { opacity: .25; }
  50%      { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  [data-salt] .is-enviant::before { animation: none; opacity: .6; }
}

/* ─── Paginació d'un llistat (elements/paginacio.php, 21 set 2026) ───────────
   Tria de quantes files per pàgina i botons per passar de pàgina. Neix al
   llistat d'ofertes i és de qualsevol llistat que la vulgui: per això viu aquí i
   no a ofertes.css. Tot són enllaços, i el botó actiu porta el mateix aspecte
   que la pestanya activa d'aquell llistat (tinta sòlida, lletra blanca), perquè
   es llegeixi com el mateix «estic aquí».
   Colors de les variables de marca; l'únic literal és el blanc, com a les
   pestanyes. */
.pag {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px 18px;
  margin: 14px 0;
}
.pag-mida,
.pag-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}
.pag-etiqueta,
.pag-rang {
  font-size: 11.5px;
  color: var(--c-muted);
  margin: 0;
}
.pag-etiqueta { margin-right: 2px; }
.pag-rang strong { color: var(--c-ink); font-weight: 700; }
.pag-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 34px;
  height: 34px;
  padding: 0 10px;
  border-radius: 12px;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1;
  color: var(--c-ink);
  background: #fff;
  box-shadow: 0 0 0 1px var(--c-line);
  text-decoration: none;
  transition: background-color .15s ease;
}
.pag-btn:hover { background: var(--c-cream); }
.pag-btn:focus-visible { outline: 2px solid var(--c-orange); outline-offset: 2px; }
.pag-btn.is-actiu,
.pag-btn.is-actiu:hover {
  background: var(--c-ink);
  color: #fff;
  box-shadow: none;
}
.pag-btn.is-off { opacity: .4; pointer-events: none; }
.pag-punts { color: var(--c-faint); padding: 0 2px; }
/* En mòbil «Anterior/Següent» es queden en la fletxa sola i tot centrat: les
   cinc pàgines i les dues fletxes han de cabre en una fila. */
@media (max-width: 640px) {
  .pag { justify-content: center; }
  .pag-text { display: none; }
}

/* ─── Layout incrustat (dins d'un <iframe>, 27 de setembre de 2026) ─────────
   elements/header.php amb `$layout = 'incrustat'`: només el contingut, sense
   menú ni capçalera. El marge és petit perquè el marc de fora ja en porta, i
   el cos no ocupa tota la pantalla: l'alçada la diu el contingut, que és el
   que el peu mesura i envia a la pàgina de fora. */
html.is-incrustat body { min-height: 0; }
.incrustat-main { padding: 14px 16px 18px; }
