/* ==========================================================================
   MOBILE — ergonomie tactile du front office et de l'espace adhérent
   (audit du 23/10/2026, 320 → 768 px, portrait et paysage)

   Chargée après app.css, dont elle ne remplace aucune règle de couleur ni de
   police : elle ne règle que des TAILLES et des AGENCEMENTS. Les débordements
   horizontaux avaient déjà été traités page par page ; ce qui restait tenait à
   la main du lecteur plutôt qu'à la largeur de l'écran :

     — des cibles tactiles de 24 à 40 px, là où le pouce en demande 44 ;
     — un bandeau de cookies qui mangeait la moitié d'un écran de 568 px ;
     — une fenêtre de gestion des cookies dont le titre, la croix de fermeture et
       le bouton « Enregistrer » sortaient du cadre, sans défilement pour les
       atteindre ;
     — une carte de 440 px qui capturait le doigt au lieu de laisser défiler la page.

   Seuil : « max-width: 991.98px » est celui du bandeau (menu en ligne dès 992 px),
   « pointer: coarse » rattrape les tablettes larges et les téléphones qui
   annoncent une grande fenêtre.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Socle
   -------------------------------------------------------------------------- */

/* Sans cette propriété, iOS gonfle le texte au passage en paysage : la mise en
   page calée sur 17 px se retrouve à 22 px. */
html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* Supprime l'attente du double-tap sur ce qui se touche, et empêche un second
   appui rapide de zoomer la page au lieu d'activer la commande. */
a, button, .btn, input, select, textarea, label, summary, [role="button"] {
    touch-action: manipulation;
}

/* Une adresse de courriel ou une URL collée dans une fiche, sans espace, ne doit
   jamais élargir la page : elle se coupe. */
main {
    overflow-wrap: break-word;
}

/* Un lien d'ancre (« #contenu-principal », « #evt-12 ») amène l'élément tout en haut de
   l'écran — sous le bandeau, qui colle en haut et mesure 108 px sur téléphone. Sans cette
   marge, l'intitulé visé restait caché derrière lui. */
@media (max-width: 991.98px) {
    html {
        scroll-padding-top: 120px;
    }
}

@media (max-width: 991.98px) and (max-height: 500px) and (orientation: landscape) {
    html {
        scroll-padding-top: 0;
    }
}

/* Une largeur minimale posée en ligne sur un bloc (« min-width: 260px ») sert à le
   renvoyer à la ligne ; sur 320 px, elle dépasse la carte qui le contient. */
@media (max-width: 575.98px) {
    [style*="min-width: 2"] {
        min-width: 0 !important;
    }
}

/* 100vh, sur mobile, mesure l'écran barre d'adresse repliée : la page courte
   déborde alors d'une barre et défile pour rien. 100dvh suit la barre. Un
   navigateur qui ne connaît pas dvh ignore la déclaration et garde 100vh. */
.rof-front-layout.min-vh-100 {
    min-height: 100dvh !important;
}

/* --------------------------------------------------------------------------
   Cibles tactiles : 44 × 44 px (Apple HIG, WCAG 2.5.5)
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px), (pointer: coarse) {

    /* Le gabarit se règle par la variable de Bootstrap plutôt que par min-height
       seul : un bouton qui n'est pas en flex garde ainsi son libellé centré, au
       lieu de le voir collé en haut d'une boîte devenue plus haute. */
    .btn, .btn-sm {
        --bs-btn-padding-y: .6rem;
        min-height: 44px;
        /* Un bouton qui ne porte qu'une icône (monter, descendre, supprimer un bloc)
           mesurait 35 px de large. */
        min-width: 44px;
    }

    .btn-rof-icon.sm {
        width: 44px;
        height: 44px;
    }

    /* Croix des fenêtres Bootstrap : 28×34 px. Le dessin garde sa taille, c'est la zone qui grandit. */
    .btn-close {
        box-sizing: border-box;
        flex: none;
        width: 44px;
        height: 44px;
        padding: 0;
    }

    .rof-searchbar input {
        min-height: 44px;
    }

    .rof-chip,
    .rof-filter-chip {
        min-height: 44px;
    }

    .rof-porte-go,
    .rof-porte-list a,
    .rof-aside-link {
        min-height: 44px;
    }

    /* Lecteur de « Notre projet politique » : boutons de mode et de navigation à 40 px. */
    .rof-lecteur-mode,
    .rof-lecteur-bouton {
        min-height: 44px;
    }

    .rof-lecteur-bouton {
        min-width: 44px;
    }

    /* « Accueil › Je suis ostéo › Évènements » : les liens du fil d'Ariane
       mesuraient 24 px de haut. */
    .rof-breadcrumb a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    /* Téléphone, courriel et site d'un établissement : des lignes de 24 px. */
    .rof-meta-list a {
        display: inline-flex;
        align-items: center;
        min-height: 44px;
    }

    /* Les liens « en gras » posés seuls sur leur ligne (raccourcis d'une colonne
       latérale, appel vers l'annuaire en fin d'article) ne sont pas des boutons,
       mais ils se touchent comme tels. */
    main a:is(.fw-semibold, .fw-bold):is(.d-block, .d-inline-flex):not(.btn):not(.rof-chip) {
        padding-block: 10px;
        min-height: 44px;
    }

    /* iOS zoome la page dès qu'on touche un champ dont le texte fait moins de 16 px,
       et ne la dézoome pas. Le pas de base du site donne 15,94 px à « --fs-sm » : un
       champ qui l'employait en ligne (le filtre par région, par exemple) déclenchait
       le zoom. Le plancher est donc posé ici, en !important pour passer devant les
       styles en ligne. */
    select,
    textarea,
    input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]) {
        font-size: max(1rem, 16px) !important;
    }

    .form-control-sm,
    .form-select-sm {
        min-height: 44px;
    }

    /* Une liste déroulante logée dans une enveloppe bordée ne mesurait que 21 px :
       le reste de l'enveloppe, 44 px, ne l'ouvrait pas. Elle la remplit. */
    .form-select.border-0.p-0,
    .rof-select-shell select {
        align-self: stretch;
        min-height: 44px !important;
        margin-block: -1px;
    }

    /* Cases à cocher et boutons radio : 17 px de côté. Le libellé, cliquable, porte
       aussi sa part de la hauteur, de sorte que la ligne entière dépasse 44 px. Les
       interrupteurs (.form-switch) gardent leur gabarit propre. */
    .form-check-input {
        width: 1.5rem;
        height: 1.5rem;
        margin-top: .6rem;
    }

    .form-check:not(.form-switch) {
        padding-left: 2rem;
    }

    .form-check:not(.form-switch) .form-check-input {
        margin-left: -2rem;
    }

    .form-check-label {
        padding-block: .6rem;
    }

    /* Boutons + et − de Leaflet : 30 px par défaut. Sélecteur renforcé car la feuille
       de Leaflet est chargée après celle-ci, en pied de page. */
    .leaflet-container.leaflet-touch .leaflet-bar a {
        width: 44px;
        height: 44px;
        line-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   Bandeau supérieur
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px) {

    /* Le logotype fait 38 px de haut : c'est son lien, pas son image, qui doit
       offrir la cible. */
    .rof-brand {
        min-width: 44px;
        min-height: 44px;
        justify-content: center;
    }

    /* « Espace adhérent », « Adhérer », « Mon espace » portaient height: 40px en
       ligne ; min-height l'emporte sur height. */
    .rof-main-header .btn,
    .rof-main-header .btn-rof-icon {
        min-height: 44px;
        min-width: 44px;
    }
}

@media (max-width: 575.98px) {

    /* Quatre rubriques sur 320 px : à largeur naturelle elles réclamaient 352 px,
       et « Annonces » n'était atteignable qu'en faisant défiler la barre — un
       onglet caché. Elles se partagent désormais la largeur à parts égales, et le
       libellé se replie si le texte système est agrandi.

       À cinq liens (quand « Notre projet politique » est en ligne), 64 px chacun
       coupaient « Actualités » au milieu du mot : la barre garde alors sa largeur
       naturelle, défile, et rofNav (rof-app.js) ramène la page courante au centre. */
    .rof-mobile-nav:not(:has(> a:nth-child(5))) a {
        flex: 1 1 0;
        min-width: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 8px 4px;
        min-height: 48px;
        line-height: 1.2;
        white-space: normal;
        overflow-wrap: anywhere;
    }
}

/* En paysage sur un téléphone, le bandeau (60 px) et sa barre de rubriques
   (48 px) occupaient 110 px d'un écran de 375 : il ne reste pas de quoi lire.
   Il cesse de coller en haut et défile avec la page. */
@media (max-height: 500px) and (orientation: landscape) {
    .rof-main-header.sticky-top {
        position: static;
    }
}

/* --------------------------------------------------------------------------
   Pied de page
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px) {

    .rof-footer nav a {
        display: flex;
        align-items: center;
        min-height: 44px;
        padding-block: 0;
    }

    /* Le téléphone et le courriel du secrétariat sont dans un paragraphe : ils
       gardent leur place dans le texte, avec une hauteur de ligne suffisante. */
    .rof-footer p a {
        display: inline-block;
        padding-block: 10px;
    }

    .rof-footer-bottom a,
    .rof-footer-bottom .btn-link {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
        min-width: 44px;
    }

    .rof-social {
        width: 44px;
        height: 44px;
    }
}

/* --------------------------------------------------------------------------
   Bandeau de consentement aux cookies
   -------------------------------------------------------------------------- */

/* Garde-fou : quelle que soit la taille de l'écran, le bandeau ne dépasse pas
   60 % de sa hauteur, et défile au besoin plutôt que de masquer la page entière. */
.rof-cookie-banner {
    max-height: 60vh;
    max-height: 60dvh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 1rem 1rem;
}

.rof-cookie-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.rof-cookie-actions .btn {
    min-height: 44px;
    padding-inline: 1.5rem;
}

@media (min-width: 768px) {
    .rof-cookie-banner {
        padding-inline: 1.5rem;
    }
}

@media (max-width: 575.98px) {

    .rof-cookie-banner {
        padding: 12px 16px 14px;
    }

    .rof-cookie-text {
        font-size: var(--fs-xs);
        line-height: 1.45;
    }

    /* Accepter et refuser côte à côte, à parts égales — la CNIL demande qu'ils
       soient aussi simples l'un que l'autre —, « Personnaliser » seul dessous. */
    .rof-cookie-actions {
        display: grid;
        grid-template-columns: 1fr 1fr;
        width: 100%;
    }

    .rof-cookie-actions .btn {
        width: 100%;
        padding-inline: 8px;
    }

    .rof-cookie-actions .btn.ghost {
        grid-column: 1 / -1;
    }
}

/* Paysage sur téléphone : le texte à gauche, les commandes à droite, sur une
   seule ligne, plutôt qu'un bloc empilé de 145 px sur un écran de 375. */
@media (max-height: 500px) and (orientation: landscape) {

    .rof-cookie-banner > div {
        flex-direction: row !important;
        align-items: center !important;
    }

    .rof-cookie-banner {
        padding-block: 8px;
    }

    .rof-cookie-text {
        font-size: var(--fs-xs);
        line-height: 1.35;
    }

    .rof-cookie-actions {
        display: flex;
        flex-wrap: nowrap;
        width: auto;
    }

    /* Trois commandes de 150 px laissaient 150 px au texte, qui se repliait sur sept
       lignes : les marges et le corps se resserrent pour qu'il garde de la place. */
    .rof-cookie-actions {
        gap: 6px;
    }

    .rof-cookie-actions .btn {
        width: auto;
        white-space: nowrap;
        padding-inline: 10px;
        font-size: var(--fs-xs);
    }

    .rof-cookie-actions .btn.ghost {
        grid-column: auto;
    }
}

/* --------------------------------------------------------------------------
   Fenêtre « Gestion des cookies »

   Elle utilisait .modal-dialog-scrollable, qui ne sait faire défiler qu'un
   .modal-content : la carte du site n'en est pas un. Elle dépassait donc la
   fenêtre des deux côtés — titre et croix au-dessus du bord haut, bouton
   « Enregistrer mes choix » sous le bord bas — et, centrée, sa partie haute
   n'était atteignable par aucun défilement.

   La carte est ici bornée à la hauteur de l'écran, son en-tête et son pied
   restent en place, seul le corps défile.
   -------------------------------------------------------------------------- */
.rof-cookie-dialog {
    margin: 8px auto;
}

.rof-cookie-card {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 16px);
    max-height: calc(100dvh - 16px);
}

.rof-cookie-card > .rof-card-head,
.rof-cookie-card > .rof-cookie-foot {
    flex: none;
}

.rof-cookie-card > .rof-cookie-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
}

@media (max-width: 575.98px) {
    .rof-cookie-dialog {
        margin: 8px;
    }

    /* Le pied porte « Politique de confidentialité » et « Enregistrer » : sur
       320 px, l'un sous l'autre, le bouton sur toute la largeur. */
    .rof-cookie-foot {
        flex-direction: column-reverse;
        align-items: stretch !important;
    }

    .rof-cookie-foot .btn {
        width: 100%;
    }

    .rof-cookie-foot a {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   Cartes (annuaire, établissements de formation)
   -------------------------------------------------------------------------- */
.rof-map {
    height: 440px;
}

@media (max-width: 991.98px) {

    /* 440 px sur un écran de 812, c'est plus de la moitié : le doigt posé sur la
       carte la déplaçait, et la page ne défilait plus tant qu'il y restait. */
    .rof-map {
        height: min(440px, 52vh);
        min-height: 260px;
    }
}

@media (max-height: 500px) and (orientation: landscape) {
    .rof-map {
        height: 70vh;
        min-height: 0;
    }
}

/* Message affiché un instant quand un doigt seul se pose sur la carte : la page
   défile, la carte se déplace à deux doigts. Voir rof-map.js. */
.rof-map-hint {
    position: absolute;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(11, 26, 46, .55);
    color: #fff;
    font-family: var(--font-ui);
    font-weight: 600;
    font-size: var(--fs-sm);
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
}

.rof-map-hint.visible {
    opacity: 1;
}

/* --------------------------------------------------------------------------
   Calendrier des évènements
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {

    /* L'intitulé se réduit à un trait de 6 px : le lien ne se touchait pas. Son
       zone d'appui s'étend à la case entière, qui fait 56 px de haut. Une case
       qui porte plusieurs évènements mène au dernier ; la liste « Prochaines
       dates », juste dessous, les donne tous. */
    .rof-calendar-grid td {
        position: relative;
    }

    .rof-calendar-event::after {
        content: "";
        position: absolute;
        inset: 0;
    }
}

/* Tablette : l'intitulé reste lisible dans la case (20 px de haut), mais il se
   touche mal. Il passe à 44 px ; la case de 78 px y suffit. */
@media (min-width: 768px) and (max-width: 991.98px), (min-width: 768px) and (pointer: coarse) {
    .rof-calendar-event {
        display: flex;
        align-items: center;
        min-height: 44px;
    }
}

/* --------------------------------------------------------------------------
   Tableaux empilés (historique des achats, panier de la boutique)

   Cinq colonnes dans 288 px : le tableau défilait latéralement dans son cadre, et le statut
   de la commande, « Reprendre le paiement », « Facture PDF » et la corbeille restaient hors
   de l'écran. Sous 768 px, chaque ligne devient une fiche ; l'attribut data-label de chaque
   cellule en nomme la valeur.
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {

    .rof-table-stack thead {
        position: absolute;
        width: 1px;
        height: 1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
    }

    .rof-table-stack,
    .rof-table-stack tbody,
    .rof-table-stack tr,
    .rof-table-stack td {
        display: block;
        width: 100%;
    }

    .rof-table-stack tbody tr {
        margin: 0 0 12px;
        padding: 10px 14px;
        border: 1px solid var(--rof-border);
        border-radius: var(--rof-radius-md);
        background: var(--rof-card-bg);
    }

    /* Dans une carte sans marge (le panier), les fiches ne doivent pas toucher les bords. */
    .card-body.p-0 .rof-table-stack tbody {
        padding: 12px 12px 0;
    }

    .rof-table-stack td {
        padding: 6px 0;
        border: 0;
        text-align: left !important;
    }

    .rof-table-stack td[data-label]::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 2px;
        font-family: var(--font-ui);
        font-size: var(--fs-xs);
        font-weight: 700;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--rof-text-muted);
    }

    .rof-table-stack td:not([data-label]):empty {
        display: none;
    }

    /* Total du panier : la ligne de pied se lit comme les autres, libellé à gauche, montant à droite. */
    .rof-table-stack tfoot,
    .rof-table-stack tfoot tr {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        width: 100%;
    }

    .rof-table-stack tfoot tr {
        padding: 10px 14px;
    }

    .rof-table-stack tfoot th {
        display: block;
        width: auto;
        padding: 0;
        border: 0;
    }

    .rof-table-stack tfoot th:empty {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   Éditeur de minisite : adresse simplifiée
   Le préfixe « https://www.osteo-rof.fr/ » occupe plus de la moitié d'une ligne de 375 px :
   le champ où l'on tape l'adresse se réduisait à une dizaine de caractères. Le préfixe passe
   au-dessus, le champ dessous, chacun sur toute la largeur.
   -------------------------------------------------------------------------- */
@media (max-width: 575.98px) {

    .rof-slug-group > .input-group-text,
    .rof-slug-group > .form-control {
        flex: 1 1 100%;
        width: 100%;
    }

    .rof-slug-group > .input-group-text {
        border-radius: var(--bs-border-radius-sm) var(--bs-border-radius-sm) 0 0 !important;
        border-bottom: 0;
    }

    .rof-slug-group > .form-control {
        margin-left: 0 !important;
        border-radius: 0 0 var(--bs-border-radius-sm) var(--bs-border-radius-sm) !important;
    }
}

/* --------------------------------------------------------------------------
   Éditeur de texte riche (annonces, éditeur de minisite)

   Sa barre d'outils est de type « MultiRow » : les 32 commandes se replient sur autant de
   rangées que la largeur l'impose. Sur 375 px, cela fait 281 px de haut (369 avec le mode
   tactile) pour une boîte de l'éditeur fixée à 160–220 px : la zone de saisie mesurait
   0 px, et l'on ne pouvait rien écrire. La barre passe sur UNE rangée que l'on fait
   glisser, et la zone de saisie retrouve sa hauteur.
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px) {

    .e-richtexteditor .e-toolbar .e-toolbar-items.e-toolbar-multirow {
        /* « inline-flex » donnait au conteneur la largeur de ses 32 commandes
           (1 614 px) : aucun défilement n'avait lieu, la barre était simplement coupée. */
        display: flex;
        width: 100%;
        max-width: 100%;
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        scrollbar-width: thin;
        -webkit-overflow-scrolling: touch;
    }

    .e-richtexteditor .e-toolbar .e-toolbar-items.e-toolbar-multirow > .e-toolbar-item {
        flex: none;
    }

    /* Le mode tactile de Syncfusion porte les boutons de 32 à 38 px ; le doigt en demande 44.
       Ses propres règles fixent min-height avec une spécificité supérieure : d'où !important. */
    .e-richtexteditor .e-toolbar .e-toolbar-item,
    .e-richtexteditor .e-toolbar .e-toolbar-item button {
        min-height: 44px !important;
    }

    .e-richtexteditor .e-toolbar .e-toolbar-item button {
        min-width: 44px !important;
    }
}

/* --------------------------------------------------------------------------
   Pages à rouler : contenu éditorial
   -------------------------------------------------------------------------- */
@media (max-width: 575.98px) {

    /* Un tableau ou une image collés dans un éditeur riche ne dépassent jamais
       la colonne. */
    .rof-prose img,
    .rof-prose iframe,
    .rof-prose video {
        max-width: 100%;
        height: auto;
    }
}
