/* Staff self-service portal — mobile-first, distinct from the admin dashboard.
   Base styles target phones; larger screens get a max-width centered column,
   not a different layout, since this is meant to be used on-site on a phone.

   Palette lifted straight from the SUBA mark itself (static/brand/gites-de-
   bretagne-*.svg: navy #172B3A ink, cream #F8F6F0 ground, sea-blue #2F6F8F)
   rather than the old unrelated green — so the portal reads as the same
   brand as the icon in its own header, not a generic app shell. */

:root {
  --s-bg: #f8f6f0;
  --s-card: #ffffff;
  --s-border: #e2ddd0;
  --s-text: #172b3a;
  --s-muted: #56636f; /* was #75806f (4.14:1 on white — under WCAG AA's 4.5:1 for
                          normal text); this hits ~6.2:1 */
  --s-accent: #172b3a;
  --s-accent-2: #2f6f8f; /* the coastline blue from the icon's sea/lighthouse scene */
  --s-accent-ink: #0d1b26;
  --s-alert: #b3261e;
  --s-alert-bg: #fbe7e5;
  /* La grille : la hachure du réservé, le lavis du créneau libre, et les deux
     états du ménage. Le lavis reste assez clair pour ne pas concurrencer le
     marqueur qu'il porte. */
  --s-stone: #eee8dc;
  --s-booked: #b8a880;
  --s-gap-wash: #fdf7ea;
  --s-needed: #b8801f;
  --s-done: #2f6f8f;
}

* { box-sizing: border-box; }

.staff-body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  background: var(--s-bg);
  color: var(--s-text);
  line-height: 1.5;
}

.staff-header {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--s-accent);
  color: #fff;
  padding: 0.9rem 1rem;
  display: flex;
  align-items: center;
  gap: 0.8rem;
}
.staff-back {
  flex: none;
  color: #fff; text-decoration: none; font-size: 0.95rem; opacity: 0.9;
  background: none; border: 0; padding: 0; font-family: inherit; cursor: pointer;
}
.staff-brand {
  font-weight: 700; font-size: 1.1rem; display: flex; align-items: center; gap: 0.5rem;
  min-width: 0; /* lets the text child actually shrink/truncate inside this flex item */
  flex: 1 1 auto;
}
.staff-brand-logo { height: 24px; width: auto; flex: none; }
/* Page titles (e.g. "Signaler un point d'attention") used to wrap onto 2-3
   lines once a back link and the logout button both share the header row —
   one line with an ellipsis reads as a title bar, not a paragraph. */
.staff-brand-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Sole purpose: end the session. No shared-tablet "switch user" concept —
   just a plain disconnect, pinned to the far right of the header. */
.staff-logout-form { flex: none; margin: 0 0 0 auto; }
.staff-logout {
  color: #fff; text-decoration: none; font-size: 0.88rem; opacity: 0.85;
  background: none; border: 1px solid rgba(255, 255, 255, 0.4); border-radius: 999px;
  padding: 0.35rem 0.8rem; font-family: inherit; cursor: pointer;
}
.staff-logout:hover { opacity: 1; background: rgba(255, 255, 255, 0.1); }

.staff-main {
  max-width: 640px;
  margin: 0 auto;
  padding: 1rem 1rem 3rem;
}

.staff-intro { color: var(--s-muted); margin: 0.5rem 0 1.2rem; }
.staff-hint { color: var(--s-muted); font-size: 0.88rem; }
.staff-muted { color: var(--s-muted); }
.staff-empty { color: var(--s-muted); font-style: italic; }

.staff-login { margin-top: 1.5rem; color: var(--s-muted); font-size: 0.9rem; }
.staff-login summary { cursor: pointer; }
.staff-login-form { display: flex; gap: 0.5rem; margin-top: 0.6rem; }
.staff-login-form input { flex: 1; min-width: 0; }

/* Staff picker (home) */
.staff-picker {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.8rem;
}
/* One <form> per staff member, POSTing straight to /auth/magic-link with
   their own email as a hidden field — picking your name IS "send me my
   link", no typing required now that every active row has an address (see
   staff_list.html). The form itself carries the card's layout/spacing; the
   button inside is reset to fill it edge-to-edge like the <a> it replaces. */
.staff-pick-card {
  margin: 0;
}
.staff-pick-card-btn {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.2rem;
  width: 100%;
  background: var(--s-card);
  border: 1px solid var(--s-border);
  border-radius: 12px;
  padding: 1.1rem 1.2rem;
  text-decoration: none;
  color: var(--s-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.staff-pick-name { font-size: 1.15rem; font-weight: 700; }
.staff-pick-role { color: var(--s-muted); font-size: 0.9rem; }

/* Landing page (/personnel/{id}) — "today first": a hero card answers the
   single most time-sensitive question (what needs cleaning today) before
   anything else, an alert strip surfaces open reports/interventions at
   their own visual weight instead of buried in a flat list, and everything
   routine collapses into a compact tile grid rather than a tall single
   column. See staff_profile.html. */
.staff-hero {
  background: var(--s-accent-ink);
  background-image: linear-gradient(155deg, var(--s-accent) 0%, var(--s-accent-ink) 100%);
  color: #fff;
  border-radius: 16px;
  padding: 1.25rem 1.3rem 1.4rem;
  margin-bottom: 0.9rem;
}
.staff-hero-eyebrow { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.06em; opacity: 0.75; }
.staff-hero-count { font-size: 2.4rem; font-weight: 800; font-variant-numeric: tabular-nums; line-height: 1.1; margin-top: 0.15rem; }
.staff-hero-label { font-size: 1rem; opacity: 0.92; margin-top: 0.1rem; }
.staff-hero-list { list-style: none; margin: 0.9rem 0 0; padding: 0; display: flex; flex-direction: column; gap: 0.4rem; }
.staff-hero-list li {
  display: flex; align-items: center; gap: 0.55rem;
  font-size: 0.92rem; background: rgba(255, 255, 255, 0.12); border-radius: 8px; padding: 0.5rem 0.65rem;
}
.staff-hero-dot { width: 6px; height: 6px; border-radius: 50%; background: #fff; opacity: 0.8; flex: none; }
.staff-hero-cta {
  display: inline-flex; align-items: center; gap: 0.4rem;
  margin-top: 1rem; color: #fff; text-decoration: none; font-weight: 600; font-size: 0.92rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}

.staff-alerts { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 0.9rem; }
.staff-alert-card {
  display: flex; align-items: center; gap: 0.8rem;
  background: var(--s-alert-bg); border: 1px solid #f2c6c2; border-radius: 12px;
  padding: 0.85rem 1rem; text-decoration: none; color: var(--s-text);
}
.staff-alert-icon {
  flex: none; width: 2.3rem; height: 2.3rem; border-radius: 50%;
  background: #fff; color: var(--s-alert); display: flex; align-items: center; justify-content: center;
  font-size: 1rem;
}
.staff-alert-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 0.1rem; }
.staff-alert-title { font-weight: 700; font-size: 0.96rem; }
.staff-alert-sub { font-size: 0.83rem; color: var(--s-muted); }
.staff-alert-arrow { color: var(--s-alert); font-weight: 700; }

.staff-grid-label { font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--s-muted); margin: 1.1rem 0 0.6rem; }
.staff-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; }
.staff-tile {
  background: var(--s-card); border: 1px solid var(--s-border); border-radius: 14px;
  padding: 0.95rem 1rem; text-decoration: none; color: var(--s-text);
  display: flex; flex-direction: column; gap: 0.55rem;
  box-shadow: 0 1px 2px rgba(23, 43, 58, 0.04);
  position: relative;
}
.staff-tile:active { background: var(--s-bg); }
.staff-tile-icon {
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  background: var(--s-bg); color: var(--s-accent);
  display: flex; align-items: center; justify-content: center; font-size: 1.1rem;
}
.staff-tile-label { font-weight: 700; font-size: 0.96rem; }
.staff-tile-sub { font-size: 0.79rem; color: var(--s-muted); }
.staff-tile-badge {
  position: absolute; top: 0.8rem; right: 0.8rem;
  min-width: 1.5rem; height: 1.5rem; padding: 0 0.35rem; border-radius: 999px;
  background: var(--s-accent); color: #fff; font-size: 0.78rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.staff-tile-badge-muted { background: var(--s-muted); }

/* Cards */
.staff-card {
  background: var(--s-card);
  border: 1px solid var(--s-border);
  border-radius: 12px;
  padding: 1.1rem 1.2rem;
  margin-bottom: 1rem;
}
.staff-card h2 { margin: 0 0 0.8rem; font-size: 1.05rem; color: var(--s-accent); }

/* Forms — big touch targets */
.staff-form { display: flex; flex-direction: column; gap: 0.9rem; }
.staff-form label { display: flex; flex-direction: column; gap: 0.35rem; font-size: 0.92rem; font-weight: 600; }
.staff-form input, .staff-form select, .staff-form textarea {
  font-size: 1rem;
  padding: 0.7rem 0.8rem;
  border: 1px solid var(--s-border);
  border-radius: 8px;
  background: #fff;
  font-family: inherit;
  width: 100%;
}
.staff-btn {
  margin-top: 0.3rem;
  padding: 0.85rem 1rem;
  background: var(--s-accent);
  color: #fff;
  border: none;
  border-radius: 10px;
  font-size: 1.02rem;
  font-weight: 600;
  cursor: pointer;
}
.staff-btn-alert { background: var(--s-alert); }

/* Property grid — small pictures, responsive */
.staff-property-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.7rem;
}
.staff-property-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--s-border);
  border-radius: 10px;
  overflow: hidden;
  text-decoration: none;
  color: var(--s-text);
  background: #fff;
}
.staff-property-thumb {
  display: block;
  height: 80px;
  background-size: cover;
  background-position: center;
  background-color: var(--s-border);
}
.staff-property-name {
  padding: 0.5rem 0.6rem;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.25;
}

/* Tables (recent entries) — one card per row, since this portal is used on
   a phone by definition (see the file header). The previous treatment was
   `display: block; overflow-x: auto` with `white-space: nowrap` on every
   cell, i.e. a horizontally-scrolling strip: the worst case on the exact
   device this portal targets. Base styles here are the card layout; the
   real table only reassembles itself at 720px, the same breakpoint the
   rest of this file uses to widen the column.

   Mirrors .table-cards in the desk/owner design.css — same data-label
   contract, same .cell-primary marker — but written against the --s-*
   tokens rather than importing that file, which staff.css deliberately
   does not load. */
/* The templates already wrap these in .table-wrap, but staff.css never
   defined it — the overflow used to live on .staff-table itself. */
.table-wrap { overflow-x: auto; margin: 0.5rem 0; }
.table-wrap table { margin: 0; }
.staff-table { width: 100%; border-collapse: collapse; font-size: 0.85rem; }
.staff-table th, .staff-table td { padding: 0.5rem 0.6rem; border-bottom: 1px solid var(--s-border); text-align: left; }
.staff-table th { color: var(--s-muted); font-weight: 600; }

@media (max-width: 719px) {
  .staff-table, .staff-table tbody, .staff-table tr, .staff-table td { display: block; width: 100%; }
  .staff-table thead { display: none; }
  .staff-table tr {
    border: 1px solid var(--s-border);
    border-radius: 12px;
    background: var(--s-card);
    padding: 0.7rem 0.9rem;
    margin-bottom: 0.7rem;
  }
  .staff-table td {
    border: none;
    padding: 0.28rem 0;
    display: flex;
    /* See .table-cards in the desk/owner design.css for why this wraps. */
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.15rem 0.9rem;
    text-align: left;
    overflow-wrap: anywhere;
  }
  .staff-table td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    flex: 0 0 auto;
    text-align: left;
    color: var(--s-muted);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }
  .staff-table td.cell-primary {
    display: block;
    text-align: left;
    font-size: 1rem;
    font-weight: 600;
    padding: 0 0 0.45rem;
    margin-bottom: 0.35rem;
    border-bottom: 1px solid var(--s-border);
  }
  .staff-table td.cell-primary::before { display: none; }
  .staff-table td.cell-block { display: block; text-align: left; }
  .staff-table td.cell-block[data-label]:not([data-label=""])::before {
    display: block;
    margin-bottom: 0.15rem;
  }

  /* Last in the block on purpose — see the same rule in design.css. */
  .staff-table td:empty { display: none; }
}

.staff-badge { display: inline-block; padding: 0.15rem 0.55rem; border-radius: 999px; font-size: 0.75rem; font-weight: 600; }
.staff-badge-open { background: var(--s-alert-bg); color: var(--s-alert); }
.staff-badge-done { background: #e5f6ec; color: var(--s-accent); }
.staff-badge-today { background: var(--s-accent); color: #fff; }
.staff-badge-alert { background: var(--s-alert-bg); color: var(--s-alert); }

/* Cleaning agenda (day-by-day, mobile-first) */
.staff-agenda-day { margin-bottom: 1.3rem; }
.staff-agenda-date {
  margin: 0 0 0.6rem;
  font-size: 1rem;
  font-weight: 700;
  color: var(--s-text);
  display: flex;
  align-items: center;
  gap: 0.5rem;
  text-transform: capitalize;
}
.staff-agenda-entry { margin-bottom: 0.7rem; }
.staff-agenda-entry-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.3rem;
}
.staff-agenda-prop { font-size: 1.05rem; font-weight: 700; }
.staff-agenda-address { margin: 0.2rem 0; font-size: 0.88rem; }
/* L'affectation, au pied de la carte de la journée.
   Séparée du reste par un filet : au-dessus on lit ce qu'il y a à faire, en
   dessous on agit. Les deux tenaient sur deux pages avant de tenir ici. */
.staff-assignee,
.staff-assign-form {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.7rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--s-border);
}
.staff-assignee { font-size: 0.92rem; font-weight: 600; color: var(--s-muted); }
.staff-assignee-mine { color: var(--s-accent-2); }
.staff-assignee-none {
  margin: 0.7rem 0 0;
  padding-top: 0.7rem;
  border-top: 1px solid var(--s-border);
  font-style: italic;
}
.staff-assign-label { font-size: 0.92rem; font-weight: 600; }
.staff-assign-select {
  flex: 1 1 8rem;
  min-height: 44px; /* la cible tactile du portail : il s'utilise debout, dans un gîte */
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--s-border);
  border-radius: 8px;
  background: var(--s-card);
  color: var(--s-text);
  font: inherit;
}
.staff-assign-form .staff-btn { min-height: 44px; }
.staff-intro-alert { color: var(--s-alert); }

.staff-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.5rem;
  color: var(--s-accent);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
}

/* Welcome book */
.staff-code {
  font-size: 1.8rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  background: var(--s-bg);
  border: 1px dashed var(--s-border);
  border-radius: 8px;
  padding: 0.6rem 0.9rem;
  display: inline-block;
}
.staff-freetext { white-space: pre-wrap; }

/* Wider screens: just breathe a bit more, same single-column mobile-first layout */
@media (min-width: 480px) {
  .staff-property-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 720px) {
  .staff-main { padding-top: 1.5rem; }
  .staff-property-grid { grid-template-columns: repeat(4, 1fr); }

  /* The landing page earns the extra width instead of just centering the
     same phone-narrow column in more empty space: a wider shell, the hero
     laid out two-up (numbers beside the property list), and a 4-across
     tile grid instead of 2. */
  body:has(.staff-hero) .staff-main { max-width: 980px; }
  .staff-hero { padding: 1.6rem 1.8rem 1.8rem; display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: center; }
  .staff-hero-list { margin-top: 0; }
  .staff-hero-cta { grid-column: 1; margin-top: 1.1rem; }
  .staff-alerts { flex-direction: row; }
  .staff-alert-card { flex: 1; }
  .staff-grid { grid-template-columns: repeat(4, 1fr); gap: 0.9rem; }
}

/* 7-day strip at the top of /staff/{id}/calendar — how many properties
   need cleaning each day, at a glance, before the detailed day-by-day
   agenda list below it. A flat row of 7 cells starting TODAY, not a
   Monday-anchored month grid — a rolling week has no fixed "which weekday
   is column 1" answer, so each cell prints its own weekday letters rather
   than relying on a static header row above the grid.

   Colors are explicit hex, not color-mix() percentages of the brand
   accent — deliberately light throughout (a workload calendar reads worse
   the closer its "busy" color gets to looking like an alert), and every
   swatch below sets its own background AND border directly so there's
   nothing for a browser without color-mix() support to silently drop.
   Three buckets (1 / 2 / 3+) — the small-multiple/contribution-graph
   convention (GitHub, Google Calendar heatmaps): enough steps to read
   "quiet vs busy" at a glance, never a gradient nobody can calibrate. A
   legend spells out what each shade means since this is a touch-first
   page with no hover affordance to discover it by. Today gets its own
   ring, independent of workload color, so "where am I" and "how busy is
   it" stay two separate facts instead of being conflated into one.

   Month is printed only on the cell that actually needs it (the first
   cell of the strip, and the 1st of any month the strip crosses into) —
   not as one label guessed for a whole multi-day row, which is what
   silently mislabeled Aug 31 as "Sept." when that row's majority was
   September. There's no vote to get wrong once the label lives on the
   date it actually describes. */
.staff-cal {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-bottom: 0.7rem;
}
.staff-cal-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  min-height: 4.2rem;
  border-radius: 10px;
  padding: 0.4rem 0.2rem;
  background: var(--s-card);
  border: 1px solid var(--s-border);
  color: var(--s-text);
  position: relative;
}
.staff-cal-monthtag {
  position: absolute;
  top: -0.55rem; left: 50%; transform: translateX(-50%);
  background: var(--s-accent-2);
  color: #fff;
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: capitalize;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  white-space: nowrap;
}
.staff-cal-dow {
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--s-muted);
  letter-spacing: 0.02em;
}
.staff-cal-daynum { font-size: 1.05rem; font-weight: 700; line-height: 1; }
.staff-cal-count {
  font-size: 0.62rem;
  font-weight: 700;
  color: var(--s-accent-2);
  line-height: 1;
}
.staff-cal-has-1 { background: #eef5f8; border-color: #d3e6ec; }
.staff-cal-has-2 { background: #dcebf1; border-color: #b7d7e2; }
.staff-cal-has-3 { background: #c3dde6; border-color: #9cc4d3; }
.staff-cal-today {
  outline: 2px solid var(--s-accent);
  outline-offset: 2px;
}

.staff-cal-legend {
  display: flex; flex-wrap: wrap; gap: 0.25rem 0.7rem;
  margin-bottom: 1.2rem;
}
.staff-cal-legend-item {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.74rem; color: var(--s-muted);
}
.staff-cal-swatch {
  width: 1rem; height: 1rem; border-radius: 4px; flex: none;
  background: var(--s-card); border: 1px solid var(--s-border);
}
.staff-cal-swatch.staff-cal-has-1 { background: #eef5f8; border-color: #d3e6ec; }
.staff-cal-swatch.staff-cal-has-2 { background: #dcebf1; border-color: #b7d7e2; }
.staff-cal-swatch.staff-cal-has-3 { background: #c3dde6; border-color: #9cc4d3; }
.staff-cal-today-swatch { background: var(--s-card); border: 2px solid var(--s-accent); }

/* Monetary amounts (see internal/money and the "eur" template helper).
   nowrap keeps the € with its number and stops a thousands separator
   becoming a line break; tabular-nums gives every digit the same advance so
   a right-aligned column lines up on the decimal comma. */
.money { white-space: nowrap; font-variant-numeric: tabular-nums; }
td.amount, th.amount, .amount { text-align: right; }
td.amount .money, td.amount { font-variant-numeric: tabular-nums; }

/* Rotation du code de boîte à clés — saisi sur place, sur un téléphone posé
   sur un plan de travail : pavé numérique (inputmode dans le HTML), cible
   large, et rien d'autre à l'écran au moment de valider. */
.staff-rotate { margin-top: 1rem; padding-top: 0.9rem; border-top: 1px solid var(--s-border); }
.staff-rotate label {
  display: block; font-size: 0.82rem; font-weight: 600;
  color: var(--s-muted); margin-bottom: 0.4rem;
}
.staff-rotate-row { display: flex; gap: 0.6rem; align-items: stretch; }
.staff-rotate-input {
  flex: 1; min-width: 0; max-width: 9rem;
  font-size: 1.6rem; font-weight: 700; letter-spacing: 0.3em; text-indent: 0.3em;
  padding: 0.5rem 0.7rem; min-height: 48px;
  border: 1px solid var(--s-border); border-radius: 8px;
}
.staff-rotate .staff-btn { min-height: 48px; }
.staff-flash {
  margin: 0 0 1rem; padding: 0.7rem 0.9rem; border-radius: 8px;
  background: var(--s-ok-bg, #e6f2ea); color: var(--s-ok, #2f6a4f);
  font-weight: 600; font-size: 0.9rem;
}
.staff-flash.is-error { background: var(--s-error-bg, #f8e6e3); color: var(--s-error, #a3342a); }

/* Le code sur la carte du gîte, pas derrière un clic : quelqu'un qui revient
   pour un chiffon oublié veut les quatre chiffres, pas une deuxième page. */
.staff-property-name { padding-bottom: 0.15rem; }
.staff-property-code {
  padding: 0 0.6rem 0.55rem;
  font-family: ui-monospace, monospace;
  font-size: 1.25rem; font-weight: 700; letter-spacing: 0.18em;
  color: var(--s-accent);
}
.staff-property-nocode {
  padding: 0 0.6rem 0.55rem;
  font-size: 0.76rem; color: var(--s-muted);
}
/* Un ménage de la semaine — la carte que la personne cherche neuf fois sur
   dix, et qui est déjà triée en tête de liste. */
.staff-property-card.is-mine { border-color: var(--s-accent); }
/* Les liens dans un .staff-hint gardaient le bleu par défaut du navigateur,
   seul élément de la page hors palette. */
.staff-hint a { color: var(--s-accent); text-underline-offset: 2px; }

/* ---- Barre du bas ---------------------------------------------------------
   La seule navigation de cette application. Fixée en bas parce que c'est un
   outil de terrain : une main tient le téléphone, le pouce atteint le bas de
   l'écran et pas le haut.

   À toutes les largeurs, contrairement aux autres applications qui la
   réservent au mobile — elles ont une barre latérale au-dessus du point de
   bascule, celle-ci n'a rien du tout, et c'est précisément ce qu'on répare. */
.staff-tab-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 40;
  display: flex;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.35rem 0.4rem calc(0.35rem + env(safe-area-inset-bottom));
  background: var(--s-card);
  border-top: 1px solid var(--s-border);
  box-shadow: 0 -2px 12px rgba(15, 43, 53, 0.06);
}
.staff-tab {
  flex: 1 1 0;
  max-width: 7rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
  padding: 0.4rem 0.25rem;
  border-radius: 10px;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.1;
  text-align: center;
  text-decoration: none;
  color: var(--s-muted);
}
.staff-tab i { font-size: 1.05rem; }
.staff-tab:hover { text-decoration: none; background: var(--s-bg); }
.staff-tab.is-active { color: var(--s-accent); }
/* La page se termine au-dessus de la barre, pas dessous : sans cette réserve
   le dernier bouton d'un formulaire se retrouve sous la barre, injoignable. */
main { padding-bottom: 4.75rem; }

/* ================================================================= grille ===
   La même vue que le planning du desk, sur un téléphone. Elle répond à une
   question que la liste ne sait pas poser : de combien de temps dispose-t-on.
   La case du départ et celle de l'arrivée sont sur la même ligne, et la
   longueur du blanc entre les deux est la réponse.

   Elle défile horizontalement, noms compris. Coller la colonne des noms à
   gauche lui ferait manger un tiers d'un écran de poche sans jamais le rendre
   — et les noms courts tiennent en un mot, ce qui suffit à se repérer. */
.staff-planbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 1rem;
}
.staff-planbar .staff-seg { flex: 1 1 14rem; margin: 0; }
.staff-days { display: flex; gap: 0.3rem; }
.staff-days-item {
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.6rem;
  border: 1px solid var(--s-border);
  border-radius: 999px;
  background: var(--s-card);
  color: var(--s-muted);
  font-size: 0.85rem;
  font-weight: 600;
  text-decoration: none;
}
.staff-days-item.is-active { background: var(--s-accent); border-color: var(--s-accent); color: #fff; }

.staff-seg {
  display: flex;
  gap: 0.3rem;
  margin: 0 0 1rem;
  padding: 0.25rem;
  background: var(--s-card);
  border: 1px solid var(--s-border);
  border-radius: 999px;
}
.staff-seg-item {
  flex: 1;
  padding: 0.5rem 0.4rem;
  border-radius: 999px;
  text-align: center;
  text-decoration: none;
  color: var(--s-muted);
  font-size: 0.9rem;
  font-weight: 600;
}
.staff-seg-item.is-active { background: var(--s-accent); color: #fff; }

.staff-plan-wrap {
  overflow-x: auto;
  margin: 0 0 0.8rem;
  background: var(--s-card);
  border: 1px solid var(--s-border);
  border-radius: 12px;
}
.staff-plan { border-collapse: collapse; font-size: 0.7rem; }
.staff-plan th, .staff-plan td {
  border: none;
  border-bottom: 1px solid var(--s-border);
  padding: 0;
  text-align: center;
}
.staff-plan tr:last-child td { border-bottom: none; }
.staff-plan thead th {
  padding: 0.3rem 0.1rem;
  color: var(--s-muted);
  font-weight: 600;
  line-height: 1.15;
  white-space: nowrap;
}
.staff-plan thead th.is-today { background: var(--s-accent); color: #fff; border-radius: 6px 6px 0 0; }
.staff-plan-month { display: block; font-size: 0.58rem; text-transform: uppercase; letter-spacing: 0.04em; }
.staff-plan-dow { display: block; font-size: 0.58rem; }
.staff-plan-daynum { display: block; font-size: 0.8rem; font-weight: 700; color: var(--s-text); }
.staff-plan thead th.is-today .staff-plan-daynum { color: #fff; }
.staff-plan-prop {
  text-align: left !important;
  padding: 0.35rem 0.5rem !important;
  max-width: 7rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--s-text);
}
.staff-cell { width: 1.5rem; height: 2rem; }
/* Le bouton remplit sa case : la cible est le jour entier, pas le point. Il
   n'a ni fond ni bordure — la case porte déjà l'état — mais il garde un focus
   visible, sans quoi la grille serait inatteignable au clavier. */
.staff-cell-hit {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.staff-cell-hit:hover { background: rgba(23, 43, 58, 0.07); }
.staff-cell-hit:focus-visible { outline: 2px solid var(--s-accent-2); outline-offset: -2px; }

/* Des trames plutôt que des aplats, comme sur les vieilles cartes en noir et
   blanc : une hachure se voit sur un écran mal réglé, à l'impression et en
   niveaux de gris, et elle laisse ressortir le marqueur qu'elle porte. */
.staff-cell.is-booked {
  background-image: repeating-linear-gradient(45deg,
    var(--s-booked) 0, var(--s-booked) 1.5px, transparent 1.5px, transparent 6px);
}
/* Le lavis ne va que sur les jours réellement libres : le jour de l'arrivée
   appartient au créneau — on peut faire le ménage le matin même — mais il est
   réservé, et le peindre comme du libre le dirait faux. */
.staff-cell.is-gap.is-free { background-color: var(--s-gap-wash); }
.staff-cell.is-gap-first { box-shadow: inset 2px 0 0 var(--s-needed); }
.staff-cell.is-gap-last { box-shadow: inset -2px 0 0 var(--s-needed); }
.staff-cell.is-gap-first.is-gap-last {
  box-shadow: inset 2px 0 0 var(--s-needed), inset -2px 0 0 var(--s-needed);
}

.staff-cell-mark {
  display: inline-block;
  width: 1.05rem;
  height: 1.05rem;
  line-height: 1.05rem;
  border-radius: 50%;
  background: var(--s-needed);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
}
.staff-cell.is-mark.is-assigned .staff-cell-mark { background: var(--s-done); }
.staff-cell-mark-legend { width: 0.9rem; height: 0.9rem; line-height: 0.9rem; font-size: 0.6rem; background: var(--s-done); }
.staff-cell-mark-needed { background: var(--s-needed); }
/* En retard : le départ est déjà passé. Un anneau, pas une nuance — une teinte
   de plus dans la même famille ne se distingue ni en niveaux de gris ni pour
   qui ne sépare pas bien les jaunes. */
.staff-cell.is-late .staff-cell-mark,
.staff-cell-mark.is-late-legend {
  box-shadow: 0 0 0 2px var(--s-card), 0 0 0 3.5px var(--s-alert);
}
.staff-cell-mark.is-late-legend { color: #fff; }

.staff-plan-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 0.9rem;
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  color: var(--s-muted);
}
.staff-plan-legend span { display: inline-flex; align-items: center; gap: 0.35rem; }
.staff-plan-swatch {
  width: 1rem;
  height: 1rem;
  border: 1px solid var(--s-border);
  border-radius: 3px;
}
.staff-plan-swatch.is-booked {
  background-image: repeating-linear-gradient(45deg,
    var(--s-booked) 0, var(--s-booked) 1.5px, transparent 1.5px, transparent 6px);
}
.staff-plan-swatch.is-gap { background: var(--s-gap-wash); }
.staff-plan-hint { margin: 0 0 1rem; }

/* La période entière, pas le premier jour libre. */
.staff-assignee-day { font-weight: 400; color: var(--s-muted); }

/* =========================================================== une carte ===
   Une carte = un ménage à répartir. Elle se lit dans l'ordre où l'on décide :
   quel gîte, est-ce que ça presse, de combien de temps je dispose, qui s'en
   occupe. La version précédente empilait quatre lignes de même graisse et de
   même gris, la plus décisive — le temps qui reste — en dernier et en petit,
   et la seule chose qui ressortait était le bouton, identique sur les onze
   cartes : ce qui criait le plus était ce qui distinguait le moins. */

.staff-job-grid { display: grid; gap: 0.8rem; }
.staff-job {
  margin: 0;
  padding: 0;
  overflow: hidden;
}
/* --s-line-urgency ne peint plus de liseré : il ne sert plus qu'au bandeau de
   la période, dont le fond porte le niveau. La pastille dit déjà l'urgence en
   toutes lettres et en couleur ; un trait vertical de plus la répétait une
   troisième fois, et sur une grille de cartes ces barres alignées formaient
   une colonne de rayures qui se lisait avant les cartes elles-mêmes. */
.staff-job.is-today { --s-line-urgency: var(--s-alert); }
.staff-job.is-tight { --s-line-urgency: #c9a227; }
.staff-job.is-calm { --s-line-urgency: #b9c6cd; }

.staff-job-head {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 0.85rem 0.95rem 0.6rem;
}
.staff-job-thumb {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  background: var(--s-bg) center/cover no-repeat;
}
.staff-job-id { flex: 1; min-width: 0; }
.staff-job-name {
  margin: 0;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.25;
  color: var(--s-text);
}
.staff-job-place { margin: 0.1rem 0 0; font-size: 0.82rem; color: var(--s-muted); }

/* Le mot ET la couleur. Sur un écran au soleil, à l'impression, ou pour qui ne
   sépare pas bien le rouge de l'orange, la couleur seule ne dit rien. */
.staff-job-urgency {
  flex: none;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 700;
  white-space: nowrap;
  background: var(--s-stone);
  color: var(--s-muted);
}
.is-today .staff-job-urgency { background: var(--s-alert-bg); color: var(--s-alert); }
.is-tight .staff-job-urgency { background: #fbf3dd; color: #7a6412; }

/* Le bandeau : la part déjà écoulée à gauche, ce qui reste à droite. La même
   information que les deux dates, mais lue sans soustraire — c'est ce que la
   grille montre d'un coup d'œil, ramené à l'échelle d'une carte. */
.staff-job-span { padding: 0 0.95rem 0.7rem; }
/* C'est la part QUI RESTE qui porte la couleur, pas celle qui est passée : le
   fond du bandeau est teinté au niveau d'urgence et la portion écoulée le
   recouvre d'un gris neutre. On lit donc ce qu'il reste, qui est la quantité
   sur laquelle on décide, et non ce qu'on a laissé filer. */
.staff-job-bar {
  height: 7px;
  border-radius: 999px;
  background: var(--s-line-urgency);
  overflow: hidden;
}
.staff-job-bar-done { display: block; height: 100%; background: var(--s-stone); }
.staff-job-dates {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0.4rem 0 0;
  font-size: 0.8rem;
  color: var(--s-muted);
}
.staff-job-arrow { color: var(--s-border); }
/* Le livret est une consultation, pas une décision : un lien discret en bout
   de ligne. Il occupait une case du pied, où il faisait une seconde cible à
   côté de l'action principale — deux boutons côte à côte, dont un seul compte. */
.staff-job-book {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0.15rem;
  color: var(--s-accent-2);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.staff-job-book:hover { text-decoration: underline; }
.staff-job-warn {
  margin: 0.4rem 0 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--s-alert);
}

/* Le pied : l'action, et les codes en second. Un bouton plein par carte
   suffisait à faire onze taches sombres identiques ; « Codes » redevient ce
   qu'il est, un lien qu'on suit une fois sur place. */
.staff-job-foot {
  display: flex;
  align-items: flex-end;
  gap: 0.6rem;
  padding: 0.7rem 0.95rem 0.85rem;
  border-top: 1px solid var(--s-border);
  background: var(--s-bg);
}
.staff-assign-form {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 0.5rem;
  flex: 1;
  margin: 0;
  padding: 0;
  border: none;
}
.staff-field { display: flex; flex-direction: column; gap: 0.2rem; margin: 0; flex: 1 1 8rem; min-width: 0; }
.staff-field label { font-size: 0.72rem; font-weight: 700; color: var(--s-muted); text-transform: uppercase; letter-spacing: 0.03em; }
.staff-field select {
  width: 100%;
  min-height: 44px; /* la cible tactile du portail : il s'utilise debout, dans un gîte */
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--s-border);
  border-radius: 8px;
  background: var(--s-card);
  color: var(--s-text);
  font: inherit;
}
/* Le bouton prend la largeur qui lui reste sur sa ligne. Quand les deux
   champs occupent la première, il se retrouvait seul sur la seconde, calé à
   gauche, avec un vide à sa droite — un bouton isolé qui a l'air d'avoir
   glissé. Et une cible plus large ne se rate pas sur un téléphone. */
.staff-job-foot .staff-btn { min-height: 44px; flex: 1 1 7rem; }

/* Ce qui est pris en charge recule : la carte reste lisible, mais elle ne
   demande plus rien. C'est ce qui n'a pas encore de nom qui doit ressortir. */
.staff-job.is-done { background: var(--s-bg); }
.staff-job.is-done .staff-job-urgency { opacity: 0.55; }
.staff-assignee { margin: 0; padding: 0; border: none; flex: 1; }
.staff-assignee-day { font-weight: 400; color: var(--s-muted); }
.staff-assignee-none { flex: 1; margin: 0; }

.staff-agenda-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.4rem;
  height: 1.4rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--s-stone, #eee8dc);
  color: var(--s-muted);
  font-size: 0.75rem;
  font-weight: 700;
}

/* Au-delà du téléphone, la colonne unique de 640 px laissait les deux tiers de
   l'écran vides et allongeait le défilement d'autant. Les cartes se rangent en
   grille, et le pied passe sur une ligne puisqu'il a la largeur. */
@media (min-width: 760px) {
  .staff-main { max-width: 1100px; }
  .staff-job-grid { grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); }
  .staff-job { display: flex; flex-direction: column; }
  .staff-job-foot { margin-top: auto; }

  /* Les colonnes sont taillées pour un pouce sur un téléphone : 24 px de large
     et le nom tronqué à 7 rem. Gardées telles quelles sur un écran large, la
     grille occupait quatre cents pixels sur mille et lisait « Le Presbytèr… »
     à côté de six cents pixels de vide. Elle prend la largeur qu'elle a. */
  /* table-layout: fixed — sur un plan d'occupation, la distance horizontale EST
     la durée. En largeur automatique, les colonnes qui portent une étiquette de
     mois (« AOÛT », « SEPT. ») faisaient le double des autres : deux jours de
     part et d'autre du 1er septembre n'occupaient plus la même place, et la
     longueur d'un créneau cessait d'être comparable à celle d'à côté. */
  .staff-plan { width: 100%; table-layout: fixed; }
  .staff-plan-prop { width: 12rem; max-width: none; padding: 0.5rem 0.7rem !important; font-size: 0.85rem; }
  .staff-cell { width: auto; height: 2.4rem; }
  .staff-plan thead th { padding: 0.45rem 0.2rem; }
  .staff-plan-dow, .staff-plan-month { font-size: 0.66rem; }
  .staff-plan-daynum { font-size: 0.9rem; }
}

/* ------------------------------------------------- boîte d'affectation ---
   Une personne par bouton, et le clic affecte : pas d'étape « confirmer ».
   Réaffecter est réversible et bon marché. */
.staff-dialog {
  width: min(24rem, calc(100vw - 2rem));
  padding: 0;
  border: 1px solid var(--s-border);
  border-radius: 14px;
  background: var(--s-card);
  color: var(--s-text);
}
.staff-dialog::backdrop { background: rgba(23, 43, 58, 0.45); }
.staff-dialog form { margin: 0; }
.staff-dialog-head {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.9rem 1rem;
  border-bottom: 1px solid var(--s-border);
}
.staff-dialog-head h2 { margin: 0; font-size: 1rem; font-weight: 700; }
.staff-dialog-sub { margin: 0.15rem 0 0; font-size: 0.82rem; color: var(--s-muted); }
.staff-dialog-close {
  margin-left: auto;
  min-width: 44px;
  min-height: 44px;
  border: none;
  background: none;
  color: var(--s-muted);
  font-size: 1rem;
  cursor: pointer;
}
.staff-dialog-list { display: flex; flex-direction: column; padding: 0.4rem; }
.staff-dialog-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  min-height: 48px;
  padding: 0.5rem 0.7rem;
  border: none;
  border-radius: 10px;
  background: none;
  color: var(--s-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.staff-dialog-row:hover { background: var(--s-bg); }
.staff-dialog-name { flex: 1; font-weight: 600; }
.staff-dialog-check { opacity: 0; color: var(--s-accent-2); }
.staff-dialog-row.is-current .staff-dialog-check { opacity: 1; }
.staff-dialog-row.is-clear { color: var(--s-muted); border-top: 1px solid var(--s-border); border-radius: 0 0 10px 10px; }
