/* TimeChamp — design system.
   I colori del brand arrivano dal tenant come variabili CSS (vedi header.php),
   così l'app è white-label senza toccare il foglio di stile.

   DIREZIONE — "servizio serale"
   Non è un gestionale da scrivania: si usa in cucina, dietro al bancone e
   all'una di notte. I neutri sono quindi CALDI (nero di fumo, non grigio-blu
   da ufficio), l'accento predefinito è ottone come il bancone di un bar e il
   verde-menta accompagna i dati positivi.
   La firma sono i NUMERI: orari, ore e importi passano dal carattere display
   con cifre a larghezza fissa, che oltre a dare personalità le incolonna. */

/* Font ospitati QUI e non caricati da Google: richiamarli dal loro server
   manderebbe l'indirizzo IP di ogni dipendente a un terzo a ogni pagina, e su
   un'app che tratta dati del personale è una cosa da non fare. */
@font-face {
  font-family: 'Bricolage Grotesque';
  src: url('../fonts/bricolage-grotesque.woff2') format('woff2');
  font-weight: 400 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('../fonts/instrument-sans.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
}

:root {
  --brand:        #b0762b;   /* ottone: il default, ogni azienda lo sovrascrive */
  --brand-2:      #2f8f7d;   /* menta scura */
  --bg:           #eceeea;
  --surface:      #ffffff;
  --surface-2:    #e3e7e1;
  --border:       #d2d7cf;
  --text:         #17201c;
  --text-soft:    #5d6a62;
  --ok:           #2f8f5b;
  --warn:         #c2790f;
  --bad:          #c8483c;
  --info:         #37718c;
  --radius:       14px;
  --radius-sm:    10px;
  --shadow:       0 1px 2px rgba(23,32,28,.05), 0 6px 18px rgba(23,32,28,.06);
  --shadow-lg:    0 18px 44px rgba(23,32,28,.18);
  --font:         'Instrument Sans', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-display: 'Bricolage Grotesque', 'Instrument Sans', -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* Tema scuro: nero caldo da sala la sera, non blu notte da cruscotto.
   È il tema curato per primo, perché è quello che il personale vede davvero
   quando timbra all'una di notte. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:        #14120f;
    --surface:   #1d1a16;
    --surface-2: #272320;
    --border:    #37312b;
    --text:      #f4efe7;
    --text-soft: #a89e92;
    --ok:        #4cbb7f;
    --warn:      #e0a545;
    --bad:       #e0705f;
    --info:      #6aa9c4;
    --shadow:    0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
    --shadow-lg: 0 20px 50px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"] {
  --bg:        #14120f;
  --surface:   #1d1a16;
  --surface-2: #272320;
  --border:    #37312b;
  --text:      #f4efe7;
  --text-soft: #a89e92;
  --ok:        #4cbb7f;
  --warn:      #e0a545;
  --bad:       #e0705f;
  --info:      #6aa9c4;
  --shadow:    0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
  --shadow-lg: 0 20px 50px rgba(0,0,0,.55);
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  padding-bottom: env(safe-area-inset-bottom);
}
a { color: var(--brand); text-decoration: none; }
a:hover { text-decoration: underline; }
/* I titoli passano dal carattere display: è lì che vive la personalità.
   Il corpo del testo resta su Instrument Sans, che a 15px si legge meglio. */
h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1.18; margin: 0 0 .6rem; letter-spacing: -.025em;
}
h1 { font-size: 1.7rem; font-weight: 750; }
h2 { font-size: 1.24rem; font-weight: 700; }
h3 { font-size: 1.02rem; font-weight: 650; letter-spacing: -.015em; }

/* --------------------------------------------------------------- numeri */
/* Orari, ore e importi sono il contenuto vero di questa app: cifre a
   larghezza fissa così le colonne si allineano davvero, e carattere display
   dove il numero è protagonista. */
table, .stat .v, .pl-cost, .pl-dstats, .clock, .shiftcard .time, .shiftcard .dur,
.iban-box .val, .wk-tot, .daystrip .n {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.stat .v, .clock, .shiftcard .time, .daystrip .n {
  font-family: var(--font-display);
  letter-spacing: -.03em;
}
small, .muted { color: var(--text-soft); }
.muted { font-size: .875rem; }

/* ---------------------------------------------------------------- layout */
.wrap { max-width: 1180px; margin: 0 auto; padding: 20px 16px 90px; }
.wrap-narrow { max-width: 620px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.row-between { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; }
.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); }
.grow { flex: 1 1 auto; }
.center { text-align: center; }
.mt { margin-top: 18px; } .mt-sm { margin-top: 10px; } .mb { margin-bottom: 18px; }
.hide { display: none !important; }

/* -------------------------------------------------------------- topbar */
/* Nota sui fallback: color-mix() richiede browser dal 2023 in poi. Dove il
   colore è indispensabile alla leggibilità si dichiara prima una tinta piena:
   i browser vecchi ignorano la riga successiva e restano comunque leggibili. */
.topbar {
  position: sticky; top: 0; z-index: 40;
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 86%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--border);
}
.topbar-in { max-width: 1180px; margin: 0 auto; padding: 10px 16px;
  display: flex; align-items: center; gap: 14px; }
.brand { display: flex; align-items: center; gap: 10px; font-weight: 700;
  font-family: var(--font-display); font-size: 1.02rem;
  color: var(--text); letter-spacing: -.03em; }
.brand:hover { text-decoration: none; }
/* Il riquadro con l'iniziale: c'è solo quando l'azienda non ha caricato un
   logo, e allora un quadrato colorato ci sta bene. */
.brand-logo { width: 30px; height: 30px; border-radius: 8px; object-fit: cover;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  display: grid; place-items: center; color: #fff; font-size: 15px; font-weight: 800; }
/* Il logo vero, invece, si mostra INTERO. Prima stava in un quadrato di 30
   pixel con object-fit: cover, cioè ritagliato al centro: di un logo largo si
   vedevano tre lettere in mezzo. Ora l'altezza è fissa, la larghezza segue le
   proporzioni e niente fondo colorato dietro — un PNG con il suo sfondo se lo
   porta già, uno trasparente si appoggia alla barra. */
img.brand-logo {
  width: auto; height: 30px; max-width: 150px;
  object-fit: contain; border-radius: 6px; background: none;
}
.nav { display: flex; gap: 2px; margin-left: auto; align-items: center; flex-wrap: wrap; }
.nav a {
  color: var(--text-soft); padding: 7px 11px; border-radius: 9px;
  font-size: .9rem; font-weight: 550; white-space: nowrap;
}
.nav a:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.nav a.on { background: var(--brand); color: #fff; }
/* Il proprio nome nella barra: si distingue dalle sezioni perché non è un
   posto dove si lavora, è chi sei. */
.nav a.nav-me { font-weight: 650; color: var(--text); }
.nav a.nav-me::before {
  content: ''; display: inline-block; width: 7px; height: 7px; margin-right: 6px;
  border-radius: 50%; background: var(--ok); vertical-align: middle;
}
/* Contatore accanto alla voce: le cose da approvare devono vedersi senza
   dover aprire la pagina per scoprirle. */
.nav-badge {
  display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 5px;
  border-radius: 9px; background: var(--warn); color: #fff;
  font-size: .7rem; font-weight: 800; line-height: 18px; text-align: center;
  vertical-align: middle;
}
.nav a.on .nav-badge { background: rgba(255,255,255,.28); }
/* Sul telefono il dipendente ha già la barra in basso: i link ripetuti in alto
   occuperebbero due righe per niente. Restano campanella e uscita. */
@media (max-width: 700px) {
  .nav a.nav-emp { display: none; }
}
.bell { position: relative; }
.bell .dot {
  position: absolute; top: 2px; right: 2px; min-width: 17px; height: 17px;
  background: var(--bad); color: #fff; border-radius: 9px; font-size: .68rem;
  display: grid; place-items: center; font-weight: 700; padding: 0 4px;
}

/* --------------------------------------------------------------- cards */
.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow);
}
.card + .card { margin-top: 14px; }
.card-head { display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.card-head h2, .card-head h3 { margin: 0; }
.stat { background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 15px 16px; box-shadow: var(--shadow); }
.stat .k { color: var(--text-soft); font-size: .78rem; text-transform: uppercase;
  letter-spacing: .06em; font-weight: 650; }
.stat .v { font-size: 1.6rem; font-weight: 750; letter-spacing: -.02em; margin-top: 3px; }

/* ------------------------------------------------------------- buttons */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid transparent; border-radius: var(--radius-sm);
  padding: 10px 17px; font-size: .93rem; font-weight: 650; font-family: inherit;
  letter-spacing: -.01em;
  cursor: pointer; background: var(--brand); color: #fff;
  transition: transform .08s ease, filter .15s ease, background .15s ease;
  min-height: 44px;
}
.btn:hover { filter: brightness(1.06); text-decoration: none; }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--border); }
.btn-ghost:hover { background: var(--surface-2); }
.btn-soft { background: var(--surface-2); color: var(--text); }
.btn-ok { background: var(--ok); } .btn-bad { background: var(--bad); }
.btn-warn { background: var(--warn); color: #422006; }
.btn-sm { padding: 6px 11px; font-size: .84rem; min-height: 34px; border-radius: 8px; }
.btn-block { width: 100%; }

/* --------------------------------------------------------------- forms */
label { display: block; font-weight: 600; font-size: .86rem; margin-bottom: 5px; }
input[type=text], input[type=email], input[type=password], input[type=number],
input[type=date], input[type=time], input[type=datetime-local], input[type=search],
input[type=tel], input[type=file], select, textarea {
  width: 100%; padding: 10px 12px; font-size: .95rem; font-family: inherit;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  min-height: 44px;
}
textarea { min-height: 90px; resize: vertical; }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--brand);
  box-shadow: 0 0 0 2px var(--brand);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent);
}
.field { margin-bottom: 14px; }
.field-hint { font-size: .8rem; color: var(--text-soft); margin-top: 4px; }
.check { display: flex; align-items: center; gap: 9px; font-weight: 500; }
.check input { width: 19px; height: 19px; min-height: 0; accent-color: var(--brand); }
fieldset { border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 14px; margin: 0 0 14px; }
legend { font-weight: 650; font-size: .87rem; padding: 0 6px; }

/* -------------------------------------------------------------- tables */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th, td { padding: 10px 11px; text-align: left; border-bottom: 1px solid var(--border);
  white-space: nowrap; }
th { font-size: .72rem; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-soft); font-weight: 700; background: var(--surface-2);
  font-family: var(--font-display); }
tbody tr:hover { background: var(--surface-2); }
td.wrap-cell, th.wrap-cell { white-space: normal; }
tfoot td { font-weight: 700; background: var(--surface-2); }

/* --------------------------------------------------------------- badge */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px;
  border-radius: 999px; font-size: .77rem; font-weight: 650; line-height: 1.6; }
.badge-ok   { background: var(--surface-2); color: var(--ok);
              background: color-mix(in srgb, var(--ok) 16%, transparent); }
.badge-warn { background: var(--surface-2); color: #b45309;
              background: color-mix(in srgb, var(--warn) 18%, transparent); }
.badge-bad  { background: var(--surface-2); color: var(--bad);
              background: color-mix(in srgb, var(--bad) 15%, transparent); }
.badge-info { background: var(--surface-2); color: var(--info);
              background: color-mix(in srgb, var(--info) 15%, transparent); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .badge-warn { color: #fbbf24; }
}

/* --------------------------------------------------------------- alert */
.alert { border-radius: var(--radius-sm); padding: 12px 14px; margin-bottom: 14px;
  border: 1px solid var(--border); background: var(--surface-2); font-size: .92rem; }
.alert-success { border-color: var(--ok);
  background: color-mix(in srgb, var(--ok) 12%, transparent);
  border-color: color-mix(in srgb, var(--ok) 35%, transparent); }
.alert-error, .alert-danger { border-color: var(--bad);
  background: color-mix(in srgb, var(--bad) 12%, transparent);
  border-color: color-mix(in srgb, var(--bad) 35%, transparent); }
.alert-warn { border-color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, transparent);
  border-color: color-mix(in srgb, var(--warn) 38%, transparent); }
.alert-info { border-color: var(--info);
  background: color-mix(in srgb, var(--info) 12%, transparent);
  border-color: color-mix(in srgb, var(--info) 32%, transparent); }

/* ------------------------------------------------------- app dipendente */
.clock-screen {
  min-height: calc(100vh - 56px);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 18px; padding: 26px 18px 100px; text-align: center;
}
.clock {
  font-size: clamp(3.6rem, 19vw, 6rem); font-weight: 250; letter-spacing: -.045em;
  font-variant-numeric: tabular-nums; line-height: 1;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.clock-sec { font-size: .38em; font-weight: 400; opacity: .55; letter-spacing: -.02em; }
.clock-date { color: var(--text-soft); font-size: 1rem; text-transform: capitalize;
  margin-top: -6px; }
.punch {
  width: min(74vw, 250px); aspect-ratio: 1; border-radius: 50%; border: none;
  color: #fff; font-size: 1.45rem; font-weight: 750; letter-spacing: .03em;
  cursor: pointer; font-family: inherit; display: grid; place-items: center;
  gap: 4px; line-height: 1.2; position: relative;
  transition: transform .12s ease, box-shadow .2s ease;
}
.punch small { font-size: .72rem; font-weight: 500; opacity: .9; letter-spacing: 0; }
.punch-in  { background: linear-gradient(140deg, #10b981, #059669);
  box-shadow: 0 18px 40px rgba(16,185,129,.38); }
.punch-out { background: linear-gradient(140deg, #f43f5e, #e11d48);
  box-shadow: 0 18px 40px rgba(244,63,94,.36); }
.punch:active { transform: scale(.96); }
.punch[disabled] { filter: grayscale(.5); opacity: .65; }
.punch::after {
  content: ''; position: absolute; inset: -9px; border-radius: 50%;
  border: 2px solid currentColor; opacity: .18; animation: pulse 2.4s ease-out infinite;
}
@keyframes pulse {
  0%   { transform: scale(1);    opacity: .22; }
  70%  { transform: scale(1.13); opacity: 0; }
  100% { transform: scale(1.13); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .punch::after { animation: none; }
}
.session-info { background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 13px 20px; box-shadow: var(--shadow);
  display: flex; gap: 22px; align-items: center; }
.session-info b { font-size: 1.1rem; }

/* barra di navigazione in basso (solo dipendente, mobile) */
.tabbar {
  position: fixed; bottom: 0; left: 0; right: 0; z-index: 50;
  background: var(--surface);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(14px); border-top: 1px solid var(--border);
  display: flex; padding-bottom: env(safe-area-inset-bottom);
}
/* flex-basis 0 + min-width 0: con cinque voci le etichette possono restringersi
   invece di far sforare la barra oltre il bordo dello schermo. */
.tabbar a { flex: 1 1 0; min-width: 0; text-align: center; padding: 9px 3px 10px;
  color: var(--text-soft); font-size: .69rem; font-weight: 600;
  display: grid; gap: 2px; justify-items: center; }
.tabbar a span { max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.tabbar a:hover { text-decoration: none; }
.tabbar a.on { color: var(--brand); }
.tabbar svg { width: 22px; height: 22px; }

/* --------------------------------------------------------------- modal */
.modal-back {
  position: fixed; inset: 0; background: rgba(15,23,42,.55); z-index: 100;
  display: grid; place-items: center; padding: 16px; backdrop-filter: blur(3px);
}
.modal {
  background: var(--surface); border-radius: var(--radius); padding: 20px;
  width: 100%; max-width: 460px; box-shadow: var(--shadow-lg);
  max-height: 88vh; overflow-y: auto;
}

/* ----------------------------------------------------------- sedi (tab) */
/* Su quale locale si sta lavorando non è un dettaglio da menu a tendina: è il
   contesto di tutto quello che c'è sotto. Stesse schede ovunque — planner,
   serate — perché sono la stessa scelta, e cambiare forma da una pagina
   all'altra la fa sembrare un'altra cosa. Con una sola sede spariscono.
   Si scorrono in orizzontale sul telefono invece di andare a capo, così la
   barra resta alta una riga sola. */
.sedi { display: flex; gap: 4px; margin-bottom: 12px; overflow-x: auto;
  -webkit-overflow-scrolling: touch; padding-bottom: 2px; }
.sede-tab { flex: 0 0 auto; padding: 8px 16px; border-radius: 999px;
  font-weight: 600; font-size: .92rem; color: var(--text-soft);
  background: var(--surface); border: 1px solid var(--border); white-space: nowrap; }
.sede-tab:hover { text-decoration: none; color: var(--text); }
.sede-tab.on { background: var(--brand); border-color: var(--brand); color: #fff; }

/* -------------------------------------------------------------- planner */
/* Sui colori: le schede turno usano un fondo pastello ricavato dal colore del
   reparto/modello con color-mix() SUL COLORE DI SUPERFICIE, non su transparent.
   Così il testo resta var(--text) — scuro in tema chiaro, chiaro in tema scuro —
   e il contrasto regge in entrambi i temi. La riga prima del mix è il fallback
   a tinta piena per i browser senza color-mix(). */

/* ---- barra strumenti ---- */
.pl-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 11px 13px; }
.pl-bar-l, .pl-bar-r { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pl-bar-r { margin-left: auto; }
.pl-sep { width: 1px; height: 26px; background: var(--border); margin: 0 2px; }

.pl-ico {
  width: 38px; height: 38px; min-height: 38px; padding: 0; flex: 0 0 auto;
  display: inline-grid; place-items: center; position: relative;
  border: 1px solid var(--border); border-radius: 50%; cursor: pointer;
  background: var(--surface); color: var(--text-soft); font-size: 1rem;
  font-family: inherit; line-height: 1;
}
.pl-ico:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
/* le icone inline non hanno width/height: senza questa regola prendono la
   dimensione predefinita degli SVG (300x150) e sfondano il pulsante */
.pl-ico svg { width: 18px; height: 18px; flex: 0 0 auto; }
.pl-bar .btn svg, .pl-foot .btn svg { width: 15px; height: 15px; flex: 0 0 auto; opacity: .75; }
.pl-ico[aria-pressed="true"], .pl-menu[open] > .pl-ico {
  color: var(--brand); border-color: var(--brand);
  background: var(--surface-2);
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
}
.pl-ico.pl-alert { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 50%, var(--border)); }
.pl-ico .pl-dot-bad {
  position: absolute; top: 3px; right: 3px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--bad); box-shadow: 0 0 0 2px var(--surface);
}

.pl-nav { display: flex; align-items: center; gap: 2px; }
.pl-week { font-weight: 700; font-size: .95rem; min-width: 9.4rem; text-align: center;
  letter-spacing: -.01em; }

/* dropdown accessibili da tastiera (details/summary nativi) */
.pl-menu { position: relative; }
.pl-menu > summary { list-style: none; cursor: pointer; }
.pl-menu > summary::-webkit-details-marker { display: none; }
.pl-menu > summary::marker { content: ''; }
.pl-pop {
  position: absolute; z-index: 60; top: calc(100% + 7px); left: 0;
  width: min(330px, 86vw); max-height: 72vh; overflow: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 14px;
}
.pl-pop-r { left: auto; right: 0; }
.pl-pop h4 { margin: 0 0 8px; font-size: .78rem; text-transform: uppercase;
  letter-spacing: .06em; color: var(--text-soft); font-weight: 700; }
.pl-pop form + h4 { margin-top: 16px; }
.pl-pop .field { margin-bottom: 10px; }
.pl-cur { display: inline-flex; align-items: center; gap: 7px; font-weight: 650;
  font-size: .87rem; margin-bottom: 12px; }
.pl-cur::before { content: '✓'; color: var(--brand); font-weight: 800; }

.pl-count {
  display: inline-grid; place-items: center; min-width: 21px; height: 21px; padding: 0 6px;
  border-radius: 999px; font-size: .74rem; font-weight: 750;
  background: var(--surface); color: var(--brand);
  background: color-mix(in srgb, var(--brand) 16%, var(--surface));
}
.pl-search { flex: 1 1 100%; }
.pl-search input { max-width: 340px; }
.pl-tot { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 6px 16px;
  border-top: 1px solid var(--border); padding-top: 9px; margin-top: 2px;
  font-size: .82rem; color: var(--text-soft); }
.pl-tot b { color: var(--text); font-weight: 700; }

/* ---- griglia ---- */
.planner {
  --pl-head: 58px;
  overflow: auto; -webkit-overflow-scrolling: touch;
  border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); max-height: calc(100vh - 250px); min-height: 280px;
}
.planner table { font-size: .85rem; border-collapse: separate; border-spacing: 0; }
.planner th, .planner td {
  vertical-align: top; padding: 6px; white-space: normal; text-align: left;
  border: 0; border-right: 1px solid var(--border); border-bottom: 1px solid var(--border);
  background: var(--surface); text-transform: none; letter-spacing: normal;
  color: var(--text); font-size: inherit;
}
.planner tr > *:last-child { border-right: 0; }
.planner tbody tr:hover { background: transparent; }

.planner thead .pl-head th { position: sticky; top: 0; z-index: 5; height: var(--pl-head); }
.planner thead .pl-costrow th { position: sticky; top: var(--pl-head); z-index: 4;
  background: var(--surface-2); }
.planner .col-emp {
  position: sticky; left: 0; z-index: 3; width: 206px; min-width: 206px;
  box-shadow: 1px 0 0 var(--border);
}
.planner thead .pl-head .col-emp { z-index: 7; background: var(--surface-2); }
.planner thead .pl-costrow .col-emp { z-index: 6; }
.pl-head .col-emp, .pl-costrow .col-emp { font-size: .74rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--text-soft); }

.pl-dname { display: inline-block; font-weight: 700; font-size: .86rem; padding: 2px 9px;
  border-radius: 999px; white-space: nowrap; }
.pl-dname.is-today { background: var(--brand); color: #fff; }
.pl-dstats { display: flex; gap: 10px; margin-top: 3px; padding-left: 3px;
  font-size: .72rem; color: var(--text-soft); white-space: nowrap; }
.pl-dstats span { display: inline-flex; align-items: center; gap: 3px; }
.pl-dstats svg { width: 12px; height: 12px; opacity: .8; }
.pl-cost { display: block; font-size: .72rem; color: var(--text-soft); white-space: nowrap; }
.pl-cost b { font-weight: 700; color: var(--text); }
.pl-cost + .pl-cost { margin-top: 1px; }

/* riga di intestazione reparto */
.planner .pl-dep > * { background: var(--surface-2); }
.pl-dep .pl-depname { font-weight: 750; font-size: .76rem; text-transform: uppercase;
  letter-spacing: .06em; }
.pl-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  background: var(--c, var(--brand)); margin-right: 7px; vertical-align: middle; }
.pl-deptot { display: flex; align-items: center; justify-content: flex-end; gap: 14px;
  font-size: .76rem; color: var(--text-soft); }
.pl-deptot b { color: var(--text); font-weight: 700; }
.pl-deptot .pl-depcount { margin-right: auto; }

/* colonna dipendente */
.pl-emp { display: flex; gap: 9px; align-items: flex-start; }
.pl-avatar {
  width: 33px; height: 33px; flex: 0 0 auto; border-radius: 50%;
  display: grid; place-items: center; font-size: .74rem; font-weight: 800;
  color: var(--text); background: var(--surface-2);
  background: color-mix(in srgb, var(--c, var(--brand)) 22%, var(--surface-2));
}
.pl-emp-txt { min-width: 0; }
.pl-emp-txt b { display: block; font-size: .87rem; font-weight: 650; line-height: 1.3; }
.pl-emp-role { display: block; font-size: .71rem; color: var(--text-soft); }
.pl-emp-tot { display: flex; flex-wrap: wrap; gap: 4px 9px; font-size: .74rem;
  color: var(--text-soft); font-variant-numeric: tabular-nums; }

/* Ore della settimana in tutti i reparti. Compare SOLO a chi ha più di una
   riga: lì il primo numero è le ore di quel reparto, e da solo si leggerebbe
   come se la persona lavorasse molto meno di quanto lavora. Con una riga sola
   i due numeri coinciderebbero, e ripeterli sarebbe rumore. */
.pl-emp-week { opacity: .8; }

/* Intervalli pronti sopra i campi data: «oggi» e «questa settimana» sono quasi
   tutto quello che si guarda, e aprire un calendario per arrivarci è caro
   soprattutto dal telefono. */
.periodi { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }

/* Il riassunto dei tentativi rifiutati: è un contorno della pagina, non il
   piatto. Un corpo più piccolo lo dice senza scriverlo, e soprattutto lo fa
   occupare meno spazio — era il motivo per cui arrivare alle timbrature da
   approvare voleva dire scorrere a lungo. */
.pf-riassunto table { font-size: .82rem; }
.pf-riassunto td, .pf-riassunto th { padding-top: 5px; padding-bottom: 5px; }
.pf-riassunto .field-hint { font-size: .72rem; }
.pl-emp-week::before { content: '·'; margin-right: 5px; opacity: .5; }

/* Riferimento contrattuale accanto alle ore pianificate.
   Neutro quando la settimana è in linea: la normalità non va colorata, o il
   colore smette di voler dire qualcosa.
   Sopra le ore settimanali si segna in grassetto ma SENZA colore d'allarme:
   qui lo straordinario si conta sul mese, quindi una settimana lunga seguita
   da una corta non è un errore. L'ambra è riservata allo sforamento mensile,
   che è l'unico che poi si paga. */
.pl-target { color: var(--text-soft); opacity: .75; font-variant-numeric: tabular-nums; }
.pl-target.is-over  { color: var(--text); opacity: 1; font-weight: 700; }
.pl-target.is-under { color: var(--text-soft); opacity: 1; }

/* Chi sfonda il monte ore del MESE: un filo lungo la riga, non un colore di
   fondo che coprirebbe i turni. */
.planner tr.is-overtime td.col-emp { box-shadow: inset 3px 0 0 var(--warn); }

.pl-otwarn { color: var(--warn); font-weight: 650; }

/* Elenco degli avvisi di conformità sopra la griglia. */
.pl-conf-lista { margin: 6px 0 6px 18px; padding: 0; }
.pl-conf-lista li { margin: 2px 0; }

/* celle e schede turno */
.planner td.pl-cell { position: relative; min-width: 130px; height: 68px; cursor: pointer; padding: 5px; }
.planner td.pl-cell:hover { background: color-mix(in srgb, var(--brand) 6%, var(--surface)); }
.planner .is-today-col { background: color-mix(in srgb, var(--brand) 4%, var(--surface)); }
.planner td.pl-cell.is-today-col:hover { background: color-mix(in srgb, var(--brand) 9%, var(--surface)); }

.sh {
  --c: var(--brand);
  display: block; width: 100%; margin: 0 0 4px; padding: 5px 8px;
  text-align: left; font-family: inherit; line-height: 1.32; cursor: pointer;
  border: 1px solid transparent; border-radius: 10px; color: var(--text);
  background: var(--surface-2);                                  /* fallback tinta piena */
  background: color-mix(in srgb, var(--c) 17%, var(--surface));  /* pastello leggibile */
}
.sh:hover { filter: brightness(1.04); box-shadow: var(--shadow); }
.sh:last-child { margin-bottom: 0; }
.sh-t { display: block; font-weight: 700; font-size: .79rem; font-variant-numeric: tabular-nums; }
.sh-s { display: block; font-size: .71rem; opacity: .7; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.sh-x { font-size: .68rem; font-weight: 600; opacity: .75; margin-left: 3px; }
.sh-b, .sh-w { display: none; }
.sh.is-draft { border-style: dashed; opacity: .84;
  border-color: var(--text-soft);
  border-color: color-mix(in srgb, var(--c) 45%, var(--text-soft)); }
.sh.is-draft .sh-b { display: inline-block; margin-top: 1px; font-size: .62rem; font-weight: 750;
  text-transform: uppercase; letter-spacing: .06em; opacity: .72; }
.sh.is-conflict { border-style: solid; border-color: var(--bad); opacity: 1; }
.sh.is-conflict .sh-w { display: inline; color: var(--bad); font-weight: 800; margin-left: 4px; }
/* Conformità: un filo ambra sul bordo sinistro, non un bordo intero.
   Il rosso pieno resta alle sovrapposizioni, che sono un errore vero; qui si
   sta segnalando un limite di legge su un turno che per il resto va bene. */
.sh.is-warn { box-shadow: inset 3px 0 0 var(--warn); }

.sh.is-flash { animation: shflash 1.4s ease; }
@keyframes shflash { 0%, 60% { box-shadow: 0 0 0 3px color-mix(in srgb, var(--bad) 45%, transparent); } }
@media (prefers-reduced-motion: reduce) { .sh.is-flash { animation: none; } }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .sh { background: color-mix(in srgb, var(--c) 32%, var(--surface)); }
  :root:not([data-theme="light"]) .pl-avatar { background: color-mix(in srgb, var(--c, var(--brand)) 34%, var(--surface-2)); }
}
:root[data-theme="dark"] .sh { background: color-mix(in srgb, var(--c) 32%, var(--surface)); }
:root[data-theme="dark"] .pl-avatar { background: color-mix(in srgb, var(--c, var(--brand)) 34%, var(--surface-2)); }

.pl-add-cell {
  position: absolute; inset: 0; margin: auto; width: 27px; height: 27px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer; font: inherit; font-size: 1rem;
  font-weight: 700; line-height: 1; opacity: 0; transition: opacity .12s ease;
  background: var(--surface-2); color: var(--brand);
  background: color-mix(in srgb, var(--brand) 14%, var(--surface));
}
td.pl-cell:hover .pl-add-cell, .pl-add-cell:focus { opacity: 1; }
@media (hover: none) { .pl-add-cell { opacity: .3; } }

/* Cella che ha già dei turni: il "+" non è più un cerchio al centro (starebbe
   sopra le schede) ma una striscia sotto l'ultima. Deve essere alta abbastanza
   da prenderla senza mirare: prima bisognava azzeccare i pochi pixel fra
   l'ultima scheda e il bordo, e un clic appena più su apriva la modifica. */
.pl-add-cell.is-under {
  position: static; inset: auto; margin: 5px 0 0; width: 100%; height: 22px;
  border-radius: 8px; opacity: 0;
  border: 1px dashed var(--border);
  background: transparent; color: var(--text-soft);
}
td.pl-cell:hover .pl-add-cell.is-under { opacity: 1; }
.pl-add-cell.is-under:hover {
  color: var(--brand); border-color: var(--brand);
  background: color-mix(in srgb, var(--brand) 10%, transparent);
}
@media (hover: none) { .pl-add-cell.is-under { opacity: .55; } }

/* ---- trascinamento dei turni ---- */
/* La scheda trascinabile lo dichiara col cursore; niente selezione del testo,
   altrimenti la pressione prolungata sul telefono seleziona l'orario invece di
   aprire il menu. */
.sh[draggable="true"] {
  cursor: grab;
  -webkit-user-select: none; user-select: none; -webkit-touch-callout: none;
}
.sh[draggable="true"]:active { cursor: grabbing; }
.sh.is-dragging { opacity: .34; }
/* "Taglia": il turno resta dov'è ma spento finché non lo si incolla altrove. */
.sh.is-cut { opacity: .42; border-style: dashed; border-color: var(--text-soft); }

/* Cella sotto il puntatore. Le celle fuori griglia non ricevono la classe,
   quindi non si illuminano mai. Verde = copia (Alt premuto), brand = sposta.
   Attenzione: .is-dnd sta sulla TABELLA (#planner-grid), non sul contenitore
   che scorre — il selettore deve dirlo, altrimenti l'evidenziazione non si
   vede pur essendoci la classe. */
.planner table.is-dnd td.pl-cell.is-drop {
  background: var(--surface-2);                                     /* fallback tinta piena */
  background: color-mix(in srgb, var(--brand) 20%, var(--surface));
  box-shadow: inset 0 0 0 2px var(--brand);
}
.planner table.is-dnd td.pl-cell.is-drop.is-copy {
  background: var(--surface-2);
  background: color-mix(in srgb, var(--ok) 22%, var(--surface));
  box-shadow: inset 0 0 0 2px var(--ok);
}
.pl-dndhint {
  position: fixed; left: 50%; bottom: 18px; transform: translateX(-50%);
  z-index: 210; max-width: min(560px, calc(100vw - 24px));
  padding: 8px 17px; border-radius: 999px; text-align: center;
  font-size: .82rem; font-weight: 600; pointer-events: none;
  background: var(--text); color: var(--bg); box-shadow: var(--shadow-lg);
}
.pl-dndhint.is-copy { background: var(--ok); color: #fff; }

/* ---- menu con il tasto destro ---- */
.pl-ctx {
  position: fixed; z-index: 300; min-width: 216px; padding: 6px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
}
.pl-ctx-h {
  padding: 5px 10px 8px; margin-bottom: 5px; max-width: 320px;
  font-size: .73rem; font-weight: 650; color: var(--text-soft);
  border-bottom: 1px solid var(--border);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pl-ctx button {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 7px 10px; border: 0; border-radius: 8px; cursor: pointer;
  font: inherit; font-size: .87rem; text-align: left;
  color: var(--text); background: transparent;
}
.pl-ctx button:hover:not(:disabled), .pl-ctx button:focus { background: var(--surface-2); }
.pl-ctx button:disabled { opacity: .42; cursor: default; }
.pl-ctx button.is-bad { color: var(--bad); }
.pl-ctx button > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-ctx kbd {
  margin-left: auto; flex: 0 0 auto; font: inherit; font-size: .72rem;
  color: var(--text-soft); white-space: nowrap;
}
/* Su telefono e tablet la tastiera non c'è: le scorciatoie sono solo rumore. */
@media (hover: none) { .pl-ctx kbd { display: none; } }

/* ---- avviso di eliminazione con "Annulla" ---- */
.pl-undo {
  position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%);
  z-index: 210; display: flex; align-items: center; gap: 14px;
  max-width: min(680px, calc(100vw - 24px));
  padding: 9px 10px 9px 20px; border-radius: 999px;
  font-size: .88rem; font-weight: 600;
  background: var(--text); color: var(--bg); box-shadow: var(--shadow-lg);
  animation: toastin .25s ease;
}
.pl-undo > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-undo button {
  flex: 0 0 auto; padding: 5px 15px; border-radius: 999px; cursor: pointer;
  font: inherit; font-size: .84rem; font-weight: 750;
  color: inherit; background: transparent; border: 1px solid currentColor;
}
.pl-undo button:hover:not(:disabled) { background: var(--bg); color: var(--text); }
.pl-undo button:disabled { opacity: .5; cursor: default; }
@media (prefers-reduced-motion: reduce) { .pl-undo { animation: none; } }

/* densità compatta */
.planner.is-compact td.pl-cell { height: 44px; }
.planner.is-compact .sh { padding: 3px 7px; }
.planner.is-compact .sh-s, .planner.is-compact .sh-b,
.planner.is-compact .pl-emp-role, .planner.is-compact .pl-dstats { display: none; }
.planner.is-compact .pl-avatar { width: 26px; height: 26px; font-size: .66rem; }
.planner.is-compact { --pl-head: 44px; }

.pl-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 12px; }

/* ---- modale turno ---- */
.m-head { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.m-tpl { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.tpl-pill {
  --c: var(--brand);
  border: 1px solid transparent; border-radius: 999px; padding: 5px 11px;
  font: inherit; font-size: .78rem; font-weight: 650; cursor: pointer; color: var(--text);
  background: var(--surface-2);
  background: color-mix(in srgb, var(--c) 18%, var(--surface));
}
.tpl-pill:hover { filter: brightness(1.05); }
.tpl-pill i { font-style: normal; font-weight: 500; opacity: .72; margin-left: 5px; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .tpl-pill { background: color-mix(in srgb, var(--c) 34%, var(--surface)); }
}
:root[data-theme="dark"] .tpl-pill { background: color-mix(in srgb, var(--c) 34%, var(--surface)); }
.m-dur { font-size: .85rem; font-weight: 650; margin: 0 0 12px; }
.m-dur.is-bad { color: var(--bad); }
.m-actions { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; margin-top: 4px; }
.m-actions .m-del { margin-right: auto; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (max-width: 720px) {
  .pl-week { min-width: 7.6rem; font-size: .88rem; }
  .planner { max-height: none; }
  .planner .col-emp { width: 160px; min-width: 160px; }
}
@media print {
  .planner { max-height: none; overflow: visible; border-color: #ccc; }
  .pl-add-cell, .pl-bar { display: none !important; }
}

/* ---------------------------------------------------------------- misc */
.map { width: 100%; height: 330px; border-radius: var(--radius-sm);
  border: 1px solid var(--border); }
.avatar { width: 38px; height: 38px; border-radius: 50%; object-fit: cover;
  background: var(--surface-2); display: grid; place-items: center;
  font-weight: 700; color: var(--text-soft); font-size: .82rem; flex: 0 0 auto; }
.empty { text-align: center; padding: 34px 16px; color: var(--text-soft); }
.empty-ico { font-size: 2.4rem; opacity: .45; display: block; margin-bottom: 8px; }
.toast {
  position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%);
  background: var(--text); color: var(--bg); padding: 12px 20px; border-radius: 999px;
  font-weight: 600; font-size: .9rem; z-index: 200; box-shadow: var(--shadow-lg);
  animation: toastin .25s ease;
}
@keyframes toastin { from { opacity: 0; transform: translate(-50%, 12px); } }
.divider { height: 1px; background: var(--border); margin: 16px 0; border: 0; }
.tag-list { display: flex; gap: 6px; flex-wrap: wrap; }
.right { text-align: right; }

/* ------------------------------------------------------------ formazione */
/* I trofei: un percorso completato è una piccola conquista, e mostrarla in
   modo che si veda è ciò che spinge a finire anche l'ultima lezione. */
.trofei { display: flex; flex-wrap: wrap; gap: 12px; }
.trofeo {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  width: 108px; padding: 12px 8px; text-align: center;
  border-radius: var(--radius); border: 1px solid var(--border);
  background: color-mix(in srgb, var(--c, var(--brand)) 9%, var(--surface));
}
.trofeo-txt { font-size: .78rem; font-weight: 650; line-height: 1.25; }
.trofeo small { font-size: .68rem; color: var(--text-soft); }
.trofeo-ico {
  display: inline-grid; place-items: center; width: 40px; height: 40px;
  border-radius: 50%; font-size: 1.35rem; line-height: 1;
  background: color-mix(in srgb, var(--c, var(--brand)) 22%, var(--surface));
  border: 2px solid var(--c, var(--brand));
}

/* Barra di avanzamento: dice "ci sei quasi" meglio di un elenco di spunte. */
.avanzamento {
  height: 8px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; margin: 10px 0 2px;
}
.avanzamento > span { display: block; height: 100%; border-radius: 999px;
  background: var(--brand); transition: width .3s ease; }

/* Elenco delle lezioni */
.lezioni { display: flex; flex-direction: column; gap: 6px; }
.lez {
  display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  background: var(--surface); color: var(--text);
}
a.lez:hover { text-decoration: none; border-color: var(--brand); }
.lez-ico { width: 22px; text-align: center; font-weight: 800; color: var(--text-soft); }
.lez-completata { background: color-mix(in srgb, var(--ok) 8%, var(--surface)); }
.lez-completata .lez-ico { color: var(--ok); }
.lez-in_corso { border-color: var(--brand); }
.lez-in_corso .lez-ico { color: var(--brand); }
.lez-bloccata { opacity: .5; }
.lez-qui { outline: 2px solid var(--brand); outline-offset: 1px; }

.lez-video { width: 100%; max-height: 62vh; border-radius: var(--radius-sm);
  background: #000; display: block; }
.lez-testo { line-height: 1.65; }

/* Immagine allegata a un avviso della bacheca: si vede subito, e resta
   cliccabile per aprirla a dimensione piena. L'altezza massima serve a non
   far sparire il resto dell'avviso sotto a una foto verticale. */
.board-img { display: block; }
.board-img img {
  display: block; max-width: 100%; max-height: 420px;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  object-fit: contain; background: var(--surface-2);
}
.board-img:hover img { border-color: var(--brand); }

/* Riquadro spento: i browser scoloriscono i campi ma lasciano nere etichette e
   legenda, e a colpo d'occhio sembra ancora attivo. */
fieldset[disabled] { opacity: .5; }

/* Sezione che si apre con un clic: serve a tenere fuori dalla vista i dati che
   non devono comparire solo perché si è scesi con la pagina (la retribuzione
   nella scheda del dipendente). È un <details>, quindi funziona anche senza JS
   e la tastiera lo apre da sola. */
.reveal > summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.reveal > summary::-webkit-details-marker { display: none; }
.reveal > summary::after {
  content: '+'; margin-left: auto; color: var(--text-soft);
  font-size: 1.1rem; line-height: 1;
}
.reveal[open] > summary::after { content: '–'; }
.reveal > summary:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 6px; }
.reveal-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.05rem; letter-spacing: -.01em;
}
.reveal-hint { color: var(--text-soft); font-size: .8rem; }
.reveal[open] .reveal-hint { display: none; }
.reveal-body { margin-top: 16px; }

/* Comando da copiare (istruzioni per il cron): va selezionato per intero anche
   da telefono, quindi scorre in orizzontale invece di andare a capo. */
.code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .84rem; line-height: 1.5;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px; margin: 6px 0 14px;
  overflow-x: auto; white-space: pre; user-select: all;
}

/* --------------------------------------------------------------- print */
@media print {
  .topbar, .tabbar, .no-print, .btn { display: none !important; }
  body { background: #fff; color: #000; font-size: 12px; }
  .wrap { max-width: none; padding: 0; }
  .card { box-shadow: none; border: 1px solid #ccc; break-inside: avoid; }
  table { font-size: 11px; }
  th { background: #eee !important; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
  .print-head { display: block !important; margin-bottom: 14px; }
}
.print-head { display: none; }

/* ---------------------------------------------- invito all'installazione */
/* Striscia in basso, sopra la barra delle sezioni del dipendente. Compare
   qualche secondo dopo l'apertura: chi arriva per timbrare deve trovare il
   pulsante, non un invito davanti. */
.tc-installa {
  position: fixed; left: 12px; right: 12px; z-index: 60;
  bottom: calc(72px + env(safe-area-inset-bottom));
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 12px 14px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  animation: tc-sale .28s cubic-bezier(.2,.8,.3,1);
}
@keyframes tc-sale { from { transform: translateY(14px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tc-installa { animation: none; } }
.tc-installa-txt { flex: 1 1 12rem; min-width: 0; line-height: 1.35; }
.tc-installa-txt b { display: block; font-size: .95rem; }
.tc-installa-txt span { font-size: .82rem; color: var(--text-soft); }
.tc-installa-btn { display: flex; gap: 8px; margin-left: auto; }
.tc-installa-btn button {
  font: inherit; font-size: .87rem; font-weight: 650; cursor: pointer;
  border-radius: 999px; padding: 9px 16px; min-height: 40px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text);
}
.tc-installa-btn [data-si] { background: var(--brand); border-color: var(--brand); color: #fff; }

/* I due passi da fare su iPhone, dentro la finestra. */
.tc-passi { margin: 10px 0 14px; padding-left: 1.3rem; }
.tc-passi li { margin: 8px 0; }
.tc-ico-share {
  font-size: 1.1em; vertical-align: -.1em;
  color: var(--brand);
}

/* Comando delle notifiche nella scheda personale. */
.tc-notif-stato { font-weight: 650; }
.tc-notif-stato.on  { color: var(--ok); }
.tc-notif-stato.off { color: var(--text-soft); }

/* Certificato allegato a un'assenza: due comandi piccoli sotto la nota. */
.cert-riga { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 6px; }
.cert-form { display: inline; }
.cert-form label.btn { margin: 0; cursor: pointer; }

/* ===================================================== LA CORSA ============
   Il gioco della puntualità. È l'unica pagina dell'applicazione con un mondo
   visivo suo — sala giochi anni ottanta — e va bene così: è l'unica che deve
   far venire voglia di aprirla. Tutto il resto dell'app resta com'è. */
.gara-testa{display:flex; flex-wrap:wrap; align-items:baseline; gap:8px 14px}
.gara-sede{font-size:.72rem; letter-spacing:.09em; color:var(--text-soft); font-weight:700}
.gara-occhiello{max-width:62ch; margin-top:6px}

.gara-tabellone{display:flex; flex-wrap:wrap; gap:10px 26px; align-items:flex-end;
  padding:14px 16px; margin-top:18px; background:#0b3a85; border:3px solid #08285e;
  border-bottom:none; color:#eef4ff; font-variant-numeric:tabular-nums}
.gara-tabellone .voce{font-size:.66rem; letter-spacing:.08em; font-weight:800; line-height:1.5}
.gara-tabellone b{display:block; font-size:1.5rem; color:#f5c518; margin-top:4px}
.gara-tabellone small{font-size:.8rem; opacity:.7}
.gara-tabellone .avanti b{color:#8ce06a}
.gara-tabellone .dietro b{color:#ffb4a6}

/* TELECAMERA, NON RIMPICCIOLIMENTO.
   Sul telefono in verticale ci sono ~360 px: una gara orizzontale ci starebbe
   solo schiacciata, coi due cavalli appiccicati e il distacco — l'unica cosa da
   leggere — invisibile. Il mondo resta largo e la finestra lo segue, come nei
   giochi dell'epoca. Zoomando la scena diventa anche più alta, e la corsa torna
   a essere la protagonista dello schermo invece di una striscia. */
.gara-visore{position:relative; overflow:hidden; border:3px solid #08285e; background:#1259c4}
.gara-mondo{position:relative; width:var(--mondo,100%); line-height:0;
  transform:translateX(var(--cam,0px)); transition:transform .6s ease-out}
.gara-mondo>img{width:100%; height:auto; display:block; image-rendering:pixelated}
.gara-corsia{position:absolute; left:0; right:0; height:0}
.gara-corsia--noi{bottom:23%}
.gara-corsia--ghost{bottom:33%}

.gara-corridore{position:absolute; bottom:0; transform:translateX(-50%);
  animation:gara-entra 2.4s cubic-bezier(.22,.9,.3,1) both}
.gara-corridore--noi{width:11%}
.gara-corridore--ghost{width:9.4%; opacity:.42; filter:grayscale(1) brightness(1.5)}
.gara-cavallo{width:100%; aspect-ratio:233/150; background-image:var(--sprite);
  background-repeat:no-repeat; background-size:400% 100%; image-rendering:pixelated;
  animation:gara-galoppo .46s steps(4) infinite}
.gara-corridore--ghost .gara-cavallo{animation-duration:.58s}
/* Il foglio è largo quattro volte il cavallo. ATTENZIONE AL FONDO SCALA:
   steps(4) si ferma sempre un passo prima della fine, quindi arrivando al 100%
   i passi cadrebbero su 0, 25, 50 e 75 per cento — in mezzo ai fotogrammi, e si
   vedrebbe mezzo cavallo attaccato a mezzo cavallo. Col 133,33% cadono su
   0, 33, 67 e 100: i fotogrammi veri. */
@keyframes gara-galoppo{from{background-position-x:0%} to{background-position-x:133.3333%}}
@keyframes gara-entra{from{left:3%} to{left:var(--pos)}}

.gara-traguardo{position:absolute; top:8%; bottom:14%; width:.7%; min-width:5px;
  background:repeating-linear-gradient(180deg,#fff 0 8px,#111 8px 16px);
  box-shadow:0 0 0 2px rgba(0,0,0,.45)}
.gara-traguardo span{position:absolute; bottom:calc(100% + 6px); left:50%;
  transform:translateX(-50%); white-space:nowrap; font-size:.6rem; font-weight:800;
  letter-spacing:.06em; color:#fff; background:#111; padding:4px 6px; border:2px solid #fff}
.gara-etichetta{position:absolute; left:50%; bottom:100%; margin-bottom:6px;
  transform:translateX(-50%); white-space:nowrap; font-size:.6rem; font-weight:800;
  letter-spacing:.06em; padding:4px 6px; border:2px solid #000}
.gara-etichetta--noi{background:#f5c518; color:#241a00}
.gara-etichetta--ghost{background:#2b3547; color:#e6ecf6; border-color:#0d1420}

/* Inquadrando da vicino il traguardo esce dal campo: senza un secondo
   riferimento non si capirebbe più a che punto del mese si è. */
.gara-mappina{display:none; align-items:center; gap:10px; padding:10px 16px;
  background:#0b2246; border:3px solid #08285e; border-top:none;
  font-size:.62rem; font-weight:800; letter-spacing:.08em; color:#9fb3d4}
.gara-stretta .gara-mappina{display:flex}
.gara-mappina .barra{position:relative; flex:1; height:12px; background:#08285e; border:2px solid #061a3d}
.gara-mappina .barra i{position:absolute; top:0; bottom:0; left:0; display:block}
.gara-mappina .barra .noi{background:#f5c518; width:var(--q-noi)}
.gara-mappina .barra .ghost{background:#6f7f99; width:var(--q-ghost); opacity:.8}
.gara-didascalia{font-size:.86rem; color:var(--text-soft); margin-top:10px; max-width:64ch}

.gara-h2{margin:34px 0 2px; font-size:1.05rem}
.gara-sotto{color:var(--text-soft); font-size:.9rem; margin:0 0 14px; max-width:64ch}

.gara-privata{display:grid; grid-template-columns:repeat(auto-fit,minmax(210px,1fr)); gap:12px}
.gara-riquadro{background:var(--surface-2); border:1px solid var(--border);
  border-radius:var(--radius-sm); padding:16px 18px}
.gara-riquadro .etich{font-size:.64rem; letter-spacing:.09em; font-weight:800; color:var(--text-soft)}
.gara-riquadro .num{font-size:2rem; font-weight:800; margin-top:8px; font-variant-numeric:tabular-nums}
.gara-riquadro .num.su{color:var(--ok)}
.gara-riquadro .num small{font-size:1rem; color:var(--text-soft); font-weight:600}
.gara-riquadro .nota{font-size:.84rem; color:var(--text-soft); margin-top:8px; line-height:1.5}
.gara-riquadro .nota .mese{display:block; margin-top:6px; font-size:.78rem; opacity:.75}
.gara-riquadro .serie{display:flex; gap:3px; margin-top:10px; flex-wrap:wrap}
.gara-riquadro .serie i{width:11px; height:11px; background:var(--ok); display:block}
.gara-riquadro .serie i.no{background:var(--border)}

.gara-podio{list-style:none; padding:0; margin:0; display:grid; gap:6px; max-width:520px}
.gara-podio li{display:flex; align-items:center; gap:12px; padding:11px 14px;
  background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm)}
.gara-podio .pos{width:26px; height:26px; display:grid; place-items:center; flex:none;
  border-radius:50%; font-weight:800; font-size:.8rem; background:var(--border); color:var(--text)}
.gara-podio .p1 .pos{background:#f5c518; color:#241a00}
.gara-podio .p2 .pos{background:#cbd3dd; color:#1b2430}
.gara-podio .p3 .pos{background:#d8a06a; color:#2a1808}
.gara-podio .chi{flex:1; font-weight:600}
.gara-podio .val{font-variant-numeric:tabular-nums; color:var(--text-soft); font-weight:700}

.gara-medaglie{display:grid; grid-template-columns:repeat(auto-fit,minmax(170px,1fr)); gap:16px}
.gara-medaglia{text-align:center}
.gara-medaglia img{width:82px; height:82px; image-rendering:pixelated}
.gara-medaglia.vuota img{filter:grayscale(1); opacity:.35}
.gara-medaglia h3{font-size:.9rem; margin:8px 0 4px}
.gara-medaglia .chi{font-size:.84rem; font-weight:700; color:var(--ok); margin:0}
.gara-medaglia .regola{font-size:.8rem; color:var(--text-soft); margin:0; line-height:1.45}

.gara-uscita{display:flex; flex-wrap:wrap; align-items:center; gap:10px 14px; margin-top:36px;
  padding-top:18px; border-top:1px solid var(--border); font-size:.84rem}

@media (prefers-reduced-motion:reduce){
  .gara-cavallo{animation:none}
  .gara-corridore{animation:none; left:var(--pos)}
  .gara-mondo{transition:none}
}
@media (max-width:560px){
  .gara-tabellone{display:grid; grid-template-columns:1fr 1fr; gap:12px 14px}
  .gara-tabellone b{font-size:1.25rem}
  .gara-tabellone .voce:last-child{grid-column:1 / -1}
  .gara-medaglie{grid-template-columns:1fr 1fr; gap:14px}
  .gara-medaglia img{width:62px; height:62px}
  .gara-privata{grid-template-columns:1fr}
  .gara-etichetta,.gara-traguardo span{font-size:.52rem; padding:3px 4px}
}
.gara-scelta{display:flex; flex-wrap:wrap; gap:8px; margin:12px 0 4px}
.gara-scelta select{width:auto; min-width:150px}

/* I trofei già vinti: piccoli, in riga per mese. Non sono la parte principale
   della pagina — sono la memoria di quello che è già successo. */
.gara-trofei{display:grid; gap:8px; max-width:520px}
.gara-mese-trofei{display:flex; align-items:center; gap:12px; padding:9px 12px;
  background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm)}
.gara-mese-trofei .quando{flex:1; font-size:.86rem; font-weight:600; text-transform:capitalize}
.gara-mese-trofei .pezzi{display:flex; gap:6px}
.gara-mese-trofei img{image-rendering:pixelated}

/* L'ALBO D'ORO — chi ha vinto cosa, e quante volte.
   Il moltiplicatore è la ragione per cui esiste: quattro righe «In orario» una
   sotto l'altra si leggono come rumore, «In orario ×4» si legge come un record. */
.gara-albo{list-style:none; padding:0; margin:0; display:grid; gap:6px; max-width:560px}
.gara-albo li{display:flex; align-items:center; gap:12px; padding:9px 12px;
  background:var(--surface-2); border:1px solid var(--border); border-radius:var(--radius-sm)}
.gara-albo .chi{flex:1; font-weight:600; font-size:.92rem}
.gara-albo .pezzi{display:flex; align-items:center; gap:10px; flex-wrap:wrap}
.gara-albo .pezzo{display:inline-flex; align-items:center; gap:3px}
.gara-albo .pezzo img{image-rendering:pixelated}
.gara-albo .pezzo b{font-size:.78rem; font-weight:800; color:var(--text-soft);
  font-variant-numeric:tabular-nums}
