/* Administration — aligné sur la DA des autres pages : accent violet #7c3aed (celui de la Sidebar), échelle de gris Tailwind, cartes blanches bordées, rayons 0.5/0.75rem, unités rem. */ /* main.tsx ne charge pas styles/global.css — vestige d'une ancienne maquette, jamais importé — donc son `* { box-sizing: border-box }` ne s'applique pas et l'application tourne en content-box : tout width:100% assorti d'un padding déborde de son conteneur. Réinitialisation cantonnée à cette page pour ne rien déplacer sur le reste du site. */ .page, .page *, .page *::before, .page *::after { box-sizing: border-box; } .page { padding: 2rem; width: 100%; max-width: 80rem; min-width: 0; margin: 0 auto; } /* ── En-tête et onglets ─────────────────────────────────────── */ .header { display: flex; align-items: center; justify-content: space-between; gap: 1rem; flex-wrap: wrap; min-width: 0; margin-bottom: 1.75rem; } .header h1 { font-size: 2.25rem; font-weight: 700; color: rgb(17, 24, 39); line-height: 1.1; margin: 0; } .tabs { display: flex; gap: 0.5rem; min-width: 0; max-width: 100%; overflow-x: auto; scrollbar-width: none; padding-bottom: 0.125rem; } .tabs::-webkit-scrollbar { display: none; } .tabs button { background: transparent; border: 1px solid rgb(229, 231, 235); color: rgb(55, 65, 81); padding: 0.5rem 0.875rem; border-radius: 0.5rem; font-size: 0.9375rem; font-weight: 500; cursor: pointer; white-space: nowrap; flex-shrink: 0; transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease; } .tabs button:hover { background: rgb(249, 250, 251); border-color: rgb(209, 213, 219); } .tabs .active, .tabs .active:hover { background: rgba(124, 58, 237, 0.08); border-color: rgba(124, 58, 237, 0.45); color: #7c3aed; } .tabs button:focus-visible, .danger:focus-visible, .search:focus-visible { outline: 2px solid #7c3aed; outline-offset: 2px; } .content { margin-top: 0.5rem; } /* ── États ──────────────────────────────────────────────────── */ .spinner { padding: 0.875rem 1rem; background: rgb(249, 250, 251); border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; color: rgb(75, 85, 99); margin-bottom: 1rem; } .error { padding: 0.875rem 1rem; background: rgb(254, 242, 242); border: 1px solid rgb(254, 202, 202); color: rgb(185, 28, 28); border-radius: 0.75rem; margin-bottom: 1rem; } .empty { padding: 1.5rem; text-align: center; color: rgb(107, 114, 128); } /* ── Barre de panneau ───────────────────────────────────────── */ .panelHeader { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; flex-wrap: wrap; margin-bottom: 1rem; color: rgb(75, 85, 99); font-size: 0.9375rem; } .search { padding: 0.5rem 0.75rem; border: 1px solid rgb(229, 231, 235); border-radius: 0.5rem; font-size: 0.9375rem; min-width: 14rem; flex: 1 1 14rem; max-width: 22rem; } /* ── Tableaux ───────────────────────────────────────────────── */ .tableWrap { background: white; border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; max-width: 100%; overflow-x: auto; } .table { width: 100%; border-collapse: collapse; font-size: 0.9375rem; } .table th, .table td { padding: 0.75rem 1rem; text-align: left; border-bottom: 1px solid rgb(243, 244, 246); overflow-wrap: anywhere; } /* Sans cette borne, un seul titre long étire la colonne et donc tout le tableau. */ .table td:nth-child(2) { min-width: 12rem; max-width: 26rem; } .table th { background: rgb(249, 250, 251); color: rgb(55, 65, 81); font-weight: 600; white-space: nowrap; cursor: pointer; user-select: none; } .table th:hover { color: #7c3aed; } .table tbody tr:last-child td { border-bottom: none; } .table tbody tr:hover { background: rgb(249, 250, 251); } .rowActions { display: flex; gap: 0.5rem; flex-wrap: wrap; } .rowActions button { background: white; border: 1px solid rgb(229, 231, 235); color: rgb(55, 65, 81); padding: 0.375rem 0.75rem; border-radius: 0.5rem; font-size: 0.875rem; cursor: pointer; } .rowActions button:hover { border-color: rgba(124, 58, 237, 0.45); color: #7c3aed; } .danger, .rowActions .danger { background: rgb(239, 68, 68); color: white; border: 1px solid rgb(239, 68, 68); } .danger:hover, .rowActions .danger:hover { background: rgb(220, 38, 38); border-color: rgb(220, 38, 38); color: white; } /* ── Badges ─────────────────────────────────────────────────── */ .badgeAdmin, .badgeUser, .badgeCIR, .badgeSCCS { display: inline-block; padding: 0.1875rem 0.625rem; font-size: 0.8125rem; font-weight: 600; white-space: nowrap; } .badgeAdmin, .badgeUser { border-radius: 999px; } .badgeAdmin { background: rgba(124, 58, 237, 0.1); color: #6d28d9; border: 1px solid rgba(124, 58, 237, 0.35); } .badgeUser { background: rgb(243, 244, 246); color: rgb(75, 85, 99); border: 1px solid rgb(229, 231, 235); } .badgeCIR, .badgeSCCS { border-radius: 0.5rem; } .badgeCIR { background: rgba(37, 99, 235, 0.1); color: rgb(29, 78, 216); border: 1px solid rgba(37, 99, 235, 0.3); } .badgeSCCS { background: rgba(16, 185, 129, 0.12); color: rgb(4, 120, 87); border: 1px solid rgba(16, 185, 129, 0.3); } /* ── Statistiques ───────────────────────────────────────────── */ .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1rem; margin-bottom: 1.25rem; } .card { background: white; border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; padding: 1.25rem; display: flex; flex-direction: column; gap: 0.375rem; align-items: flex-start; } .card svg { width: 1.25rem; height: 1.25rem; color: #7c3aed; margin-bottom: 0.25rem; } .cardLabel { font-size: 0.875rem; color: rgb(107, 114, 128); } .cardValue { font-size: 1.75rem; font-weight: 700; color: rgb(17, 24, 39); line-height: 1.1; } .chartWrap { background: white; border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; padding: 1.25rem; } .chartLabel { font-weight: 600; color: rgb(17, 24, 39); margin-bottom: 1rem; } .bars { display: flex; flex-direction: column; gap: 0.75rem; } .barRow { display: flex; align-items: center; gap: 0.75rem; } .barTitle { width: 3.5rem; flex-shrink: 0; font-size: 0.875rem; font-weight: 500; color: rgb(55, 65, 81); } /* La largeur est posée en style inline par le composant : min-width garde une amorce visible quand la valeur est nulle. */ .barFill { height: 0.625rem; min-width: 0.625rem; background: rgb(37, 99, 235); border-radius: 999px; } .barFillAlt { background: rgb(16, 185, 129); } .barVal { width: 3rem; flex-shrink: 0; text-align: right; font-variant-numeric: tabular-nums; color: rgb(75, 85, 99); } /* ── Scrapers ───────────────────────────────────────────────── */ .scraperControls { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 1rem; align-items: start; } .scraperControls > div:first-child { display: flex; flex-direction: column; gap: 0.5rem; } .scraperControls button { background: #7c3aed; color: white; border: 1px solid #7c3aed; padding: 0.625rem 1rem; border-radius: 0.5rem; font-size: 0.9375rem; font-weight: 500; cursor: pointer; } .scraperControls button:hover { background: #6d28d9; border-color: #6d28d9; } .logList { background: white; border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; padding: 1.25rem; } .logList h4 { margin: 0 0 0.75rem; font-size: 0.9375rem; font-weight: 600; color: rgb(17, 24, 39); } .logList ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; } .logList li { padding: 0.625rem 0.75rem; background: rgb(249, 250, 251); border: 1px solid rgb(243, 244, 246); border-radius: 0.5rem; font-size: 0.875rem; color: rgb(75, 85, 99); overflow-wrap: anywhere; } .status { font-weight: 600; color: rgb(17, 24, 39); } /* ── Modale ─────────────────────────────────────────────────── */ .modalBackdrop { position: fixed; inset: 0; background: rgba(17, 24, 39, 0.5); display: flex; align-items: center; justify-content: center; padding: 1rem; z-index: 9999; } .modal { background: white; border-radius: 0.75rem; padding: 1.5rem; width: 100%; max-width: 26rem; box-shadow: 0 10px 25px rgba(17, 24, 39, 0.15); } .modalActions { display: flex; gap: 0.5rem; justify-content: flex-end; margin-top: 1.25rem; flex-wrap: wrap; } .modalActions button { background: white; border: 1px solid rgb(229, 231, 235); color: rgb(55, 65, 81); padding: 0.5rem 1rem; border-radius: 0.5rem; font-size: 0.9375rem; cursor: pointer; } .modalActions button:last-child { background: #7c3aed; border-color: #7c3aed; color: white; } /* ── Responsive ─────────────────────────────────────────────── */ @media (max-width: 1024px) { .scraperControls { grid-template-columns: 1fr; } .scraperControls > div:first-child { flex-direction: row; flex-wrap: wrap; } } @media (max-width: 900px) { .page { padding: 1.25rem 1rem; } .header { align-items: flex-start; flex-direction: column; gap: 0.875rem; } .header h1 { font-size: 1.75rem; } .tabs { width: 100%; } /* Chaque ligne devient une carte, avec l'intitulé de colonne en regard. */ .tableWrap { background: transparent; border: none; border-radius: 0; max-width: 100%; overflow-x: visible; } .table, .table tbody, .table tr, .table td { display: block; width: 100%; } .table td:nth-child(2) { min-width: 0; max-width: none; } .table thead { display: none; } .table tr { background: white; border: 1px solid rgb(229, 231, 235); border-radius: 0.75rem; padding: 0.25rem 0; margin-bottom: 0.75rem; } .table tbody tr:hover { background: white; } /* Surtout pas display:flex ici : le texte de la cellule deviendrait un élément flex anonyme, avec min-width:auto — un titre long refuserait de se réduire et sortirait de la carte, en entraînant toute la page. En bloc, l'intitulé passe au-dessus de la valeur et la coupure de mots suffit. */ .table td { display: block; padding: 0.5rem 1rem; border-bottom: none; text-align: left; overflow-wrap: anywhere; word-break: break-word; } .table td[data-label]::before { content: attr(data-label); display: block; font-size: 0.6875rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; color: rgb(107, 114, 128); margin-bottom: 0.125rem; } /* `.table td { display: block }` l'emporte en spécificité sur `.rowActions` : on le rétablit ici pour garder les actions sur une rangée. */ .table td.rowActions { display: flex; } .rowActions { justify-content: stretch; padding-top: 0.75rem; border-top: 1px solid rgb(243, 244, 246); margin-top: 0.25rem; } .rowActions button { flex: 1 1 8rem; min-width: 0; padding: 0.5rem 0.75rem; } .search { max-width: none; } } @media (max-width: 480px) { .cards { grid-template-columns: 1fr; } .scraperControls > div:first-child { flex-direction: column; } .scraperControls button { width: 100%; } .barTitle { width: 2.75rem; } } /* NB : le site n'a pas de mode sombre réel — index.css bascule --bg sur le body mais aucune page n'utilise ces variables et toutes gardent des cartes claires. Cette page suit la même convention pour rester cohérente avec ses sœurs. */