/* Author: MEMORA solutions, https://memora.solutions ; info@memora.ca */
/* Minuteur visuel — styles des 5 cadrans (disque, sablier, anneau, chiffres, feu de circulation). */

[x-cloak] { display: none !important; }

/* --- #713/#714 (2026-07-05) : gabarit réaligné sur les autres outils gratuits ---
   Les exceptions précédentes (#706 col-lg-10 isolé, #708 container-fluid, #711 grille 2 colonnes)
   ont été retirées : le blade utilise `.container` + `.col-lg-10`, désormais la largeur STANDARD
   de tous les outils "carte unique" du site (élargie site-wide en #714, generateur-mots-passe/
   tirage-presentations/etc. inclus — l'espace vide signalé n'était pas un bug du minuteur mais
   le gabarit col-lg-8 partagé par 6 outils, tous portés à col-lg-10 ensemble).
   AUCUN plafond de largeur ici (contrairement à l'ancien max-width:640px) : comme les autres
   outils, la carte (.card, Bootstrap) remplit naturellement sa colonne — le cadran garde son
   propre plafond (.mv-dial-zone, 400px) et les groupes de boutons restent centrés via flex, donc
   rien ne s'étire de façon disgracieuse. Un plafond ici recréerait exactement le problème de
   #711 (bandes vides à l'intérieur d'une carte redevenue large). */
.mv-wrap { margin: 0 auto; }

/* Séparateur discret entre le cadran (le "spectacle") et les contrôles (l'"outil") — hiérarchie
   visuelle en une seule colonne, sans réintroduire de grille 2 colonnes. */
.mv-divider {
    border: none;
    border-top: 1px solid var(--sys-border-subtle, #E5E7EB);
    margin: 1.75rem 0 1.5rem;
}

/* --- Sélecteurs (style + couleur) ---
   Boutons de style : classes charte ct-btn (ct-btn-outline au repos / ct-btn-primary actif),
   pas de bordure ad hoc — cohérent avec tirage-presentations/constructeur-prompts. */
.mv-style-selector,
.mv-color-selector {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: center;
    margin: 0 0 1.25rem;
}

/* Swatches de couleur : pastilles pleines (pas de bouton texte) — le seul moyen sensé d'indiquer
   « sélectionné » est un anneau autour de la couleur elle-même (pattern standard des sélecteurs
   de couleur), pas une bordure de bouton texte. Anneau via box-shadow (jamais `border` de contour). */
.mv-color-btn {
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
    border-radius: 50%;
    border: 3px solid #fff;
    box-shadow: 0 0 0 1.5px var(--sys-border-subtle, #E5E7EB);
    cursor: pointer;
    padding: 0;
    transition: transform .15s ease, box-shadow .15s ease;
}
.mv-color-btn:hover { transform: scale(1.1); }
.mv-color-btn:focus-visible { outline: 3px solid var(--c-accent, #9A2A06); outline-offset: 2px; }
.mv-color-btn.active { box-shadow: 0 0 0 2.5px var(--c-dark, #1A1D23); }
/* #742 : 6e swatch "couleur personnalisée" - un <label> habillé comme les boutons ronds
   ci-dessus, avec l'<input type="color"> natif invisible mais superposé (pleine taille,
   opacity:0) pour garder l'accessibilité clavier/lecteur d'écran native du color picker OS,
   sans avoir à réimplémenter un picker maison. */
.mv-color-btn--custom {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
}
.mv-color-custom-input {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    border: none;
    opacity: 0;
    cursor: pointer;
}
.mv-color-btn--custom-icon {
    font-size: 1.1rem;
    font-weight: 700;
    color: var(--c-text-muted, #52586a);
    pointer-events: none;
}

/* #787-792 : bouton étoile "épingler cette couleur" - même classe .mv-pin-btn que les durées
   (44x44 AAA), simplement inline avec un libellé texte (pas à côté d'un bouton "Définir" ici). */
.mv-color-favorite-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    margin: -.25rem 0 .75rem;
}
.mv-color-favorite-toggle__label {
    font-size: .8rem;
    color: var(--c-text-muted, #52586a);
}

/* #787-792 : couleurs favorites épinglées (max 2) - chip bordée avec pastille + bouton × propre
   segment cliquable (pattern chip 2026, cf. .mv-preset-pinned pour les durées), jamais un rond
   flottant hors-cadre. */
.mv-favorite-colors {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    justify-content: center;
    margin: -.5rem 0 1.25rem;
}
.mv-favorite-color-chip {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    background: #fff;
    border: 1px solid var(--sys-border-subtle, #E5E7EB);
    border-radius: 999px;
    padding: .2rem .3rem;
}
/* #812-815 : ces boutons ont aria-label="Retirer ..." (nécessaire pour l'accessibilité), ce qui
   les fait matcher malencontreusement la règle globale charte.css `[aria-label*="Retirer"]`
   (pensée pour un bouton "vote/soutenir" ailleurs sur le site) qui force border/background à
   none en !important. D'où le doublement de sélecteur (spécificité) + !important ici, sinon le
   fond/bordure du bouton × disparaît silencieusement (bug détecté en capture utilisateur - le ×
   semblait "flottant" hors du chip faute de fond/bordure visibles). */
.mv-favorite-color-chip .mv-favorite-color-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
    border: none !important;
    border-radius: 50%;
    background: transparent !important;
    color: var(--c-text-muted, #52586a);
    font-size: .9rem;
    line-height: 1;
    padding: 0;
    cursor: pointer;
}
.mv-favorite-color-chip .mv-favorite-color-remove:hover { background: var(--c-danger, #DC2626) !important; color: #fff; }
.mv-favorite-color-chip .mv-favorite-color-remove:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/* #744-750 : couleurs personnalisées récentes (connectés seulement) - rangée discrète sous le
   sélecteur, mêmes pastilles que .mv-color-btn mais plus petites (rôle secondaire de rappel). */
.mv-recent-colors {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem;
    justify-content: center;
    margin: -.5rem 0 1.25rem;
}
.mv-recent-colors-label {
    font-size: .75rem;
    color: var(--c-text-muted, #52586a);
}
.mv-color-btn-recent {
    width: 26px;
    height: 26px;
    min-width: 26px;
    min-height: 26px;
}

/* Bandeau d'incitation à la connexion (invités) - mêmes tons que le rappel de sauvegarde des
   autres outils (roue-tirage), pour une cohérence visuelle site-wide. */
.mv-login-hint {
    background: #f0f9ff;
    border: 1px solid #bae6fd;
    border-radius: 10px;
    padding: .6rem .9rem;
    margin: -.5rem 0 1.25rem;
    font-size: .85rem;
    color: #0369a1;
    text-align: center;
}
.mv-login-hint a {
    color: #0369a1;
    font-weight: 700;
    text-decoration: underline;
    margin-left: .25rem;
}

/* #746 : bandeau "animations réduites" - visible immédiatement (pas caché dans "Réglages"),
   même gabarit que .mv-login-hint pour cohérence visuelle, ton ambre (information neutre,
   pas une erreur) plutôt que bleu pour se distinguer du bandeau de connexion. Contraste
   vérifié AAA via wcag_check_contrast : #78350f sur #fffbeb = 8.75:1, #78350f sur #fef3c7
   (bouton) = 8.15:1. */
.mv-motion-hint {
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-radius: 10px;
    padding: .6rem .9rem;
    margin: 0 0 1.25rem;
    font-size: .85rem;
    color: #78350f;
    text-align: center;
}
.mv-motion-hint button {
    display: inline-block;
    margin-left: .5rem;
    background: #fef3c7;
    border: 1px solid #fde68a;
    border-radius: 8px;
    padding: .25rem .6rem;
    font-size: .85rem;
    font-weight: 700;
    color: #78350f;
    cursor: pointer;
    text-decoration: underline;
}
.mv-motion-hint button:hover,
.mv-motion-hint button:focus-visible {
    background: #fde68a;
}

/* --- Zone visuelle du cadran ---
   #713 : 520px -> 400px (col-lg-8 standard). #714 : 400px -> 440px (carte élargie à col-lg-10
   site-wide, cf. .mv-wrap) — léger réajustement proportionné, toujours loin de l'ancienne
   exception 520px qui faisait "dominer" le cadran. Fond circulaire doux (radial-gradient)
   derrière le cadran : mise en scène discrète qui lui donne du relief sans agrandir la carte
   elle-même — c'est la composition, pas la taille, qui porte la présentation. */
.mv-dial-zone {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 1.5rem;
    width: min(70vw, 440px);
    max-width: 440px;
    aspect-ratio: 1 / 1;
    position: relative;
    /* #719 : confine le mix-blend-mode du chiffre central (voir .mv-style-disk .mv-center-display
       plus bas) à cette zone — sans isolation, le blend "fuiterait" et affecterait le rendu
       d'éléments situés SOUS tout .mv-dial-zone dans l'arbre d'empilement (carte, fond de page). */
    isolation: isolate;
}
.mv-dial-zone::before {
    content: '';
    position: absolute;
    inset: -6%;
    border-radius: 50%;
    background: radial-gradient(circle, var(--c-primary, #064E5A) 0%, transparent 72%);
    opacity: .05;
    z-index: -1;
}
/* !important nécessaire : un reset global d'icônes du thème (svg { width/height: 24px }) a une
   spécificité concurrente et écraserait sinon la mise à l'échelle du cadran (SVG à viewBox). */
.mv-dial-zone svg { width: 100% !important; height: 100% !important; max-width: none !important; max-height: none !important; display: block; }

.mv-ring-track { fill: none; stroke: #E5E7EB; stroke-width: 12; }
.mv-ring-progress {
    fill: none;
    stroke-width: 12;
    stroke-linecap: round;
    transition: stroke-dashoffset .3s linear, stroke .2s ease;
}

.mv-disk-face { fill: #fff; stroke: #E5E7EB; stroke-width: 2; }
.mv-disk-slice { transition: d .3s linear, fill .2s ease; }
.mv-disk-knob { fill: var(--c-dark, #1A1D23); opacity: .35; }
.mv-tick { stroke: #C7CDD6; stroke-width: 1.5; }
.mv-tick-major { stroke: #9AA3B2; stroke-width: 2.5; }
/* #718 : couche 2 des graduations, peinte APRÈS le secteur coloré (voir minuteur-visuel.blade.php).
   Ton blanc = strictement identique au fill de .mv-disk-face (#fff) : invisible sur la face
   blanche (aucune graduation dupliquée visible là où le secteur n'a pas encore progressé),
   nettement visible sur les 5 teintes sombres de la palette une fois recouvertes. */
.mv-tick-overlay { stroke: #fff; stroke-width: 1.5; opacity: .55; }
.mv-tick-overlay-major { stroke: #fff; stroke-width: 2.5; opacity: .8; }

/* Verre : dégradé translucide (au lieu d'un brun uni plat) + ombre douce sur tout le cadran sablier
   pour suggérer l'épaisseur du verre, sans toucher à la géométrie des paths (angles droits inchangés). */
.mv-hourglass-frame { fill: none; stroke: url(#mvGlassGradient); stroke-opacity: .92; stroke-width: 3; stroke-linejoin: round; }
.mv-style-hourglass svg { filter: drop-shadow(0 3px 6px rgba(0,0,0,.18)); }

/* Sable : dégradé vertical (relief) + texture de grain (feTurbulence, mix-blend-mode multiply)
   + fine ligne de surface ombrée à la limite du clip existant (aucun changement de hauteur/calcul JS). */
.mv-hourglass-sand { fill: url(#mvSandGradient); transition: y .3s linear, height .3s linear; }
/* Garde-fou défensif : si le filtre feTurbulence échoue à s'appliquer pour une raison
   quelconque (moteur de rendu), le pire cas visuel doit être un rect quasi invisible à 7%,
   jamais le fill noir opaque par défaut d'un <rect> SVG sans fill explicite. */
.mv-hourglass-sand-grain { filter: url(#mvSandGrain); mix-blend-mode: multiply; opacity: .07; transition: y .3s linear, height .3s linear; }
.mv-hourglass-sand-surface { fill: rgba(0, 0, 0, .14); transition: y .3s linear; }
.mv-hourglass-stream { stroke: #D4A574; stroke-width: 2; opacity: .8; }
.mv-hourglass-stream.is-running:not(.mv-reduced-motion .mv-hourglass-stream) {
    animation: mv-stream-flow 0.6s linear infinite;
}

/* #765-770 (v2, corrige un retour utilisateur : le v1 dispersait les grains en diagonale au lieu
   d'un filet cohérent, et la course était trop courte pour atteindre visiblement le bulbe du
   bas) : 9 grains individuels tombent en ligne DROITE (dérive latérale quasi nulle - la neige
   d'un vrai sablier ne part pas en éventail au passage du goulot) sur ~54px, du haut du goulot
   jusque bien À L'INTÉRIEUR du tas du bas. Un seul @keyframes partagé, chaque grain lit ses
   propres variables CSS (--gx micro-dérive, --gd délai, --gdur vitesse) posées en style inline
   par le Blade : plusieurs grains visibles à des hauteurs différentes du même filet à tout
   instant, comme un vrai écoulement - pas de contour blanc (donnait un effet "œuf tacheté" à
   cette petite taille), fill uni à fort contraste sur le fond clair du goulot. */
.mv-sand-grain-particle { fill: #3D2410; opacity: 0; }
.mv-sand-stream.is-running .mv-sand-grain-particle {
    animation: mv-grain-fall var(--gdur, 1.1s) linear infinite;
    animation-delay: var(--gd, 0s);
}
@keyframes mv-grain-fall {
    0%   { transform: translate(0, -16px) scale(.9); opacity: 0; }
    8%   { opacity: 1; }
    /* Opacité maintenue à 1 jusqu'à 85% du trajet (pas un fondu linéaire sur toute la chute,
       sinon le grain est quasi invisible bien avant d'atteindre le bas - c'est ce qui donnait
       l'impression qu'il "ne tombe pas en bas") : le grain reste net tout le long de la
       descente, ne s'estompe qu'à l'arrivée dans le tas.
       Course verticale recalibrée (v3, grille de calibrage sur viewBox 200x260) : départ
       y≈114 (juste au-dessus du goulot y=130), arrivée y≈180 (translateY +50, bien À
       L'INTÉRIEUR du triangle du bas dont la largeur à cette hauteur est déjà d'environ 63
       unités - donc visiblement dans le tas, pas juste au bord du goulot comme avant
       (translateY +38 ne portait qu'à y≈168, trop proche du sommet du triangle). */
    85%  { opacity: 1; transform: translate(calc(var(--gx, 0px) * .85), 46px) scale(.82); }
    100% { transform: translate(var(--gx, 0px), 50px) scale(.8); opacity: 0; }
}

.mv-traffic-circle { stroke: #D1D5DB; stroke-width: 3; transition: fill .3s ease, opacity .3s ease; }
.mv-traffic-circle.mv-off { fill: #E5E7EB; opacity: .5; }
.mv-traffic-circle.mv-green.mv-on { fill: #15803D; }
.mv-traffic-circle.mv-yellow.mv-on { fill: #CA8A04; }
.mv-traffic-circle.mv-red.mv-on { fill: #B91C1C; }

/* Chiffres / flip — #759-764 : fond et couleur de texte pilotés en ligne (dialColorHex/
   flipTextColor, même palette + contraste WCAG AAA automatique que le disque/anneau) ;
   fond de repli si JS désactivé (rendu SSR uniquement). */
.mv-flip-display {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    background: var(--c-dark, #1A1D23);
    color: #fff;
    border-radius: 16px;
    font-family: 'Consolas', 'Menlo', monospace;
    font-variant-numeric: tabular-nums;
    font-size: clamp(2.5rem, 12vw, 4.5rem);
    font-weight: 800;
    letter-spacing: 2px;
}

/* --- Affichage central mm:ss superposé, À L'INTÉRIEUR du cadran (tous styles) ---
   Couleur adaptée par style pour garantir le contraste avec ce qu'il y a dessous :
   blanc sur le disque (secteur coloré plein) et le feu (plaque foncée), sombre sur
   l'anneau/le sablier (fond carte blanc au centre). */
.mv-dial-zone { position: relative; }
.mv-center-display {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Consolas', 'Menlo', monospace;
    font-variant-numeric: tabular-nums;
    font-size: clamp(2.25rem, 11vw, 4rem);
    font-weight: 800;
    color: var(--c-dark, #1A1D23);
    pointer-events: none;
}
.mv-style-traffic .mv-center-display { color: #fff; }
/* #740/#741 : le secteur du disque est un triangle dont la pointe part exactement du centre -
   là où le chiffre est affiché - donc AUCUNE couleur de texte unique ne peut rester lisible
   des deux côtés à la fois. Un premier essai (mix-blend-mode: difference) produisait une
   teinte inversée émergente (rouge -> cyan) au lieu du "blanc sur couleur / noir sur blanc"
   demandé. Remplacé par un vrai double calque (voir minuteur-visuel.blade.php) :
   - .mv-center-display--base : TOUJOURS foncé, visible partout où le secteur coloré n'a pas
     encore progressé (la face blanche du cadran).
   - .mv-center-display--accent : découpé EXACTEMENT sur le secteur coloré (clip-path url()
     vers un <clipPath objectBoundingBox> partageant le même tracé que .mv-disk-slice) ;
     couleur choisie AUTOMATIQUEMENT (JS, diskAccentTextColor) selon le contraste réel contre
     l'accent - blanc par défaut, mais foncé si l'accent est trop pâle, curatée ou personnalisée. */
.mv-style-disk .mv-center-display--base {
    color: var(--c-dark, #1A1D23);
}
.mv-style-hourglass .mv-center-display { font-size: clamp(1.5rem, 7vw, 2.25rem); }
/* #709 : plafond réduit (2.75rem -> 2rem) en cohérence avec le rayon des cercles réduit
   34 -> 28 (voir minuteur-visuel.blade.php, bloc style === 'traffic') : le cercle du milieu
   est maintenant plus petit, un texte trop grand y déborderait à nouveau. */
.mv-style-traffic .mv-center-display { font-size: clamp(1.4rem, 6vw, 2rem); }

/* --- Légende du feu de circulation — seuils réels (mm:ss), une ligne par couleur --- */
.mv-traffic-legend {
    text-align: center;
    font-size: .85rem;
    color: var(--c-dark, #1A1D23);
    margin: .75rem auto 0;
    max-width: 32rem;
    line-height: 1.6;
}
.mv-traffic-legend__line { margin: 0 0 .2rem; opacity: .85; }
.mv-traffic-legend__note { margin: .4rem 0 0; opacity: .7; font-style: italic; }

/* --- Live region ARIA (lecteurs d'écran uniquement) ---
   #837-840 : rendue visuellement masquée (pattern sr-only standard) - le message
   ("14 minutes restantes") dupliquait purement le mm:ss déjà affiché en continu au centre du
   cadran, signalé comme inutile à l'écran par l'utilisateur. L'annonce reste dans le DOM et
   continue de fonctionner pour les lecteurs d'écran (aria-live="polite" inchangé côté blade/JS). */
.mv-live {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --- Contrôles & présélections ---
   Boutons = classes charte (ct-btn / ct-btn-outline / ct-btn-primary / ct-btn-accent / ct-btn-sm),
   aucune classe/bordure ad hoc ici — voir minuteur-visuel.blade.php. On complète seulement
   ce que le système ct-btn ne couvre pas déjà (disposition + état désactivé, cibles 44px). */
.mv-controls {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    justify-content: center;
    align-items: center;
    margin-bottom: 1.25rem;
}
.mv-controls .ct-btn,
.mv-presets .ct-btn,
.mv-custom-time .ct-btn { min-height: 44px; }
.mv-wrap .ct-btn:disabled { opacity: .5; cursor: not-allowed; }

.mv-presets {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: center;
    margin-bottom: .6rem;
}
/* Les 2 groupes (durées simples, Pomodoro) sont désormais des lignes déliberées (#751-758) —
   le dernier garde la marge normale avant la durée personnalisée. */
.mv-presets:last-of-type { margin-bottom: 1.5rem; }

/* #782-786 : durée personnalisée épinglée - le × est désormais un segment intégré à même la
   pastille (chip Material 3 / shadcn « dismissible tag », tendance 2026 confirmée pp_search),
   pas un petit rond flottant hors-cadre (ancien pattern, sous le seuil WCAG 24px + peu lisible). */
/* #840-843 : bordure UNIQUE portée par le conteneur englobant (pattern chip 2026 confirmé par
   pp_search : "one chip container with an integrated trailing remove button, not two visibly
   segmented bordered parts" - Material 3 / shadcn). Remplace l'ancienne approche où CHAQUE
   segment (bouton durée + bouton ×) portait sa propre bordure de 2px collées l'une à l'autre :
   fragile par nature (cause réelle d'un bug signalé - un composant Blade sans lien avec cette
   page redéfinissait ailleurs la classe .ct-btn partagée, réduisant silencieusement sa bordure
   à 1px pile à cette jonction, ce qui créait un "step" visible lu comme une 2e forme imbriquée).
   Une seule bordure sur .mv-preset-pinned + overflow:hidden pour clipper les coins des enfants
   (rendus totalement sans bordure propre) élimine structurellement tout risque de dédoublement
   ou de désalignement à la jonction, quel que soit ce qui arrive à .ct-btn par ailleurs. */
.mv-preset-pinned {
    display: inline-flex;
    align-items: stretch;
    border: 2px solid var(--c-primary);
    border-radius: var(--r-btn);
    overflow: hidden;
}
.mv-preset-pinned .ct-btn {
    border: none !important;
    border-radius: 0;
}
/* #812-815 : aria-label="Retirer ..." (accessibilité) matche par accident la règle globale
   charte.css `[aria-label*="Retirer"]` (pensée pour un bouton "vote/soutenir" ailleurs sur le
   site) qui force border/background à none en !important - conservé ici en !important sur le
   fond (le × doit rester visible), mais la bordure est désormais entièrement retirée (c'est le
   conteneur .mv-preset-pinned qui porte l'unique bordure du chip). */
.mv-preset-pinned .mv-preset-pinned__remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    min-height: 28px;
    padding: 0 8px;
    border: none !important;
    border-left: 1px solid rgba(6, 78, 90, .25) !important;
    border-radius: 0;
    background: #fff !important;
    color: var(--c-text-muted, #52586a);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    flex: 0 0 auto;
}
.mv-preset-pinned .mv-preset-pinned__remove:hover { background: var(--c-danger, #DC2626) !important; color: #fff; }
.mv-preset-pinned .mv-preset-pinned__remove:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/* Bouton étoile "épingler cette durée/couleur" - à côté de "Définir", même hauteur de cible
   tactile. #812-815 : son aria-label devient "Retirer ..." une fois actif (favoris couleur),
   ce qui matche par accident la règle globale charte.css `[aria-label*="Retirer"]` (!important) -
   border/background forcés en !important ici pour ne pas perdre l'apparence au bascule actif. */
.mv-pin-btn {
    min-width: 44px;
    min-height: 44px;
    border-radius: 8px;
    border: 1.5px solid var(--sys-border-subtle, #E5E7EB) !important;
    background: #fff !important;
    font-size: 1.2rem;
    cursor: pointer;
    color: var(--c-text-muted, #52586a);
}
.mv-pin-btn.active { color: #B45309; border-color: #B45309; }
.mv-pin-btn:disabled { opacity: .4; cursor: not-allowed; }

/* --- Durée personnalisée — saisie exacte en minutes, alignée avec .mv-presets --- */
.mv-custom-time {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .6rem;
    margin-bottom: 1.5rem;
}
.mv-custom-time label {
    font-size: .9rem;
    font-weight: 600;
    color: var(--c-dark, #1A1D23);
}
.mv-custom-time input[type="number"] {
    width: 90px;
    min-height: 44px;
    padding: .4rem .6rem;
    border: 1.5px solid var(--c-primary, #064E5A);
    border-radius: 8px;
    font-size: 1rem;
    text-align: center;
}

/* --- Réglages accessibilité --- */
.mv-settings { margin-bottom: 1rem; }
.mv-settings summary {
    cursor: pointer;
    font-family: var(--f-heading, 'Plus Jakarta Sans', sans-serif);
    font-weight: 700;
    color: var(--c-dark, #1A1D23);
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    list-style: none;
    padding: 0 12px;
    border: 1px solid var(--c-primary, #064E5A);
    border-radius: var(--r-btn, 8px);
    outline-offset: 2px;
}
.mv-settings summary::-webkit-details-marker { display: none; }
.mv-settings__chevron { color: var(--c-primary, #064E5A); font-size: .75rem; transition: transform .2s ease; flex-shrink: 0; }
.mv-settings[open] summary .mv-settings__chevron { transform: rotate(180deg); }
.mv-settings__body {
    display: grid;
    gap: .75rem;
    padding: 1rem;
    background: #f8f9fa;
    border-radius: 10px;
    margin-top: .5rem;
}
.mv-settings__row { display: flex; align-items: center; justify-content: space-between; gap: 1rem; font-size: .9rem; }
.mv-settings__row input[type="number"] {
    width: 80px;
    padding: .4rem .6rem;
    border: 1.5px solid #E5E7EB;
    border-radius: 8px;
    font-size: .9rem;
}

/* #831-836 : sous-sections groupées à l'intérieur du panneau unique "Réglages et
   personnalisations" (fusion de l'ancien 2e disclosure .mv-color-manager) - veille pp_search
   2026 confirmée : un seul accordéon avec des sous-titres légers plutôt que plusieurs tiroirs
   empilés ou des onglets imbriqués (qui doublent le coût d'interaction pour un contenu qui
   n'est pas comparatif). Chaque groupe = un droit d'en-tête discret + un filet supérieur
   (sauf le premier), pas une nouvelle boîte pleine largeur qui alourdirait le panneau déjà replié. */
.mv-settings__group { display: grid; gap: .6rem; }
.mv-settings__group + .mv-settings__group {
    padding-top: .85rem;
    border-top: 1px solid var(--sys-border-subtle, #E5E7EB);
}
.mv-settings__group-title {
    margin: 0;
    font-size: .75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--c-text-muted, #52586a);
}

/* #797-801 : variante empilée (label au-dessus, pas côte-à-côte) pour les seuils du feu -
   plusieurs contrôles (profils + repli personnalisé) ne tiennent pas sur une seule ligne. */
.mv-settings__row--stack { flex-direction: column; align-items: stretch; gap: .5rem; }
.mv-traffic-profiles { display: flex; flex-wrap: wrap; gap: .4rem; }
.mv-traffic-custom { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-size: .85rem; }
.mv-traffic-custom input[type="number"] { width: 70px; }
/* #802-805 : confirmation immédiate du profil appliqué - contraste AAA vérifié (7.13:1). */
.mv-traffic-applied-hint {
    display: flex;
    align-items: center;
    gap: .35rem;
    margin: 0;
    font-size: .8rem;
    color: #166534;
}

@media (prefers-reduced-motion: reduce) {
    .mv-ring-progress, .mv-disk-slice, .mv-hourglass-sand, .mv-hourglass-sand-grain, .mv-hourglass-sand-surface, .mv-sand-grain-particle, .ct-btn {
        transition: none !important;
        animation: none !important;
    }
}
.mv-reduced-motion .mv-ring-progress,
.mv-reduced-motion .mv-disk-slice,
.mv-reduced-motion .mv-hourglass-sand,
.mv-reduced-motion .mv-hourglass-sand-grain,
.mv-reduced-motion .mv-hourglass-sand-surface,
.mv-reduced-motion .mv-sand-grain-particle {
    transition: none !important;
    animation: none !important;
}

@keyframes mv-stream-flow {
    0% { opacity: .4; }
    50% { opacity: 1; }
    100% { opacity: .4; }
}

@media (max-width: 540px) {
    .mv-dial-zone { width: min(82vw, 300px); }
}
