html, body { font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } h1:focus { outline: none; } a, .btn-link { color: #0071c1; } .btn-primary { color: #fff; background-color: #1b6ec2; border-color: #1861ac; } .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; } .content { padding-top: 1.1rem; } .valid.modified:not([type=checkbox]) { outline: 1px solid #26b050; } .invalid { outline: 1px solid red; } .validation-message { color: red; } #blazor-error-ui { color-scheme: light only; background: lightyellow; bottom: 0; box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); box-sizing: border-box; display: none; left: 0; padding: 0.6rem 1.25rem 0.7rem 1.25rem; position: fixed; width: 100%; z-index: 1000; } #blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 0.75rem; top: 0.5rem; } .blazor-error-boundary { background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121; padding: 1rem 1rem 1rem 3.7rem; color: white; } .blazor-error-boundary::after { content: "An error has occurred." } .loading-progress { position: absolute; display: block; width: 8rem; height: 8rem; inset: 20vh 0 auto 0; margin: 0 auto 0 auto; } .loading-progress circle { fill: none; stroke: #e0e0e0; stroke-width: 0.6rem; transform-origin: 50% 50%; transform: rotate(-90deg); } .loading-progress circle:last-child { stroke: #1b6ec2; stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; transition: stroke-dasharray 0.05s ease-in-out; } .loading-progress-text { position: absolute; text-align: center; font-weight: bold; inset: calc(20vh + 3.25rem) 0 auto 0.2rem; } .loading-progress-text:after { content: var(--blazor-load-percentage-text, "Loading"); } code { color: #c02d76; } .form-floating > .form-control-plaintext::placeholder, .form-floating > .form-control::placeholder { color: var(--bs-secondary-color); text-align: end; } .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { text-align: start; } /* ------------------------------------------------------------------ MaBibli — interface du catalogue (phase 3) Conçue mobile d'abord : une seule colonne, cibles tactiles d'au moins 2,75 rem, aucune règle de largeur en dessous du point de rupture. Le PC n'ajoute qu'une largeur maximale et une grille de cartes. ------------------------------------------------------------------ */ :root { --mb-accent: #1b3a5c; --mb-bord: #dcdcdc; --mb-fond-doux: #f4f5f7; --mb-texte-doux: #5c6470; --mb-danger: #a4242c; /* Hauteur de la barre d'onglets (MainLayout). Partagée pour que les actions flottantes se posent JUSTE au-dessus : deux barres fixes en bas d'écran se recouvriraient. */ --mb-onglets-hauteur: 2.6rem; } body { background: #fff; color: #1d2129; } .titre-page { font-size: 1.4rem; margin: 0 0 0.75rem; } .message-discret { color: var(--mb-texte-doux); font-size: 0.9rem; } .message-erreur { background: #fdecec; border-left: 3px solid var(--mb-danger); color: #7a1a20; padding: 0.6rem 0.75rem; border-radius: 4px; margin: 0.75rem 0; } .message-avertissement { background: #fff8e1; border-left: 3px solid #c99700; color: #6b5200; padding: 0.6rem 0.75rem; border-radius: 4px; margin: 0.5rem 0; font-size: 0.9rem; } .compteur { color: var(--mb-texte-doux); font-size: 0.85rem; margin: 0.75rem 0 0.25rem; } /* --- Champs de saisie --- */ .barre-recherche { margin-bottom: 0.75rem; } .champ { display: block; margin-bottom: 0.9rem; border: 0; padding: 0; } .champ-libelle { display: block; font-size: 0.85rem; font-weight: 600; margin-bottom: 0.3rem; } .champ-aide, .obligatoire { font-weight: 400; color: var(--mb-texte-doux); } .champ-saisie { width: 100%; /* 16px minimum : en dessous, iOS zoome au focus. */ font-size: 1rem; padding: 0.7rem 0.75rem; border: 1px solid var(--mb-bord); border-radius: 8px; background: #fff; } .champ-saisie:focus { outline: 2px solid var(--mb-accent); outline-offset: -1px; } /* --- Segments (filtres, format, statut) --- */ .segments { display: flex; flex-wrap: wrap; gap: 0.35rem; margin-bottom: 0.5rem; } .segment { flex: 1 1 auto; min-height: 2.5rem; padding: 0.4rem 0.7rem; font-size: 0.85rem; border: 1px solid var(--mb-bord); border-radius: 999px; background: #fff; color: #1d2129; cursor: pointer; } .segment-actif { background: var(--mb-accent); border-color: var(--mb-accent); color: #fff; } .segments-compacts .segment { min-height: 2.2rem; font-size: 0.8rem; } .segment.statut-a-lire.segment-actif { background: #6b4fa8; border-color: #6b4fa8; } .segment.statut-en-cours.segment-actif { background: #b06b00; border-color: #b06b00; } .segment.statut-lu.segment-actif { background: #1f7a44; border-color: #1f7a44; } /* --- Boutons --- */ .bouton { display: inline-flex; align-items: center; justify-content: center; min-height: 2.75rem; padding: 0.6rem 1rem; border-radius: 8px; border: 1px solid var(--mb-bord); background: #fff; color: #1d2129; font-size: 0.95rem; text-decoration: none; cursor: pointer; } .bouton:disabled { opacity: 0.55; cursor: default; } .bouton-principal { background: var(--mb-accent); border-color: var(--mb-accent); color: #fff; } .bouton-discret { background: var(--mb-fond-doux); } .bouton-danger { background: var(--mb-danger); border-color: var(--mb-danger); color: #fff; } .actions-formulaire { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 1rem 0; } /* Cette barre ne porte plus que des ACTIONS : la navigation est passée dans les onglets. Elle se pose au-dessus d'eux, jamais dessus. */ .actions-flottantes { position: fixed; left: 0; right: 0; bottom: calc(var(--mb-onglets-hauteur) + env(safe-area-inset-bottom)); display: flex; flex-wrap: wrap; gap: 0.5rem; padding: 0.6rem 1rem calc(0.6rem + env(safe-area-inset-bottom)); background: rgba(255, 255, 255, 0.96); border-top: 1px solid var(--mb-bord); } /* Base de 8rem : au-delà de trois entrées la barre passe sur deux lignes plutôt que de comprimer chaque libellé sur trois lignes de texte. Mesuré sur 375 px de large. */ .actions-flottantes .bouton { flex: 1 1 8rem; } /* --- Couvertures --- */ .couverture { position: relative; flex: 0 0 auto; overflow: hidden; border-radius: 6px; background: var(--mb-fond-doux); border: 1px solid var(--mb-bord); } .couverture-petite { width: 3.5rem; height: 5.25rem; } .couverture-moyenne { width: 6rem; height: 9rem; } .couverture-substitut { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; font-weight: 700; color: #9aa2ad; } .couverture-image { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; } /* Posée par l'attribut onerror : les couvertures OpenLibrary renvoient des 502 intermittents, l'image cassée laisse place au substitut. */ .couverture-image.image-cassee { display: none; } /* --- Liste de livres --- */ .liste-livres, .liste-candidats { list-style: none; margin: 0; padding: 0; } .carte-livre, .carte-candidat { display: flex; gap: 0.75rem; padding: 0.75rem 0; border-bottom: 1px solid var(--mb-bord); } .carte-corps { min-width: 0; flex: 1; } .carte-titre { display: block; font-weight: 600; color: #1d2129; text-decoration: none; margin: 0 0 0.15rem; } .carte-auteur { margin: 0 0 0.25rem; color: var(--mb-texte-doux); font-size: 0.9rem; } .carte-details { display: flex; flex-wrap: wrap; gap: 0.4rem; align-items: center; margin: 0 0 0.5rem; font-size: 0.8rem; color: var(--mb-texte-doux); } .etiquette { background: var(--mb-fond-doux); border-radius: 4px; padding: 0.1rem 0.4rem; } /* --- Choix entre plusieurs notices --- */ /* Les candidats partagent titre et auteur : ce sont l'éditeur et l'année qui les départagent, donc ils sont mis en avant visuellement. */ .candidat-distinction { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0 0 0.4rem; font-size: 0.9rem; } .candidat-editeur { font-weight: 600; } .candidat-annee { background: #eef2f7; border-radius: 4px; padding: 0.05rem 0.4rem; } /* --- Formulaire --- */ .formulaire-apercu { display: flex; justify-content: center; margin-bottom: 1rem; } .zone-danger { margin-top: 2rem; padding-top: 1rem; border-top: 1px solid var(--mb-bord); } /* --- PC : simple élargissement, la structure mobile ne change pas. --- */ @media (min-width: 48rem) { .actions-flottantes { position: static; padding: 0; margin-top: 1.5rem; background: none; border-top: 0; } .actions-flottantes .bouton { flex: 0 0 auto; } } /* --- Prêts --- */ /* Le prêt est une information du foyer, pas de l'utilisateur : sa couleur est volontairement différente de celles des statuts de lecture, qui sont personnels. */ .etiquette-prete { background: #fdecd8; color: #7a4a00; font-weight: 600; } .bloc-prets { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--mb-bord); } .titre-section { font-size: 1.1rem; margin: 0 0 0.5rem; } .titre-sous-section { font-size: 0.95rem; margin: 1.25rem 0 0.35rem; color: var(--mb-texte-doux); } .bandeau-pret { background: #fff8ef; border-left: 3px solid #c98a2e; border-radius: 4px; padding: 0.6rem 0.75rem; margin: 0.5rem 0; font-size: 0.95rem; } .pret-duree { color: var(--mb-texte-doux); font-size: 0.85rem; white-space: nowrap; } .avertissement-fort { display: block; margin-top: 0.35rem; font-weight: 600; } /* L'historique se lit, il ne se manipule pas : rien n'y est cliquable. */ .liste-historique { list-style: none; margin: 0; padding: 0; font-size: 0.9rem; } .liste-historique li { padding: 0.4rem 0; border-bottom: 1px solid var(--mb-bord); } .historique-dates { display: block; color: var(--mb-texte-doux); font-size: 0.85rem; } /* Bouton d'action au sein d'une carte : il ne doit pas peser autant qu'un bouton de page, tout en gardant une cible tactile utilisable. */ .bouton-compact { min-height: 2.25rem; padding: 0.35rem 0.8rem; font-size: 0.85rem; } /* --- Scan du code-barres --- */ .scanner-cadre { position: relative; background: #000; border-radius: 8px; overflow: hidden; aspect-ratio: 4 / 3; } .scanner-video { width: 100%; height: 100%; object-fit: cover; display: block; } /* Le viseur matérialise la bande réellement décodée : viser ailleurs ne sert à rien. */ .scanner-viseur { position: absolute; left: 5%; right: 5%; top: 27.5%; height: 45%; border: 2px solid rgba(255, 255, 255, 0.85); border-radius: 6px; box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.35); } .scanner-mesure { font-variant-numeric: tabular-nums; } /* --- Agrandissement de la couverture --- */ /* Le déclencheur recouvre exactement la vignette. Il n'existe que quand il y a une image : sans couverture, le substitut à initiale reste un décor inerte. */ .couverture-declencheur { position: absolute; inset: 0; padding: 0; border: 0; background: none; cursor: zoom-in; } .calque-couverture { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; padding: 1.5rem; background: rgba(0, 0, 0, 0.82); cursor: zoom-out; } .calque-couverture:focus { outline: none; } /* Bornée par la fenêtre : sur mobile la couverture occupe la largeur, sur PC elle ne dépasse pas la hauteur utile. */ .calque-image { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 6px; background: #fff; cursor: default; } .calque-image.image-cassee { display: none; } .calque-fermer { position: absolute; top: calc(0.5rem + env(safe-area-inset-top)); right: 0.5rem; min-width: 2.75rem; min-height: 2.75rem; border: 0; border-radius: 999px; background: rgba(255, 255, 255, 0.15); color: #fff; font-size: 1.1rem; cursor: pointer; } /* --- Statut de lecture en lecture seule --- */ /* Pastille pleine, aux couleurs des segments actifs, pour ne pas se confondre avec l'étiquette pâle du prêt : le statut est personnel, le prêt est celui du foyer. */ .etiquette-statut { color: #fff; font-weight: 600; } .etiquette-statut.statut-a-lire { background: #6b4fa8; } .etiquette-statut.statut-en-cours { background: #b06b00; } .etiquette-statut.statut-lu { background: #1f7a44; } /* --- Fiche du livre en lecture seule --- */ .couverture-grande { width: 8rem; height: 12rem; } .fiche-entete { display: flex; gap: 1rem; align-items: flex-start; margin-bottom: 1rem; } .fiche-infos { min-width: 0; flex: 1; } .fiche-titre { font-size: 1.15rem; margin: 0 0 0.25rem; } .fiche-auteurs { margin: 0 0 0.5rem; color: var(--mb-texte-doux); } /* Deux colonnes « libellé / valeur » qui restent lisibles à 320 px. */ .fiche-champs { margin: 0; font-size: 0.9rem; } .fiche-champs div { display: flex; gap: 0.5rem; padding: 0.15rem 0; } .fiche-champs dt { flex: 0 0 5rem; color: var(--mb-texte-doux); } .fiche-champs dd { margin: 0; min-width: 0; word-break: break-word; } /* Le statut reste manipulable hors édition : c'est le geste le plus fréquent de l'application, l'enfouir derrière « Éditer » serait un recul. */ .bloc-statut { margin-top: 1.25rem; padding-top: 1rem; border-top: 1px solid var(--mb-bord); } /* --- Auteurs --- */ /* Le nom d'un auteur est un point d'entrée, pas une décoration : il doit se voir comme cliquable, et rester une cible atteignable au pouce dans une liste dense. */ .lien-auteur { color: var(--mb-accent); text-decoration: none; padding: 0.1rem 0; } .lien-auteur:hover, .lien-auteur:focus { text-decoration: underline; } .liste-auteurs, .liste-rapprochements { list-style: none; margin: 0; padding: 0; } .carte-auteur-ligne { display: flex; gap: 0.5rem; align-items: center; justify-content: space-between; min-height: 2.75rem; padding: 0.4rem 0; border-bottom: 1px solid var(--mb-bord); } .rapprochements { margin-bottom: 1.5rem; padding: 0.75rem; border: 1px solid var(--mb-bord); border-radius: 8px; background: var(--mb-fond-doux); } .carte-rapprochement { padding: 0.5rem 0; border-top: 1px solid var(--mb-bord); } .rapprochement-noms { margin: 0; font-size: 0.95rem; } /* ───────────────────────────────────────────────────────────────────────────── Liste d'envies et bibliographie par auteur. Mobile d'abord : une colonne, l'action à droite du texte, rien qui déborde. ───────────────────────────────────────────────────────────────────────────── */ .bloc-souhait-ajout { background: var(--mb-fond-doux); border-radius: 8px; padding: 0.75rem; margin-bottom: 1rem; } /* Le champ ISBN et son bouton sur une ligne : le bouton ne doit pas se rétrécir au point de devenir intouchable au pouce quand le champ est large. */ .ligne-isbn { display: flex; gap: 0.5rem; } .ligne-isbn .champ-saisie { flex: 1; min-width: 0; } .ligne-isbn .bouton { flex-shrink: 0; } .actions-export { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-bottom: 0.75rem; } .liste-souhaits, .liste-bibliographie { list-style: none; margin: 0; padding: 0; } .carte-souhait, .carte-oeuvre { display: flex; gap: 0.75rem; align-items: flex-start; padding: 0.75rem 0; border-bottom: 1px solid var(--mb-bord); } /* Le corps prend la place restante et « min-width: 0 » l'autorise à rétrécir : sans lui, un titre long pousse le bouton hors de l'écran sur mobile. */ .carte-souhait .carte-corps, .carte-oeuvre .carte-corps { flex: 1; min-width: 0; } .carte-souhait .bouton, .carte-oeuvre .bouton { flex-shrink: 0; align-self: center; } .souhait-note { margin: 0.25rem 0 0; color: var(--mb-texte-doux); font-size: 0.9rem; font-style: italic; } /* Le grisage des livres déjà possédés : c'est l'information principale de l'écran de bibliographie. L'opacité seule suffirait visuellement, mais elle ne dit rien à un lecteur d'écran — d'où l'étiquette « Déjà chez vous » qui l'accompagne toujours dans le balisage. */ .oeuvre-possedee { opacity: 0.55; } .oeuvre-possedee .carte-titre { font-weight: 400; } .etiquette-possede { background: #e3ece3; color: #2f5d34; font-weight: 600; } .etiquette-souhaite { background: #e6e6f5; color: #3b3b7a; font-weight: 600; } /* --- Mise à jour de l'application --- */ /* Injecté par js/mise-a-jour.js, hors composants Blazor : ce bandeau doit pouvoir s'afficher même si l'application WebAssembly n'a pas démarré. D'où une règle globale et non scopée. Il existe parce que les empreintes des assets WASM sont désactivées (CLAUDE.md) : le service worker est le seul cache-busting du projet, et sa mise à jour attendrait sinon la fermeture de tous les onglets. */ #mb-maj { position: fixed; left: 0; right: 0; bottom: 0; z-index: 1100; display: flex; gap: 0.75rem; align-items: center; justify-content: center; flex-wrap: wrap; padding: 0.7rem 1rem; background: #1b3a5c; color: #fff; font-size: 0.9rem; } #mb-maj button { min-height: 2.5rem; padding: 0.4rem 0.9rem; border: 0; border-radius: 6px; background: #f5d76e; color: #4a3800; font-weight: 600; cursor: pointer; } /* Un ISBN se relit chiffre à chiffre : une chasse fixe évite de confondre 1 et l, 0 et O, et rend les tranches séparées par des tirets alignées d'une ligne à l'autre. */ .code-isbn { font-family: ui-monospace, "SFMono-Regular", "Menlo", "Consolas", monospace; white-space: nowrap; } /* Titre d'écran et son bouton de réglages sur la même ligne : le bouton « Filtrer » du catalogue appartient au titre, pas au contenu. */ .entete-page { display: flex; align-items: baseline; justify-content: space-between; gap: 0.75rem; } .entete-page .titre-page { margin-bottom: 0.5rem; } /* --- Liste d'envies : ordre choisi --- */ /* Colonne de déplacement à gauche de chaque envie. Les flèches sont larges à dessein : c'est le seul moyen de réordonner au doigt, le glisser-déposer HTML5 n'existant pas sur mobile. */ .rang-actions { display: flex; flex-direction: column; align-items: center; gap: 0.15rem; flex: 0 0 auto; } .rang-actions .bouton { padding: 0.15rem 0.5rem; line-height: 1.1; } .rang-numero { font-size: 0.75rem; color: var(--mb-texte-doux); font-variant-numeric: tabular-nums; } /* La carte saisie s'efface pendant le glissé : sans ce repère, on ne sait plus laquelle on déplace une fois le curseur loin de son point de départ. */ .carte-glissee { opacity: 0.4; } /* Trois manières de chercher, sur une ligne : réutilise l'apparence des segments du catalogue plutôt que d'inventer un troisième style de bascule. */ .onglets-secondaires { display: flex; gap: 0.25rem; margin: 0.75rem 0; } .onglets-secondaires .segment { flex: 1 1 0; } /* --- Sagas, cycles et séries --- */ .liste-series, .liste-tomes, .liste-sous-series { list-style: none; margin: 0.5rem 0; padding: 0; } .carte-serie { padding: 0.7rem 0; border-bottom: 1px solid var(--mb-bord); } .liste-sous-series { margin: 0.35rem 0 0 1rem; font-size: 0.9rem; } .liste-sous-series li { padding: 0.2rem 0; display: flex; gap: 0.5rem; align-items: baseline; flex-wrap: wrap; } .carte-tome { display: flex; gap: 0.6rem; align-items: flex-start; padding: 0.6rem 0; border-bottom: 1px solid var(--mb-bord); } /* Le tome absent est estompé, comme une œuvre déjà possédée l'est dans la bibliographie — mais l'opacité ne dit rien à un lecteur d'écran, d'où l'étiquette qui l'accompagne. */ .tome-manquant .carte-titre { font-weight: 400; color: var(--mb-texte-doux); } .etiquette-manquant { background: #f3e2e2; color: #7a2f2f; font-weight: 600; } .actions-tome { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.35rem; } /* Rattacher un livre à une place : la recherche s'ouvre SOUS le tome concerné, pour qu'on voie ce qu'on est en train de compléter. */ .recherche-livre { display: flex; flex-direction: column; gap: 0.3rem; margin-top: 0.5rem; padding: 0.5rem; background: var(--mb-fond-doux); border-radius: 6px; } .recherche-livre .bouton { text-align: left; } .fiche-serie { margin: 0.2rem 0; font-size: 0.9rem; color: var(--mb-texte-doux); } /* --- Revues et numéros --- */ .liste-numeros { list-style: none; margin: 0.5rem 0; padding: 0; } .carte-numero { display: flex; gap: 0.6rem; align-items: flex-start; justify-content: space-between; padding: 0.6rem 0; border-bottom: 1px solid var(--mb-bord); } /* Numéro, date et note tiennent sur une ligne dès qu'il y a la place, et se replient sinon : la saisie d'un numéro est répétitive, on ne veut pas la faire défiler. */ .champs-numero { display: flex; flex-wrap: wrap; gap: 0.75rem; } .champs-numero .champ { flex: 1 1 8rem; } /* --- Rôles des auteurs (scénario, dessin, couleurs) --- */ .role-auteur { color: var(--mb-texte-doux); font-size: 0.85em; } /* Un nom, sa rangée de rôles : la ligne se replie sur les écrans étroits plutôt que de comprimer les boutons, qui doivent rester atteignables au pouce. */ .ligne-role { display: flex; flex-wrap: wrap; align-items: center; gap: 0.4rem 0.75rem; margin-top: 0.4rem; } .nom-role { font-weight: 600; font-size: 0.9rem; }