| 758 | .ka-tabbar svg{transition:none} |
758 | .ka-tabbar svg{transition:none} |
| 759 | .ka-tabbar .active svg,.ka-tabbar .active::after{animation:none} |
759 | .ka-tabbar .active svg,.ka-tabbar .active::after{animation:none} |
| 760 | } |
760 | } |
| |
761 | + |
| |
762 | + |
| |
763 | +/* ===================================================================== |
| |
764 | + Fiche événement premium (refonte 2026-09-07, même socle que les fiches |
| |
765 | + Lou-Ka v3 / Immo-Ka v3) — tokens --sk-*, styles SCOPÉS sous .sk-*. |
| |
766 | + Fond papier, cartes blanches bord 1 px, FRAMBOISE réservée aux CTA / prix / |
| |
767 | + états actifs. Aucun `order` : ordre DOM = ordre visuel. |
| |
768 | + ===================================================================== */ |
| |
769 | +:root{ |
| |
770 | + --sk-bg:#f5f3ee; --sk-surface:#ffffff; --sk-surface-2:#faf9f5; |
| |
771 | + --sk-border:#e6e3dc; --sk-border-2:#d3cfc6; |
| |
772 | + --sk-text:#141814; --sk-text-2:#4d5551; --sk-muted:#7c837e; |
| |
773 | + --sk-accent:#d6336c; --sk-accent-deep:#a12551; --sk-accent-soft:#fbe0eb; |
| |
774 | + --sk-success:#1e7b4a; --sk-success-soft:#e7f4ec; --sk-warning:#a8690a; --sk-warning-soft:#fcf3e1; |
| |
775 | + --sk-danger:#b3423a; --sk-danger-soft:#fbe9e7; --sk-info:#3b5bdb; --sk-info-soft:#e9edfb; |
| |
776 | + --sk-r-sm:10px; --sk-r-md:14px; --sk-r-lg:18px; --sk-r-xl:22px; |
| |
777 | + --sk-shadow-sm:0 2px 12px rgba(0,0,0,.04); --sk-shadow-md:0 8px 28px rgba(0,0,0,.07); |
| |
778 | + --sk-header-h:56px; --sk-nav-h:52px; |
| |
779 | +} |
| |
780 | +body.sk-fiche-page{background:var(--sk-bg)} |
| |
781 | +body.sk-fiche-page .ticker{display:none} |
| |
782 | +body.sk-fiche-page .ka-tabbar{display:none!important} |
| |
783 | +body.sk-fiche-page .kaa-btn,body.sk-fiche-page .kaa-hello{display:none!important} |
| |
784 | +body.sk-fiche-page .header{background:rgba(245,243,238,.92);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--sk-border)} |
| |
785 | +body.sk-fiche-page .header-inner{min-height:var(--sk-header-h);gap:10px} |
| |
786 | +body.sk-fiche-page .header .brand{font-size:21px} |
| |
787 | +body.sk-fiche-page .header .brand-tag,body.sk-fiche-page .header .gk-badge{display:none} |
| |
788 | +body.sk-fiche-page .header .nav{margin-left:0} |
| |
789 | +.hdr-actions{display:flex;align-items:center;gap:6px;margin-left:auto} |
| |
790 | +.hdr-btn{display:inline-grid;place-items:center;width:40px;height:40px;border-radius:999px;border:1px solid var(--sk-border); |
| |
791 | + background:var(--sk-surface);color:var(--sk-text);cursor:pointer;padding:0;transition:background .15s,transform .15s} |
| |
792 | +.hdr-btn:active{transform:scale(.95)} |
| |
793 | +.hdr-btn.on{color:var(--sk-accent);border-color:var(--sk-accent);background:var(--sk-accent-soft)} |
| |
794 | +@media(hover:hover){.hdr-btn:hover{background:var(--sk-surface-2)}} |
| |
795 | +/* le cœur ♥ existant, posé dans la rangée d'actions de la fiche */ |
| |
796 | +.sk-fiche .fav-btn{position:static;width:46px;height:46px;border-radius:12px;border:1px solid var(--sk-border);background:var(--sk-surface);color:var(--sk-text);box-shadow:none} |
| |
797 | +.sk-fiche .fav-btn.on{color:var(--sk-accent);border-color:var(--sk-accent);background:var(--sk-accent-soft)} |
| |
798 | +.sk-fiche .fav-btn svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2} |
| |
799 | +.sk-fiche .fav-btn.on svg{fill:currentColor} |
| |
800 | +/* ---- gabarit ---- */ |
| |
801 | +.sk-fiche { padding: 10px 0 110px; color: var(--sk-text); } |
| |
802 | +.sk-wrap { max-width: 1200px; margin: 0 auto; padding: 0 16px; } |
| |
803 | +.sk-grid { display: block; } |
| |
804 | +.sk-main { min-width: 0; display: flex; flex-direction: column; gap: 14px; } |
| |
805 | +.sk-aside { display: none; } |
| |
806 | +@media (min-width: 768px) { |
| |
807 | + .sk-wrap { padding: 0 24px; } |
| |
808 | + .sk-fiche { padding-top: 18px; } |
| |
809 | + .sk-main { gap: 16px; } |
| |
810 | +} |
| |
811 | +@media (min-width: 1024px) { |
| |
812 | + .sk-grid { display: grid; grid-template-columns: minmax(0, 1fr) 356px; gap: 32px; align-items: start; } |
| |
813 | + .sk-aside { display: block; position: sticky; top: calc(var(--sk-header-h) + 16px); } |
| |
814 | + .sk-fiche { padding-bottom: 80px; } |
| |
815 | +} |
| |
816 | +.sk-crumbs { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--sk-muted); margin: 0 0 10px; } |
| |
817 | +.sk-crumbs a { color: var(--sk-text-2); } |
| |
818 | +.sk-crumbs span:last-child { color: var(--sk-text); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 60vw; } |
| |
819 | +.sk-fiche section[id] { scroll-margin-top: calc(var(--sk-header-h) + var(--sk-nav-h) + 10px); } |
| |
820 | + |
| |
821 | +/* ---- carte de section ---- */ |
| |
822 | +.sk-card { |
| |
823 | + background: var(--sk-surface); border: 1px solid var(--sk-border); |
| |
824 | + border-radius: var(--sk-r-lg); box-shadow: var(--sk-shadow-sm); |
| |
825 | + padding: 16px; min-width: 0; |
| |
826 | +} |
| |
827 | +@media (min-width: 768px) { .sk-card { padding: 20px 22px; } } |
| |
828 | +.sk-card-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; } |
| |
829 | +.sk-card-title { display: flex; align-items: center; gap: 9px; margin: 0; font-family: var(--font-display); font-weight: 700; font-size: 17px; line-height: 1.2; letter-spacing: -0.02em; color: var(--sk-text); } |
| |
830 | +.sk-card-title svg { color: var(--sk-accent-deep); flex: none; } |
| |
831 | +.sk-card-sub { font-size: 12.5px; color: var(--sk-muted); margin: 3px 0 0; } |
| |
832 | +.sk-card-aside { flex: none; display: flex; align-items: center; gap: 8px; } |
| |
833 | +.sk-link { background: none; border: 0; padding: 0; color: var(--sk-text-2); font: 600 13px var(--font-body); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--sk-border-2); } |
| |
834 | +.sk-link:hover { color: var(--sk-accent-deep); } |
| |
835 | +.sk-more { |
| |
836 | + display: inline-flex; align-items: center; justify-content: center; gap: 8px; |
| |
837 | + width: 100%; min-height: 44px; margin-top: 12px; padding: 8px 14px; |
| |
838 | + border: 1px solid var(--sk-border); border-radius: var(--sk-r-sm); background: var(--sk-surface); |
| |
839 | + color: var(--sk-text); font: 600 13.5px var(--font-body); cursor: pointer; |
| |
840 | + transition: background 0.15s, border-color 0.15s; |
| |
841 | +} |
| |
842 | +.sk-more:hover { background: var(--sk-surface-2); border-color: var(--sk-border-2); } |
| |
843 | +.sk-more svg { color: var(--sk-muted); } |
| |
844 | + |
| |
845 | +/* ---- boutons ---- */ |
| |
846 | +.sk-btn { |
| |
847 | + display: inline-flex; align-items: center; justify-content: center; gap: 8px; |
| |
848 | + min-height: 46px; padding: 10px 16px; border-radius: 12px; border: 1px solid transparent; |
| |
849 | + font: 600 14.5px var(--font-body); cursor: pointer; text-decoration: none; |
| |
850 | + transition: transform 0.12s, background 0.15s, box-shadow 0.15s; white-space: nowrap; |
| |
851 | +} |
| |
852 | +.sk-btn:active { transform: translateY(1px); } |
| |
853 | +.sk-btn-primary { background: var(--sk-accent); color: #fff; box-shadow: 0 6px 18px rgba(226, 55, 68, 0.22); } |
| |
854 | +.sk-btn-primary:hover { background: var(--sk-accent-deep); } |
| |
855 | +.sk-btn-ghost { background: var(--sk-surface); border-color: var(--sk-border); color: var(--sk-text); } |
| |
856 | +.sk-btn-ghost:hover { background: var(--sk-surface-2); border-color: var(--sk-border-2); } |
| |
857 | +.sk-btn-icon { width: 46px; padding: 0; flex: none; } |
| |
858 | +.sk-btn-icon.on { color: var(--sk-accent); border-color: var(--sk-accent); background: var(--sk-accent-soft); } |
| |
859 | + |
| |
860 | +/* ---- héro ---- */ |
| |
861 | +.sk-hero { display: flex; flex-direction: column; gap: 10px; padding: 4px 0 0; } |
| |
862 | +.sk-hero-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; } |
| |
863 | +.sk-price { font-family: var(--font-display); font-weight: 700; font-size: clamp(32px, 8.4vw, 38px); line-height: 1; letter-spacing: -0.035em; color: var(--sk-text); display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; } |
| |
864 | +.sk-price small { font: 500 14px var(--font-body); color: var(--sk-muted); letter-spacing: 0; } |
| |
865 | +.sk-price-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; } |
| |
866 | +.sk-capsule { |
| |
867 | + display: inline-flex; align-items: center; gap: 6px; padding: 5px 10px; |
| |
868 | + border-radius: 999px; font: 600 12.5px var(--font-body); border: 1px solid transparent; white-space: nowrap; |
| |
869 | +} |
| |
870 | +.sk-capsule b { font-weight: 700; } |
| |
871 | +.sk-capsule.good { background: var(--sk-success-soft); color: var(--sk-success); } |
| |
872 | +.sk-capsule.ok { background: var(--sk-surface); color: var(--sk-text-2); border-color: var(--sk-border); } |
| |
873 | +.sk-capsule.high { background: var(--sk-warning-soft); color: var(--sk-warning); } |
| |
874 | +.sk-capsule.neutral { background: var(--sk-surface-2); color: var(--sk-muted); border-color: var(--sk-border); } |
| |
875 | +.sk-capsule.brand { background: var(--sk-accent-soft); color: var(--sk-accent-deep); } |
| |
876 | +.sk-h1 { margin: 0; font-family: var(--font-body); font-weight: 600; font-size: 16px; line-height: 1.35; letter-spacing: 0; color: var(--sk-text); } |
| |
877 | +.sk-h1 .sk-city { display: block; font-weight: 500; font-size: 14px; color: var(--sk-text-2); } |
| |
878 | +.sk-summary { margin: 0; font-size: 14px; color: var(--sk-text-2); display: flex; flex-wrap: wrap; gap: 4px 8px; align-items: center; } |
| |
879 | +.sk-summary .sep { color: var(--sk-border-2); } |
| |
880 | +.sk-actions { display: flex; gap: 8px; align-items: center; } |
| |
881 | +.sk-actions .sk-btn-primary { flex: 1; } |
| |
882 | +.sk-hero .sk-actions { margin-top: 2px; } |
| |
883 | +@media (min-width: 1024px) { |
| |
884 | + .sk-hero .sk-actions { display: none; } /* actions dans l'aside sticky */ |
| |
885 | +} |
| |
886 | + |
| |
887 | +/* ---- galerie ---- */ |
| |
888 | +.sk-gallery { position: relative; border-radius: var(--sk-r-lg); overflow: hidden; background: #ecece8; } |
| |
889 | +.sk-gallery-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; aspect-ratio: 4 / 3; scrollbar-width: none; -webkit-overflow-scrolling: touch; } |
| |
890 | +.sk-gallery-track::-webkit-scrollbar { display: none; } |
| |
891 | +.sk-gallery-track img, .sk-gallery > img { flex: 0 0 100%; width: 100%; height: 100%; object-fit: cover; scroll-snap-align: center; cursor: zoom-in; display: block; } |
| |
892 | +.sk-gallery > img { aspect-ratio: 4 / 3; } |
| |
893 | +@media (min-width: 768px) { .sk-gallery-track, .sk-gallery > img { aspect-ratio: 16 / 9; } } |
| |
894 | +.sk-gallery-count { |
| |
895 | + position: absolute; left: 12px; bottom: 12px; z-index: 2; |
| |
896 | + background: rgba(20, 24, 20, 0.66); color: #fff; font: 600 12px var(--font-body); |
| |
897 | + padding: 4px 10px; border-radius: 999px; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); |
| |
898 | + font-variant-numeric: tabular-nums; |
| |
899 | +} |
| |
900 | +.sk-gallery-full, .sk-gallery-nav { |
| |
901 | + position: absolute; z-index: 2; display: grid; place-items: center; |
| |
902 | + width: 40px; height: 40px; border-radius: 999px; border: 0; cursor: pointer; |
| |
903 | + background: rgba(255, 255, 255, 0.92); color: var(--sk-text); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.12); |
| |
904 | +} |
| |
905 | +.sk-gallery-full { right: 12px; bottom: 12px; } |
| |
906 | +.sk-gallery-nav { top: 50%; transform: translateY(-50%); display: none; } |
| |
907 | +.sk-gallery-nav.prev { left: 12px; } .sk-gallery-nav.next { right: 12px; } |
| |
908 | +@media (hover: hover) and (min-width: 768px) { .sk-gallery-nav { display: grid; } } |
| |
909 | +.sk-thumbs { display: none; } |
| |
910 | +@media (min-width: 768px) { |
| |
911 | + .sk-thumbs { display: grid; grid-template-columns: repeat(auto-fill, minmax(76px, 1fr)); gap: 6px; margin-top: 8px; } |
| |
912 | + .sk-thumbs button { border: 0; padding: 0; border-radius: 8px; overflow: hidden; aspect-ratio: 4 / 3; background: #ecece8; cursor: pointer; outline-offset: 2px; opacity: 0.75; transition: opacity 0.15s; } |
| |
913 | + .sk-thumbs button.on, .sk-thumbs button:hover { opacity: 1; } |
| |
914 | + .sk-thumbs button.on { outline: 2px solid var(--sk-accent); } |
| |
915 | + .sk-thumbs img { width: 100%; height: 100%; object-fit: cover; } |
| |
916 | +} |
| |
917 | +/* lightbox (plein écran) */ |
| |
918 | +.sk-lightbox { position: fixed; inset: 0; z-index: var(--z-modal, 900); background: rgba(12, 14, 12, 0.96); } |
| |
919 | +.sk-lightbox-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; height: 100%; scrollbar-width: none; touch-action: pan-x pinch-zoom; } |
| |
920 | +.sk-lightbox-track::-webkit-scrollbar { display: none; } |
| |
921 | +.sk-lightbox-cell { flex: 0 0 100%; height: 100%; scroll-snap-align: center; display: flex; align-items: center; justify-content: center; padding: max(56px, env(safe-area-inset-top)) 10px max(28px, env(safe-area-inset-bottom)); overflow: hidden; } |
| |
922 | +.sk-lightbox-cell img { max-width: 100%; max-height: 100%; border-radius: 10px; user-select: none; -webkit-user-drag: none; will-change: transform; } |
| |
923 | +.sk-lightbox-close { position: fixed; top: max(12px, env(safe-area-inset-top)); right: 12px; z-index: 3; width: 44px; height: 44px; border-radius: 50%; border: 1px solid rgba(255, 255, 255, 0.3); background: rgba(0, 0, 0, 0.5); color: #fff; display: grid; place-items: center; cursor: pointer; } |
| |
924 | +.sk-lightbox-count { position: fixed; top: max(22px, env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); z-index: 3; color: #fff; font: 600 13px var(--font-body); background: rgba(0, 0, 0, 0.45); padding: 4px 12px; border-radius: 999px; } |
| |
925 | +.sk-lightbox .sk-gallery-nav { display: none; } |
| |
926 | +@media (hover: hover) { .sk-lightbox .sk-gallery-nav { display: grid; position: fixed; } } |
| |
927 | + |
| |
928 | +/* ---- Score ---- */ |
| |
929 | +.sk-score { display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: center; } |
| |
930 | +.sk-score-ring { position: relative; width: 88px; height: 88px; flex: none; } |
| |
931 | +.sk-score-ring svg { width: 88px; height: 88px; transform: rotate(-90deg); } |
| |
932 | +.sk-score-ring .bg { fill: none; stroke: var(--sk-surface-2); stroke-width: 7; } |
| |
933 | +.sk-score-ring .arc { fill: none; stroke: var(--sk-accent); stroke-width: 7; stroke-linecap: round; transition: stroke-dasharray 0.9s cubic-bezier(0.2, 0.8, 0.2, 1); } |
| |
934 | +.sk-score-ring .arc.partial { stroke: var(--sk-text-2); } |
| |
935 | +.sk-score-val { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--font-display); font-weight: 700; font-size: 27px; letter-spacing: -0.03em; line-height: 1; } |
| |
936 | +.sk-score-val small { display: block; text-align: center; font: 600 10px var(--font-body); color: var(--sk-muted); margin-top: 2px; letter-spacing: 0.04em; } |
| |
937 | +.sk-score-lbl { font-family: var(--font-display); font-weight: 700; font-size: 17px; letter-spacing: -0.02em; } |
| |
938 | +.sk-score-sub { font-size: 13px; color: var(--sk-text-2); margin-top: 2px; line-height: 1.4; } |
| |
939 | +.sk-score-parts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; } |
| |
940 | +.sk-score-part { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; padding: 4px 9px; border-radius: 8px; background: var(--sk-surface-2); border: 1px solid var(--sk-border); color: var(--sk-text-2); } |
| |
941 | +.sk-score-part b { color: var(--sk-text); font-variant-numeric: tabular-nums; } |
| |
942 | +.sk-score-part.na { color: var(--sk-muted); border-style: dashed; } |
| |
943 | + |
| |
944 | +/* ---- En bref ---- */ |
| |
945 | +.sk-brief { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; } |
| |
946 | +.sk-brief li { display: grid; grid-template-columns: 24px 1fr; gap: 10px; align-items: start; } |
| |
947 | +.sk-brief-ico { width: 24px; height: 24px; border-radius: 8px; display: grid; place-items: center; font-size: 12px; font-weight: 700; margin-top: 1px; } |
| |
948 | +.sk-brief-ico.good { background: var(--sk-success-soft); color: var(--sk-success); } |
| |
949 | +.sk-brief-ico.warn { background: var(--sk-warning-soft); color: var(--sk-warning); } |
| |
950 | +.sk-brief-ico.bad { background: var(--sk-danger-soft); color: var(--sk-danger); } |
| |
951 | +.sk-brief-ico.neutral { background: var(--sk-surface-2); color: var(--sk-muted); border: 1px solid var(--sk-border); } |
| |
952 | +.sk-brief-t { font-weight: 600; font-size: 14px; line-height: 1.35; } |
| |
953 | +.sk-brief-d { font-size: 13px; color: var(--sk-text-2); line-height: 1.4; margin-top: 1px; } |
| |
954 | + |
| |
955 | +/* ---- navigation par sections (sticky) ---- */ |
| |
956 | +.sk-nav { |
| |
957 | + position: sticky; top: var(--sk-header-h); z-index: var(--z-sticky, 300); |
| |
958 | + margin: 0 -16px; padding: 6px 16px; |
| |
959 | + background: rgba(245, 243, 238, 0.97); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); |
| |
960 | + border-bottom: 1px solid var(--sk-border); |
| |
961 | +} |
| |
962 | +@media (min-width: 768px) { .sk-nav { margin: 0 -24px; padding: 6px 24px; } } |
| |
963 | +@media (min-width: 1024px) { .sk-nav { margin: 0; padding: 6px 0; border-radius: 0; } } |
| |
964 | +.sk-nav-track { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; } |
| |
965 | +.sk-nav-track::-webkit-scrollbar { display: none; } |
| |
966 | +.sk-nav a { |
| |
967 | + flex: 0 0 auto; display: inline-flex; align-items: center; min-height: 40px; padding: 8px 13px; |
| |
968 | + border-radius: 999px; font: 600 13px var(--font-body); color: var(--sk-text-2); |
| |
969 | + border: 1px solid transparent; transition: background 0.15s, color 0.15s; scroll-snap-align: start; |
| |
970 | +} |
| |
971 | +.sk-nav a:hover { background: var(--sk-surface); border-color: var(--sk-border); } |
| |
972 | +.sk-nav a.on { background: var(--sk-text); color: #fff; border-color: var(--sk-text); } |
| |
973 | + |
| |
974 | +/* ---- caractéristiques ---- */ |
| |
975 | +.sk-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } |
| |
976 | +@media (min-width: 560px) { .sk-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); } } |
| |
977 | +@media (min-width: 900px) { .sk-facts { grid-template-columns: repeat(4, minmax(0, 1fr)); } } |
| |
978 | +.sk-fact { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--sk-border); border-radius: 12px; background: var(--sk-surface-2); min-width: 0; } |
| |
979 | +.sk-fact-ico { width: 32px; height: 32px; border-radius: 9px; background: var(--sk-surface); border: 1px solid var(--sk-border); display: grid; place-items: center; color: var(--sk-accent-deep); flex: none; } |
| |
980 | +.sk-fact-v { font-weight: 700; font-size: 14px; line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
981 | +.sk-fact-l { font-size: 11.5px; color: var(--sk-muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
982 | +.sk-fact-txt { min-width: 0; } |
| |
983 | +.sk-facts-rows { margin-top: 12px; } |
| |
984 | +.sk-kv { display: flex; justify-content: space-between; gap: 12px; padding: 8px 0; border-top: 1px solid var(--sk-border); font-size: 13.5px; } |
| |
985 | +.sk-kv .k { color: var(--sk-muted); } .sk-kv .v { font-weight: 600; text-align: right; } |
| |
986 | +.sk-note { margin: 10px 0 0; padding: 9px 12px; border-radius: 10px; font-size: 13px; line-height: 1.4; } |
| |
987 | +.sk-note.good { background: var(--sk-success-soft); color: var(--sk-success); } |
| |
988 | +.sk-note.info { background: var(--sk-info-soft); color: var(--sk-info); } |
| |
989 | +.sk-note.warn { background: var(--sk-warning-soft); color: var(--sk-warning); } |
| |
990 | + |
| |
991 | +/* ---- description ---- */ |
| |
992 | +.sk-desc { position: relative; } |
| |
993 | +.sk-desc-body p { font-size: 15px; line-height: 1.6; color: var(--sk-text-2); margin: 0 0 10px; white-space: pre-line; } |
| |
994 | +.sk-desc-body h4 { margin: 12px 0 3px; font: 700 14px var(--font-body); color: var(--sk-text); } |
| |
995 | +.sk-desc-lead { font-size: 15.5px !important; color: var(--sk-text) !important; font-weight: 500; } |
| |
996 | +.sk-desc.clamped .sk-desc-body { max-height: 200px; overflow: hidden; -webkit-mask-image: linear-gradient(#000 62%, transparent); mask-image: linear-gradient(#000 62%, transparent); } |
| |
997 | +.sk-desc-orig { margin-top: 8px; } |
| |
998 | +.sk-desc-orig p { font-size: 13.5px; color: var(--sk-muted); } |
| |
999 | + |
| |
1000 | +/* ---- inclusions ---- */ |
| |
1001 | +.sk-amen { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; } |
| |
1002 | +@media (min-width: 640px) { .sk-amen { grid-template-columns: repeat(3, minmax(0, 1fr)); } } |
| |
1003 | +.sk-amen-it { display: flex; align-items: center; gap: 9px; min-height: 42px; padding: 5px 0; border-bottom: 1px solid var(--sk-border); font-size: 13.5px; min-width: 0; } |
| |
1004 | +.sk-amen-ico { width: 28px; height: 28px; border-radius: 8px; background: var(--sk-accent-soft); color: var(--sk-accent-deep); display: grid; place-items: center; flex: none; } |
| |
1005 | +.sk-amen-it.unconfirmed { color: var(--sk-text-2); } |
| |
1006 | +.sk-amen-it.unconfirmed .sk-amen-ico { background: var(--sk-surface-2); color: var(--sk-muted); border: 1px dashed var(--sk-border-2); } |
| |
1007 | +.sk-amen-txt { min-width: 0; line-height: 1.25; } |
| |
1008 | +.sk-amen-conf { margin-left: auto; color: var(--sk-success); flex: none; } |
| |
1009 | + |
| |
1010 | +/* ---- KPI / tuiles ---- */ |
| |
1011 | +.sk-kpis { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } |
| |
1012 | +@media (min-width: 600px) { .sk-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); } .sk-kpi-v { font-size: 20px; } } |
| |
1013 | +.sk-kpis.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } |
| |
1014 | +.sk-kpi { padding: 10px 12px; border: 1px solid var(--sk-border); border-radius: 12px; background: var(--sk-surface); min-width: 0; } |
| |
1015 | +.sk-kpi.accent { background: var(--sk-accent-soft); border-color: #f5c2c6; } |
| |
1016 | +.sk-kpi-v { font-family: var(--font-display); font-weight: 700; font-size: clamp(16px, 4.8vw, 20px); letter-spacing: -0.025em; line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--sk-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } |
| |
1017 | +.sk-kpi-v.wrap { white-space: normal; font-size: 16px; line-height: 1.2; } |
| |
1018 | +.sk-kpi-v small { font: 600 11px var(--font-body); color: var(--sk-muted); margin-left: 3px; } |
| |
1019 | +.sk-kpi-l { font-size: 11.5px; color: var(--sk-muted); margin-top: 3px; line-height: 1.3; } |
| |
1020 | +.sk-kpi.anim .sk-kpi-v { animation: sk-rise 0.5s ease both; } |
| |
1021 | +@keyframes sk-rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } } |
| |
1022 | + |
| |
1023 | +/* ---- rangées compactes (accessibilité, mesures) ---- */ |
| |
1024 | +.sk-rows { display: flex; flex-direction: column; gap: 4px; } |
| |
1025 | +.sk-row { display: grid; grid-template-columns: minmax(0, 1fr) auto auto; align-items: center; gap: 10px; min-height: 30px; font-size: 13.5px; } |
| |
1026 | +.sk-row-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--sk-text); } |
| |
1027 | +.sk-row-name small { color: var(--sk-muted); font-size: 12px; margin-left: 4px; } |
| |
1028 | +.sk-row-bar { width: 78px; height: 6px; border-radius: 3px; background: var(--sk-surface-2); border: 1px solid var(--sk-border); overflow: hidden; } |
| |
1029 | +.sk-row-bar i { display: block; height: 100%; background: var(--sk-text); border-radius: 3px; } |
| |
1030 | +.sk-row-bar i.good { background: var(--sk-success); } |
| |
1031 | +.sk-row-bar i.warn { background: var(--sk-warning); } |
| |
1032 | +.sk-row-bar i.bad { background: var(--sk-danger); } |
| |
1033 | +.sk-row-val { font-weight: 700; font-size: 13px; font-variant-numeric: tabular-nums; min-width: 28px; text-align: right; } |
| |
1034 | +.sk-row-lbl { font-size: 12px; color: var(--sk-muted); min-width: 68px; text-align: right; } |
| |
1035 | +.sk-row-lbl.good { color: var(--sk-success); } .sk-row-lbl.warn { color: var(--sk-warning); } .sk-row-lbl.bad { color: var(--sk-danger); } |
| |
1036 | + |
| |
1037 | +/* ---- pastilles d'état ---- */ |
| |
1038 | +.sk-badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font: 600 12px var(--font-body); border: 1px solid transparent; white-space: nowrap; } |
| |
1039 | +.sk-badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; } |
| |
1040 | +.sk-badge.good { background: var(--sk-success-soft); color: var(--sk-success); } |
| |
1041 | +.sk-badge.warn { background: var(--sk-warning-soft); color: var(--sk-warning); } |
| |
1042 | +.sk-badge.bad { background: var(--sk-danger-soft); color: var(--sk-danger); } |
| |
1043 | +.sk-badge.neutral { background: var(--sk-surface-2); color: var(--sk-text-2); border-color: var(--sk-border); } |
| |
1044 | +.sk-badge.info { background: var(--sk-info-soft); color: var(--sk-info); } |
| |
1045 | +.sk-badge.lg { font-size: 13.5px; padding: 6px 12px; } |
| |
1046 | +.sk-pill { display: inline-block; font: 600 10.5px var(--font-body); text-transform: uppercase; letter-spacing: 0.05em; padding: 2px 7px; border-radius: 6px; margin-left: 6px; vertical-align: 1px; } |
| |
1047 | +.sk-pill.included { background: var(--sk-success-soft); color: var(--sk-success); } |
| |
1048 | +.sk-pill.observed { background: var(--sk-surface-2); color: var(--sk-text-2); border: 1px solid var(--sk-border); } |
| |
1049 | +.sk-pill.estimated { background: var(--sk-accent-soft); color: var(--sk-accent-deep); } |
| |
1050 | +.sk-pill.unknown { background: var(--sk-surface-2); color: var(--sk-muted); border: 1px dashed var(--sk-border-2); } |
| |
1051 | + |
| |
1052 | +/* ---- listes d'items (lieux, comparables, stations) ---- */ |
| |
1053 | +.sk-list { list-style: none; margin: 0; padding: 0; } |
| |
1054 | +.sk-item { display: flex; align-items: center; gap: 12px; padding: 10px 0; border-top: 1px solid var(--sk-border); min-width: 0; } |
| |
1055 | +.sk-list > .sk-item:first-child { border-top: 0; padding-top: 2px; } |
| |
1056 | +.sk-item-ico { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; flex: none; background: var(--sk-surface-2); border: 1px solid var(--sk-border); color: var(--sk-text-2); } |
| |
1057 | +.sk-item-ico svg.cm-ico { width: 26px; height: 26px; } |
| |
1058 | +.sk-item-main { flex: 1; min-width: 0; } |
| |
1059 | +.sk-item-t { font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1060 | +.sk-item-s { font-size: 12.5px; color: var(--sk-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1061 | +.sk-item-r { text-align: right; flex: none; } |
| |
1062 | +.sk-item-v { font-weight: 700; font-size: 14px; font-variant-numeric: tabular-nums; } |
| |
1063 | +.sk-item-m { font-size: 12px; color: var(--sk-muted); } |
| |
1064 | +.sk-item-best { color: var(--sk-success); font-weight: 700; font-size: 11.5px; margin-left: 6px; } |
| |
1065 | + |
| |
1066 | +/* ---- carrousel horizontal ---- */ |
| |
1067 | +.sk-carousel { display: flex; gap: 10px; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: 0 -16px; padding: 2px 16px 6px; } |
| |
1068 | +.sk-carousel::-webkit-scrollbar { display: none; } |
| |
1069 | +@media (min-width: 768px) { .sk-carousel { margin: 0; padding: 2px 0 6px; } } |
| |
1070 | +.sk-ccard { flex: 0 0 44%; min-width: 148px; max-width: 210px; scroll-snap-align: start; border: 1px solid var(--sk-border); border-radius: var(--sk-r-md); padding: 12px; background: var(--sk-surface); display: flex; flex-direction: column; gap: 6px; min-height: 104px; } |
| |
1071 | +@media (min-width: 768px) { .sk-ccard { flex-basis: 176px; } } |
| |
1072 | +.sk-ccard-top { display: flex; align-items: center; justify-content: space-between; gap: 8px; } |
| |
1073 | +.sk-ccard-c { font: 600 10.5px var(--font-body); text-transform: uppercase; letter-spacing: 0.06em; color: var(--sk-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1074 | +.sk-ccard-d { font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; } |
| |
1075 | +.sk-ccard-n { font-size: 12.5px; color: var(--sk-text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1076 | +.sk-ccard-m { font-size: 11.5px; color: var(--sk-muted); } |
| |
1077 | + |
| |
1078 | +/* ---- filtres (chips) ---- */ |
| |
1079 | +.sk-chips { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; padding-bottom: 10px; } |
| |
1080 | +.sk-chips::-webkit-scrollbar { display: none; } |
| |
1081 | +.sk-chip { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 7px; min-height: 38px; padding: 6px 12px; border-radius: 999px; border: 1px solid var(--sk-border); background: var(--sk-surface); color: var(--sk-text-2); font: 600 12.5px var(--font-body); cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; } |
| |
1082 | +.sk-chip .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--c, var(--sk-text)); flex: none; } |
| |
1083 | +.sk-chip small { font-weight: 600; opacity: 0.65; } |
| |
1084 | +.sk-chip.on { background: var(--sk-text); color: #fff; border-color: var(--sk-text); } |
| |
1085 | +.sk-chip:disabled { opacity: 0.45; cursor: default; } |
| |
1086 | + |
| |
1087 | +/* ---- carte ---- */ |
| |
1088 | +.sk-map { position: relative; height: 340px; border-radius: var(--sk-r-lg); overflow: hidden; border: 1px solid var(--sk-border); background: #ecece8; } |
| |
1089 | +@media (min-width: 768px) { .sk-map { height: 440px; } } |
| |
1090 | +@media (min-width: 1024px) { .sk-map { height: 520px; } } |
| |
1091 | +.sk-map .ka-map { |
| |
1092 | + position: absolute; inset: 0; |
| |
1093 | + --ka-accent: var(--sk-accent); --ka-on-accent: #fff; --ka-surface: var(--sk-surface); |
| |
1094 | + --ka-ink: var(--sk-text); --ka-line: var(--sk-border-2); --ka-radius: 10px; |
| |
1095 | + --ka-shadow: 0 8px 24px rgba(20, 24, 20, 0.14); --ka-font: var(--font-body); |
| |
1096 | +} |
| |
1097 | +.sk-map-legend { position: absolute; left: 10px; bottom: 10px; z-index: 5; display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; background: rgba(255, 255, 255, 0.92); border: 1px solid var(--sk-border); font: 500 11px var(--font-body); color: var(--sk-text-2); pointer-events: none; } |
| |
1098 | +.sk-map-legend i { width: 10px; height: 10px; border-radius: 3px; background: var(--sk-accent); } |
| |
1099 | +.sk-map-skel { position: absolute; inset: 0; } |
| |
1100 | +.sk-map-hint { font-size: 12px; color: var(--sk-muted); margin: 8px 0 0; } |
| |
1101 | + |
| |
1102 | +/* ---- accordéon ---- */ |
| |
1103 | +.sk-acc { border-top: 1px solid var(--sk-border); } |
| |
1104 | +.sk-acc:first-child { border-top: 0; } |
| |
1105 | +.sk-acc-btn { width: 100%; display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 48px; padding: 10px 0; background: none; border: 0; font: 600 14px var(--font-body); color: var(--sk-text); cursor: pointer; text-align: left; } |
| |
1106 | +.sk-acc-btn .sk-acc-meta { font-weight: 500; font-size: 12.5px; color: var(--sk-muted); margin-left: auto; white-space: nowrap; } |
| |
1107 | +.sk-acc-btn .chev { color: var(--sk-muted); flex: none; transition: transform 0.2s ease; } |
| |
1108 | +.sk-acc-btn[aria-expanded="true"] .chev { transform: rotate(180deg); } |
| |
1109 | +.sk-acc-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.22s ease; } |
| |
1110 | +.sk-acc-body.open { grid-template-rows: 1fr; } |
| |
1111 | +.sk-acc-body > div { min-height: 0; overflow: hidden; } |
| |
1112 | +.sk-acc-inner { padding: 0 0 14px; font-size: 13.5px; color: var(--sk-text-2); line-height: 1.5; } |
| |
1113 | +.sk-acc-inner p { margin: 0 0 8px; } |
| |
1114 | +.sk-acc-inner a { color: var(--sk-text-2); text-decoration: underline; text-underline-offset: 2px; } |
| |
1115 | +.sk-acc.sm .sk-acc-btn { min-height: 40px; font-size: 13px; color: var(--sk-text-2); } |
| |
1116 | + |
| |
1117 | +/* ---- bottom sheet (mobile) / modale (desktop) ---- */ |
| |
1118 | +.sk-sheet-backdrop { position: fixed; inset: 0; z-index: var(--z-overlay, 800); background: rgba(20, 24, 20, 0.42); animation: sk-fade 0.18s ease; } |
| |
1119 | +.sk-sheet { |
| |
1120 | + position: fixed; left: 0; right: 0; bottom: 0; z-index: var(--z-modal, 900); |
| |
1121 | + height: var(--sk-sheet-h, 68dvh); max-height: 94dvh; |
| |
1122 | + background: var(--sk-surface); border-radius: 20px 20px 0 0; |
| |
1123 | + display: flex; flex-direction: column; box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.18); |
| |
1124 | + animation: sk-up 0.28s cubic-bezier(0.2, 0.8, 0.2, 1); |
| |
1125 | + padding-bottom: env(safe-area-inset-bottom); |
| |
1126 | + touch-action: pan-y; |
| |
1127 | +} |
| |
1128 | +.sk-sheet.full { height: 94dvh; } |
| |
1129 | +.sk-sheet-handle { width: 40px; height: 4px; border-radius: 2px; background: var(--sk-border-2); margin: 8px auto 0; flex: none; } |
| |
1130 | +.sk-sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 10px 16px 10px; border-bottom: 1px solid var(--sk-border); flex: none; } |
| |
1131 | +.sk-sheet-title { font-family: var(--font-display); font-weight: 700; font-size: 16px; letter-spacing: -0.02em; margin: 0; } |
| |
1132 | +.sk-sheet-sub { font-size: 12.5px; color: var(--sk-muted); margin: 2px 0 0; } |
| |
1133 | +.sk-sheet-x { width: 36px; height: 36px; border-radius: 50%; border: 1px solid var(--sk-border); background: var(--sk-surface-2); display: grid; place-items: center; cursor: pointer; color: var(--sk-text); flex: none; } |
| |
1134 | +.sk-sheet-body { flex: 1; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 12px 16px 18px; } |
| |
1135 | +.sk-sheet-foot { flex: none; padding: 10px 16px; border-top: 1px solid var(--sk-border); background: var(--sk-surface); } |
| |
1136 | +@keyframes sk-up { from { transform: translateY(40px); opacity: 0.6; } to { transform: none; opacity: 1; } } |
| |
1137 | +@keyframes sk-fade { from { opacity: 0; } to { opacity: 1; } } |
| |
1138 | +@keyframes sk-pop { from { transform: translate(-50%, -50%) scale(0.97); opacity: 0; } to { transform: translate(-50%, -50%) scale(1); opacity: 1; } } |
| |
1139 | +@media (min-width: 900px) { |
| |
1140 | + .sk-sheet, .sk-sheet.full { |
| |
1141 | + left: 50%; right: auto; top: 50%; bottom: auto; transform: translate(-50%, -50%); |
| |
1142 | + width: min(680px, calc(100vw - 48px)); height: auto; max-height: min(82vh, 780px); |
| |
1143 | + border-radius: var(--sk-r-lg); animation: sk-pop 0.18s ease; padding-bottom: 0; |
| |
1144 | + } |
| |
1145 | + .sk-sheet-handle { display: none; } |
| |
1146 | + .sk-sheet-head { padding: 16px 20px 12px; } |
| |
1147 | + .sk-sheet-body { padding: 14px 20px 20px; } |
| |
1148 | +} |
| |
1149 | +.sk-sheet-filters { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; } |
| |
1150 | +.sk-seg { display: inline-flex; border: 1px solid var(--sk-border); border-radius: 999px; overflow: hidden; background: var(--sk-surface); } |
| |
1151 | +.sk-seg button { border: 0; background: transparent; padding: 7px 12px; min-height: 36px; font: 600 12.5px var(--font-body); color: var(--sk-text-2); cursor: pointer; } |
| |
1152 | +.sk-seg button.on { background: var(--sk-text); color: #fff; } |
| |
1153 | +.sk-seg button + button { border-left: 1px solid var(--sk-border); } |
| |
1154 | + |
| |
1155 | +/* ---- CTA sticky ---- */ |
| |
1156 | +.sk-cta-bar { |
| |
1157 | + position: fixed; left: 0; right: 0; bottom: var(--consent-h, 0px); z-index: var(--z-bottombar, 600); |
| |
1158 | + display: flex; align-items: center; gap: 12px; |
| |
1159 | + padding: 10px 16px calc(10px + env(safe-area-inset-bottom)); |
| |
1160 | + background: rgba(255, 255, 255, 0.94); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px); |
| |
1161 | + border-top: 1px solid var(--sk-border); |
| |
1162 | + transform: translateY(110%); transition: transform 0.25s ease; will-change: transform; |
| |
1163 | +} |
| |
1164 | +.sk-cta-bar.show { transform: none; } |
| |
1165 | +.sk-cta-txt { min-width: 0; flex: 0 1 auto; } |
| |
1166 | +.sk-cta-price { font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: -0.02em; line-height: 1.1; white-space: nowrap; } |
| |
1167 | +.sk-cta-price small { font: 500 11px var(--font-body); color: var(--sk-muted); letter-spacing: 0; } |
| |
1168 | +.sk-cta-sub { font-size: 12px; color: var(--sk-text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } |
| |
1169 | +.sk-cta-sub.good { color: var(--sk-success); font-weight: 600; } |
| |
1170 | +.sk-cta-bar .sk-btn-primary { flex: 1; min-height: 44px; margin-left: auto; max-width: 260px; } |
| |
1171 | +@media (min-width: 1024px) { .sk-cta-bar { display: none; } } |
| |
1172 | + |
| |
1173 | +/* ---- Demander à Ka ---- */ |
| |
1174 | +.sk-ka-btn { |
| |
1175 | + position: fixed; right: 14px; bottom: calc(78px + env(safe-area-inset-bottom) + var(--consent-h, 0px)); z-index: var(--z-dropdown, 700); |
| |
1176 | + display: inline-flex; align-items: center; gap: 7px; min-height: 42px; padding: 8px 14px 8px 12px; |
| |
1177 | + border-radius: 999px; border: 0; background: var(--sk-text); color: #fff; |
| |
1178 | + font: 600 13px var(--font-body); cursor: pointer; box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2); |
| |
1179 | + transition: transform 0.15s, opacity 0.2s; |
| |
1180 | +} |
| |
1181 | +.sk-ka-btn svg { color: var(--sk-accent); } |
| |
1182 | +.sk-ka-btn:active { transform: scale(0.97); } |
| |
1183 | +.sk-ka-btn.hide { opacity: 0; pointer-events: none; transform: translateY(8px); } |
| |
1184 | +@media (min-width: 1024px) { .sk-ka-btn { display: none; } } /* desktop : bouton dans l'aside */ |
| |
1185 | +.sk-ka-intro { display: flex; gap: 12px; align-items: flex-start; padding: 4px 0 12px; } |
| |
1186 | +.sk-ka-avatar { width: 38px; height: 38px; border-radius: 12px; background: var(--sk-text); color: var(--sk-accent); display: grid; place-items: center; flex: none; } |
| |
1187 | +.sk-ka-intro p { margin: 0; font-size: 13.5px; color: var(--sk-text-2); line-height: 1.45; } |
| |
1188 | +.sk-ka-ctx { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 12px; background: var(--sk-surface-2); border: 1px solid var(--sk-border); font-size: 12.5px; color: var(--sk-text-2); margin-bottom: 12px; } |
| |
1189 | +.sk-ka-ctx img { width: 44px; height: 34px; object-fit: cover; border-radius: 6px; flex: none; } |
| |
1190 | +.sk-ka-ctx b { color: var(--sk-text); display: block; font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1191 | +.sk-ka-sugs { display: flex; flex-direction: column; gap: 6px; } |
| |
1192 | +.sk-ka-sug { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; min-height: 46px; padding: 10px 14px; border-radius: 12px; border: 1px solid var(--sk-border); background: var(--sk-surface); font: 500 14px var(--font-body); color: var(--sk-text); cursor: pointer; text-align: left; transition: background 0.15s, border-color 0.15s; } |
| |
1193 | +.sk-ka-sug:hover { background: var(--sk-accent-soft); border-color: #f5c2c6; } |
| |
1194 | +.sk-ka-sug svg { color: var(--sk-muted); flex: none; } |
| |
1195 | +.sk-ka-in { display: flex; gap: 8px; align-items: center; } |
| |
1196 | +.sk-ka-in input { flex: 1; min-height: 46px; padding: 10px 14px; border-radius: 12px; border: 1px solid var(--sk-border); background: var(--sk-surface); font: 400 16px var(--font-body); color: var(--sk-text); } |
| |
1197 | +.sk-ka-in input:focus { outline: 2px solid var(--sk-accent); outline-offset: 1px; } |
| |
1198 | +.sk-ka-in button { width: 46px; height: 46px; border-radius: 12px; border: 0; background: var(--sk-accent); color: #fff; display: grid; place-items: center; cursor: pointer; flex: none; } |
| |
1199 | +.sk-ka-in button:disabled { opacity: 0.4; cursor: default; } |
| |
1200 | + |
| |
1201 | +/* ---- aside desktop ---- */ |
| |
1202 | +.sk-aside-card { display: flex; flex-direction: column; gap: 12px; } |
| |
1203 | +.sk-aside .sk-btn-primary { white-space: normal; text-align: center; line-height: 1.25; } |
| |
1204 | +.sk-aside .sk-ka-inline { justify-content: flex-start; } |
| |
1205 | +.sk-aside .sk-ka-inline svg { color: var(--sk-accent); } |
| |
1206 | +.sk-aside .sk-price { font-size: 32px; } |
| |
1207 | +.sk-aside-addr { font-size: 14px; color: var(--sk-text-2); line-height: 1.4; } |
| |
1208 | +.sk-aside-sep { border: 0; border-top: 1px solid var(--sk-border); margin: 4px 0; } |
| |
1209 | +.sk-aside-score { display: flex; align-items: center; gap: 12px; } |
| |
1210 | +.sk-aside-score .sk-score-ring { width: 56px; height: 56px; } |
| |
1211 | +.sk-aside-score .sk-score-ring svg { width: 56px; height: 56px; } |
| |
1212 | +.sk-aside-score .sk-score-val { font-size: 18px; } |
| |
1213 | +.sk-aside-score .sk-score-val small { display: none; } |
| |
1214 | +.sk-aside-score-txt { font-size: 13px; color: var(--sk-text-2); line-height: 1.4; } |
| |
1215 | +.sk-aside-score-txt b { display: block; color: var(--sk-text); font-size: 14px; } |
| |
1216 | +.sk-aside .sk-brief { gap: 8px; } |
| |
1217 | +.sk-aside .sk-brief-t { font-size: 13.5px; } |
| |
1218 | +.sk-aside .sk-brief-d { display: none; } |
| |
1219 | +.sk-aside-meta { font-size: 12px; color: var(--sk-muted); text-align: center; } |
| |
1220 | + |
| |
1221 | +/* ---- source & méthodologie (pied de section) ---- */ |
| |
1222 | +.sk-source { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--sk-border); font-size: 12px; color: var(--sk-muted); } |
| |
1223 | +.sk-source b { font-weight: 600; color: var(--sk-text-2); } |
| |
1224 | +.sk-source a, .sk-source button { color: var(--sk-text-2); background: none; border: 0; padding: 0; font: inherit; text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--sk-border-2); cursor: pointer; } |
| |
1225 | +.sk-source a:hover, .sk-source button:hover { color: var(--sk-accent-deep); } |
| |
1226 | +.sk-fine { font-size: 12.5px; color: var(--sk-muted); line-height: 1.5; margin: 8px 0 0; } |
| |
1227 | +.sk-fine a { color: var(--sk-text-2); text-decoration: underline; text-underline-offset: 2px; } |
| |
1228 | +.sk-fine.meth { margin-top: 0; } |
| |
1229 | + |
| |
1230 | +/* ---- états : squelettes, vides, erreurs ---- */ |
| |
1231 | +.sk-skel { border-radius: 10px; background: linear-gradient(90deg, #ecece8 25%, #f4f4f1 50%, #ecece8 75%); background-size: 400% 100%; animation: sk-shimmer 1.3s infinite linear; } |
| |
1232 | +@keyframes sk-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } } |
| |
1233 | +.sk-skel-lines { display: flex; flex-direction: column; gap: 8px; } |
| |
1234 | +.sk-skel-lines .sk-skel { height: 12px; } |
| |
1235 | +.sk-skel-lines .sk-skel.short { width: 55%; } |
| |
1236 | +.sk-empty { padding: 14px; border-radius: 12px; background: var(--sk-surface-2); border: 1px dashed var(--sk-border-2); color: var(--sk-muted); font-size: 13.5px; text-align: center; line-height: 1.45; } |
| |
1237 | +.sk-error { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; border-radius: 12px; background: var(--sk-warning-soft); color: var(--sk-warning); font-size: 13.5px; } |
| |
1238 | +.sk-error button { border: 1px solid currentColor; background: transparent; color: inherit; border-radius: 999px; padding: 6px 12px; font: 600 12.5px var(--font-body); cursor: pointer; min-height: 36px; } |
| |
1239 | +.sk-page-error { max-width: 520px; margin: 60px auto; text-align: center; padding: 0 16px; } |
| |
1240 | +.sk-page-error h2 { font-family: var(--font-display); letter-spacing: -0.02em; } |
| |
1241 | +.sk-page-error p { color: var(--sk-text-2); } |
| |
1242 | +.sk-toast { position: fixed; left: 50%; bottom: calc(96px + env(safe-area-inset-bottom) + var(--consent-h, 0px)); transform: translateX(-50%); z-index: var(--z-toast, 950); background: var(--sk-text); color: #fff; font: 600 13px var(--font-body); padding: 10px 16px; border-radius: 999px; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); animation: sk-up 0.25s ease; max-width: calc(100vw - 32px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } |
| |
1243 | + |
| |
1244 | +/* ---- prix / marché ---- */ |
| |
1245 | +.sk-market-head { display: grid; grid-template-columns: 1fr auto; gap: 12px; align-items: start; } |
| |
1246 | +.sk-market-big { font-family: var(--font-display); font-weight: 700; font-size: 28px; letter-spacing: -0.03em; line-height: 1; } |
| |
1247 | +.sk-market-big small { font: 500 13px var(--font-body); color: var(--sk-muted); margin-left: 4px; letter-spacing: 0; } |
| |
1248 | +.sk-market-sub { font-size: 13px; color: var(--sk-text-2); margin-top: 4px; } |
| |
1249 | +.sk-histo { display: block; width: 100%; max-width: 520px; height: auto; margin: 12px 0 4px; } |
| |
1250 | +.sk-histo-bar { fill: #dedfd9; } |
| |
1251 | +.sk-histo-bar.on { fill: var(--sk-accent); } |
| |
1252 | +.sk-histo-lbl { font: 700 10px var(--font-body); fill: var(--sk-text); } |
| |
1253 | +.sk-histo-lbl.fv { fill: var(--sk-text-2); } |
| |
1254 | +.sk-histo-axis { font: 500 9.5px var(--font-body); fill: var(--sk-muted); } |
| |
1255 | +.sk-meta { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: 12.5px; color: var(--sk-text-2); margin: 6px 0 0; } |
| |
1256 | +.sk-meta b { color: var(--sk-text); } |
| |
1257 | + |
| |
1258 | +/* jauge du registre des loyers */ |
| |
1259 | +.sk-gauge { margin: 14px 0 6px; } |
| |
1260 | +.sk-gauge-lbls { display: flex; justify-content: space-between; font: 600 11px var(--font-body); color: var(--sk-muted); margin-bottom: 6px; } |
| |
1261 | +.sk-gauge-lbls .good { color: var(--sk-success); } .sk-gauge-lbls .bad { color: var(--sk-danger); } |
| |
1262 | +.sk-gauge svg { display: block; width: 100%; max-width: 520px; height: auto; overflow: visible; } |
| |
1263 | +.sk-gauge, .sk-gauge-lbls { max-width: 520px; } |
| |
1264 | +.sk-gauge-track { fill: var(--sk-surface-2); stroke: var(--sk-border); } |
| |
1265 | +.sk-gauge-box { fill: #ecece8; } |
| |
1266 | +.sk-gauge-med { stroke: var(--sk-text-2); stroke-width: 1.5; } |
| |
1267 | +.sk-gauge-me { fill: var(--sk-accent); stroke: #fff; stroke-width: 2.5; } |
| |
1268 | +.sk-gauge-txt { font: 600 10.5px var(--font-body); fill: var(--sk-muted); } |
| |
1269 | +.sk-gauge-txt.me { fill: var(--sk-text); font-weight: 700; } |
| |
1270 | +.sk-bars { display: block; width: 100%; max-width: 520px; height: auto; margin: 6px 0 0; } |
| |
1271 | +.sk-bar { fill: #dedfd9; } |
| |
1272 | +.sk-bar.on { fill: var(--sk-accent); } |
| |
1273 | +.sk-bar-val { font: 600 10px var(--font-body); fill: var(--sk-text-2); } |
| |
1274 | +.sk-bar-cat { font: 600 11px var(--font-body); fill: var(--sk-text-2); } |
| |
1275 | +.sk-bar-cat.on { fill: var(--sk-text); font-weight: 700; } |
| |
1276 | +.sk-bar-n { font: 500 9.5px var(--font-body); fill: var(--sk-muted); } |
| |
1277 | +.sk-bars-axe { stroke: var(--sk-border); } |
| |
1278 | + |
| |
1279 | +/* ---- risques / environnement ---- */ |
| |
1280 | +.sk-status { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } |
| |
1281 | +.sk-status-t { font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: -0.02em; } |
| |
1282 | +.sk-status-d { font-size: 13.5px; color: var(--sk-text-2); margin: 8px 0 0; line-height: 1.5; } |
| |
1283 | +.sk-air { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; margin-top: 12px; } |
| |
1284 | +@media (max-width: 400px) { .sk-air { grid-template-columns: repeat(2, minmax(0, 1fr)); } } |
| |
1285 | +.sk-air-c { padding: 10px 12px; border-radius: 12px; border: 1px solid var(--sk-border); background: var(--sk-surface-2); min-width: 0; } |
| |
1286 | +.sk-air-p { font: 600 11.5px var(--font-body); color: var(--sk-muted); text-transform: uppercase; letter-spacing: 0.05em; } |
| |
1287 | +.sk-air-v { font-family: var(--font-display); font-weight: 700; font-size: 18px; letter-spacing: -0.02em; margin-top: 2px; font-variant-numeric: tabular-nums; white-space: nowrap; } |
| |
1288 | +.sk-air-v small { font: 500 11px var(--font-body); color: var(--sk-muted); margin-left: 3px; } |
| |
1289 | +.sk-air-s { font-size: 11.5px; margin-top: 3px; line-height: 1.3; } |
| |
1290 | +.sk-air-s.good { color: var(--sk-success); } .sk-air-s.warn { color: var(--sk-warning); } .sk-air-s.bad { color: var(--sk-danger); } .sk-air-s.neutral { color: var(--sk-muted); } |
| |
1291 | + |
| |
1292 | +/* ---- coût réel ---- */ |
| |
1293 | +.sk-cost { list-style: none; margin: 0; padding: 0; } |
| |
1294 | +.sk-cost li { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 8px 0; border-top: 1px solid var(--sk-border); font-size: 13.5px; } |
| |
1295 | +.sk-cost li:first-child { border-top: 0; } |
| |
1296 | +.sk-cost .n { color: var(--sk-text-2); min-width: 0; } |
| |
1297 | +.sk-cost .v { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; } |
| |
1298 | +.sk-cost .v.na { color: var(--sk-muted); font-weight: 500; } |
| |
1299 | +.sk-cost li.total { border-top: 1px solid var(--sk-border-2); margin-top: 4px; padding-top: 10px; font-size: 15px; } |
| |
1300 | +.sk-cost li.total .n, .sk-cost li.total .v { color: var(--sk-text); font-weight: 700; } |
| |
1301 | +.sk-cost li.annuel { font-size: 12.5px; color: var(--sk-muted); border-top: 0; padding-top: 0; } |
| |
1302 | +.sk-cost-note { font-size: 12.5px; color: var(--sk-text-2); margin: 8px 0 0; } |
| |
1303 | + |
| |
1304 | +/* ---- dossier de l'immeuble (accordéons) ---- */ |
| |
1305 | +.sk-tl { list-style: none; margin: 4px 0 0; padding: 0 0 0 12px; border-left: 2px solid var(--sk-border); display: flex; flex-direction: column; gap: 8px; } |
| |
1306 | +.sk-tl li { position: relative; font-size: 13px; color: var(--sk-text-2); } |
| |
1307 | +.sk-tl li::before { content: ""; position: absolute; left: -17.5px; top: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--sk-surface); border: 2px solid var(--sk-border-2); } |
| |
1308 | +.sk-tl li.prix::before { border-color: var(--sk-accent); } |
| |
1309 | +.sk-tl li.disparition::before { border-color: var(--sk-danger); } |
| |
1310 | +.sk-tl li.reapparition::before { border-color: var(--sk-success); } |
| |
1311 | +.sk-tl-date { display: inline-block; min-width: 84px; font: 600 11.5px var(--font-body); color: var(--sk-muted); } |
| |
1312 | +.sk-star { font-family: var(--font-display); font-weight: 700; font-size: 20px; color: var(--sk-text); display: inline-flex; align-items: center; gap: 5px; } |
| |
1313 | +.sk-star svg { color: #e0a800; } |
| |
1314 | +.sk-quote { margin: 10px 0 0; padding: 8px 12px; font-size: 13px; color: var(--sk-text-2); border-left: 3px solid var(--sk-border-2); background: var(--sk-surface-2); border-radius: 8px; } |
| |
1315 | +.sk-quote footer { margin-top: 4px; font-size: 11.5px; color: var(--sk-muted); } |
| |
1316 | +.sk-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 4px; } |
| |
1317 | +.sk-tag { font: 600 11.5px var(--font-body); padding: 2px 8px; border-radius: 999px; background: var(--sk-danger-soft); color: var(--sk-danger); } |
| |
1318 | +.sk-tag.n { background: var(--sk-surface-2); color: var(--sk-text-2); border: 1px solid var(--sk-border); } |
| |
1319 | + |
| |
1320 | +/* ---- KA Scores (cercles compacts) ---- */ |
| |
1321 | +.sk-ks { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 6px; } |
| |
1322 | +@media (max-width: 400px) { .sk-ks { grid-template-columns: repeat(3, minmax(0, 1fr)); } } |
| |
1323 | +.sk-ks-c { text-align: center; padding: 8px 4px; border-radius: 12px; border: 1px solid var(--sk-border); background: var(--sk-surface-2); min-width: 0; } |
| |
1324 | +.sk-ks-c svg { width: 52px; height: 52px; transform: rotate(-90deg); } |
| |
1325 | +.sk-ks-c .bg { fill: none; stroke: #e6e6e1; stroke-width: 5; } |
| |
1326 | +.sk-ks-c .arc { fill: none; stroke: var(--sk-text); stroke-width: 5; stroke-linecap: round; } |
| |
1327 | +.sk-ks-c.haut .arc { stroke: var(--sk-success); } .sk-ks-c.bon .arc { stroke: var(--sk-text); } .sk-ks-c.moyen .arc { stroke: var(--sk-warning); } .sk-ks-c.bas .arc { stroke: var(--sk-danger); } |
| |
1328 | +.sk-ks-wrap { position: relative; width: 52px; height: 52px; margin: 0 auto; } |
| |
1329 | +.sk-ks-v { position: absolute; inset: 0; display: grid; place-items: center; font: 700 15px var(--font-display); letter-spacing: -0.02em; } |
| |
1330 | +.sk-ks-n { font: 600 11.5px var(--font-body); margin-top: 6px; color: var(--sk-text); } |
| |
1331 | +.sk-ks-l { font-size: 10.5px; color: var(--sk-muted); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } |
| |
1332 | +.sk-ks-detail { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px 18px; } |
| |
1333 | +.sk-ks-detail h4 { margin: 8px 0 4px; font: 700 12.5px var(--font-body); color: var(--sk-text); } |
| |
1334 | +.sk-ks-detail ul { margin: 0; padding-left: 16px; font-size: 13px; color: var(--sk-text-2); } |
| |
1335 | +.sk-ks-detail li { margin: 2px 0; } |
| |
1336 | + |
| |
1337 | +/* ---- fin de fiche ---- */ |
| |
1338 | +.sk-end { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } |
| |
1339 | +@media (min-width: 640px) { .sk-end { grid-template-columns: repeat(4, minmax(0, 1fr)); } } |
| |
1340 | +.sk-end a, .sk-end button { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 12px; border-radius: 12px; border: 1px solid var(--sk-border); background: var(--sk-surface); color: var(--sk-text); font: 600 13px var(--font-body); cursor: pointer; text-align: left; min-height: 64px; } |
| |
1341 | +.sk-end a:hover, .sk-end button:hover { background: var(--sk-surface-2); } |
| |
1342 | +.sk-end svg { color: var(--sk-accent-deep); } |
| |
1343 | +.sk-end small { font-weight: 500; color: var(--sk-muted); font-size: 12px; } |
| |
1344 | +.sk-sources { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; } |
| |
1345 | +.sk-sources li { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 4px 12px; padding: 9px 0; border-top: 1px solid var(--sk-border); font-size: 13px; align-items: center; } |
| |
1346 | +.sk-sources li:first-child { border-top: 0; } |
| |
1347 | +.sk-sources .n { font-weight: 600; grid-column: 1; grid-row: 1; } |
| |
1348 | +.sk-sources .r { font-size: 12.5px; color: var(--sk-text-2); grid-column: 1; grid-row: 2; } |
| |
1349 | +.sk-sources .d { font-size: 12px; color: var(--sk-muted); grid-column: 2; grid-row: 1 / span 2; text-align: right; white-space: nowrap; align-self: start; } |
| |
1350 | +.sk-sources a { color: var(--sk-text-2); text-decoration: underline; text-underline-offset: 2px; } |
| |
1351 | + |
| |
1352 | + |
| |
1353 | +/* ---- ajouts Immo-Ka : héro, galerie, formulaire, tableaux, rôle ---- */ |
| |
1354 | +.sk-kicker { font-family: var(--font-mono); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.12em; color: var(--sk-muted); margin-bottom: 4px; } |
| |
1355 | +.sk-gallery-empty { display: grid; place-items: center; aspect-ratio: 4 / 3; } |
| |
1356 | +@media (min-width: 768px) { .sk-gallery-empty { aspect-ratio: 16 / 9; } } |
| |
1357 | +.sk-gallery-empty .type-fallback { position: static; width: 100%; height: 100%; } |
| |
1358 | +.sk-gallery-caption { |
| |
1359 | + position: absolute; left: 12px; top: 12px; z-index: 2; max-width: calc(100% - 24px); |
| |
1360 | + background: rgba(20, 24, 20, 0.62); color: #fff; font: 500 12px var(--font-body); |
| |
1361 | + padding: 4px 10px; border-radius: 999px; backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); |
| |
1362 | + overflow: hidden; text-overflow: ellipsis; white-space: nowrap; |
| |
1363 | +} |
| |
1364 | +.sk-subtitle { margin: 14px 0 8px !important; font-weight: 600 !important; color: var(--sk-text-2) !important; font-size: 13px !important; } |
| |
1365 | +.sk-subtitle small { font-weight: 500; color: var(--sk-muted); } |
| |
1366 | +.sk-more .flip { transform: rotate(180deg); } |
| |
1367 | +.sk-acc-ico { vertical-align: -2px; margin-right: 8px; color: var(--sk-muted); } |
| |
1368 | +.sk-role { margin-top: 14px; } |
| |
1369 | +.sk-tl li.baisse::before { border-color: var(--sk-success); } |
| |
1370 | +.sk-tl li.hausse::before { border-color: var(--sk-warning); } |
| |
1371 | +/* formulaire du calculateur */ |
| |
1372 | +.sk-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; } |
| |
1373 | +@media (min-width: 640px) { .sk-form { grid-template-columns: repeat(4, minmax(0, 1fr)); } } |
| |
1374 | +.sk-form label { display: flex; flex-direction: column; gap: 4px; min-width: 0; } |
| |
1375 | +.sk-form label span { font-size: 11.5px; color: var(--sk-muted); font-weight: 600; } |
| |
1376 | +.sk-form input, .sk-form select { |
| |
1377 | + min-height: 42px; padding: 8px 10px; border-radius: 10px; border: 1px solid var(--sk-border); background: var(--sk-surface); |
| |
1378 | + font: 500 15px var(--font-body); color: var(--sk-text); width: 100%; min-width: 0; appearance: none; -webkit-appearance: none; |
| |
1379 | +} |
| |
1380 | +.sk-form select { background-image: linear-gradient(45deg, transparent 50%, var(--sk-muted) 50%), linear-gradient(135deg, var(--sk-muted) 50%, transparent 50%); background-position: calc(100% - 16px) 50%, calc(100% - 11px) 50%; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 28px; } |
| |
1381 | +.sk-form input:focus, .sk-form select:focus { outline: 2px solid var(--sk-accent); outline-offset: 1px; } |
| |
1382 | +/* tableaux (pièces, banques, amortissement) */ |
| |
1383 | +.sk-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 -4px; padding: 0 4px; } |
| |
1384 | +.sk-table { width: 100%; border-collapse: collapse; font-size: 13px; } |
| |
1385 | +.sk-table th { text-align: left; font: 600 11.5px var(--font-body); color: var(--sk-muted); text-transform: uppercase; letter-spacing: 0.04em; padding: 6px 8px; border-bottom: 1px solid var(--sk-border); white-space: nowrap; } |
| |
1386 | +.sk-table td { padding: 8px 8px; border-bottom: 1px solid var(--sk-border); vertical-align: top; color: var(--sk-text-2); } |
| |
1387 | +.sk-table td:first-child { color: var(--sk-text); font-weight: 500; } |
| |
1388 | +.sk-table tr:last-child td { border-bottom: 0; } |
| |
1389 | +.sk-table a { color: var(--sk-text-2); text-decoration: underline; text-underline-offset: 2px; } |
| |
1390 | +/* aside : courtier */ |
| |
1391 | +.sk-aside-broker { display: flex; flex-direction: column; gap: 2px; font-size: 13.5px; color: var(--sk-text-2); } |
| |
1392 | +.sk-aside-broker-k { font: 600 11px var(--font-body); text-transform: uppercase; letter-spacing: 0.06em; color: var(--sk-muted); } |
| |
1393 | +.sk-aside-broker b { color: var(--sk-text); } |
| |
1394 | +.sk-aside-broker a { display: inline-flex; align-items: center; gap: 6px; color: var(--sk-text-2); } |
| |
1395 | +/* jauge Vrai-Prix : libellés */ |
| |
1396 | +.sk-gauge-lbls { margin-top: 4px; margin-bottom: 0; } |
| |
1397 | +.sk-kv .v a { color: var(--sk-text-2); text-decoration: underline; text-underline-offset: 2px; } |
| |
1398 | +.sk-kv .v { min-width: 0; overflow-wrap: anywhere; } |
| |
1399 | + |
| |
1400 | + |
| |
1401 | + |
| |
1402 | +body.sk-fiche-page .header-inner{padding-left:16px;padding-right:16px} |
| |
1403 | +@media(min-width:641px){body.sk-fiche-page .header-inner{padding-left:24px;padding-right:24px}} |
| |
1404 | +.hdr-actions .fav-btn{position:static;width:40px;height:40px;border-radius:999px;border:1px solid var(--sk-border);background:var(--sk-surface);color:var(--sk-text);box-shadow:none;display:inline-grid;place-items:center} |
| |
1405 | +.hdr-actions .fav-btn.on{color:var(--sk-accent);border-color:var(--sk-accent);background:var(--sk-accent-soft)} |
| |
1406 | +.hdr-actions .fav-btn svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2} |
| |
1407 | +.hdr-actions .fav-btn.on svg{fill:currentColor} |
| |
1408 | +@media(max-width:980px){body.sk-fiche-page .header .nav{display:none}} |
| |
1409 | + |
| |
1410 | +/* ---- ajouts Sorti·Ka : image, accordéons natifs, carte, statut ---- */ |
| |
1411 | +.sk-image{position:relative;border-radius:var(--sk-r-lg);overflow:hidden;background:linear-gradient(135deg,var(--sk-accent-soft),var(--sk-surface-2));aspect-ratio:16/9} |
| |
1412 | +@media(max-width:640px){.sk-image{aspect-ratio:4/3}} |
| |
1413 | +.sk-image img{width:100%;height:100%;object-fit:cover;display:block} |
| |
1414 | +.sk-image.noimg{aspect-ratio:16/6;display:grid;place-items:center;color:var(--sk-accent-deep);font-family:var(--font-display);font-weight:700;font-size:20px} |
| |
1415 | +.sk-capsule.date{background:var(--sk-text);color:#fff} |
| |
1416 | +.sk-details{border-top:1px solid var(--sk-border)} |
| |
1417 | +.sk-details:first-child{border-top:0} |
| |
1418 | +.sk-details summary{list-style:none;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:44px;padding:8px 0;font:600 13.5px var(--font-body);color:var(--sk-text-2);cursor:pointer} |
| |
1419 | +.sk-details summary::-webkit-details-marker{display:none} |
| |
1420 | +.sk-details summary::after{content:"";width:8px;height:8px;border-right:2px solid var(--sk-muted);border-bottom:2px solid var(--sk-muted);transform:rotate(45deg);transition:transform .2s;flex:none;margin-right:6px} |
| |
1421 | +.sk-details[open] summary::after{transform:rotate(-135deg)} |
| |
1422 | +.sk-details .sk-acc-inner{padding:0 0 14px;font-size:13.5px;color:var(--sk-text-2);line-height:1.5} |
| |
1423 | +.sk-details .sk-acc-inner p{margin:0 0 8px} |
| |
1424 | +.sk-map{height:300px} |
| |
1425 | +@media(min-width:768px){.sk-map{height:380px}} |
| |
1426 | +.sk-map .leaflet-container{position:absolute;inset:0;font:inherit} |
| |
1427 | +.sk-fiche .grid{margin-top:0} |
| |
1428 | +.sk-sheet .sk-ka-sugs{margin-top:0} |
| |
1429 | +.sk-sheet-x{font-size:18px;line-height:1} |
| |
1430 | +.sk-fiche h3[id]{scroll-margin-top:calc(var(--sk-header-h) + var(--sk-nav-h) + 10px)} |
| |
1431 | +.sk-status{margin-top:6px} |
| |
1432 | + |
| |
1433 | +/* ---- accessibilité mouvement réduit ---- */ |
| |
1434 | +@media (prefers-reduced-motion: reduce) { |
| |
1435 | + .sk-sheet, .sk-sheet-backdrop, .sk-toast, .sk-kpi.anim .sk-kpi-v { animation: none; } |
| |
1436 | + .sk-score-ring .arc, .sk-acc-body, .sk-cta-bar { transition: none; } |
| |
1437 | +} |
| |
1438 | + |
| |
1439 | +/* ---- utilitaire a11y ---- */ |
| |
1440 | +.visually-hidden { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; } |
| |
1441 | + |
| 761 | </style> |
1442 | </style> |
| 762 | </head> |
1443 | </head> |
| 763 | <body> |
1444 | <body> |
| 929 | <div class="toast" id="toast" role="status" aria-live="polite"></div> |
1610 | <div class="toast" id="toast" role="status" aria-live="polite"></div> |
| 930 | |
1611 | |
| 931 | <!-- ======== VUE FICHE ÉVÉNEMENT ======== --> |
1612 | <!-- ======== VUE FICHE ÉVÉNEMENT ======== --> |
| 932 | −<main id="view-detail" class="hidden"> |
1613 | +<main id="view-detail" class="hidden sk-fiche"><div id="sk-root"></div></main> |
| 933 | − <div class="container detail"> |
| |
| 934 | − <span class="back" id="back">← Toutes les sorties</span> |
| |
| 935 | − <div class="detail-grid"> |
| |
| 936 | − <article class="detail-main"> |
| |
| 937 | − <div class="d-imgwrap" id="d-img"></div> |
| |
| 938 | − <div class="d-body"> |
| |
| 939 | − <span class="klabel" id="d-cats-label"></span> |
| |
| 940 | − <div id="d-status"></div> |
| |
| 941 | − <div class="d-title-row"><h1 id="d-title"></h1><span id="d-fav"></span></div> |
| |
| 942 | − <div class="desc" id="d-desc"></div> |
| |
| 943 | − <div class="detail-cats" id="d-cats"></div> |
| |
| 944 | − </div> |
| |
| 945 | − </article> |
| |
| 946 | − <aside class="side"> |
| |
| 947 | − <div class="box" id="d-facts"></div> |
| |
| 948 | − <a class="btn btn-cta" id="d-cta" target="_blank" rel="noopener">Billets · fiche originale ↗</a> |
| |
| 949 | − <div class="box" id="d-src"></div> |
| |
| 950 | − </aside> |
| |
| 951 | − </div> |
| |
| 952 | − <section class="similar"> |
| |
| 953 | − <span class="kicker">À voir aussi</span> |
| |
| 954 | − <h2 id="d-similar-title">Événements similaires</h2> |
| |
| 955 | − <div class="grid" id="d-similar"></div> |
| |
| 956 | − </section> |
| |
| 957 | − </div> |
| |
| 958 | − <!-- CTA sticky mobile : le billet toujours à portée de pouce --> |
| |
| 959 | − <div class="d-ctabar" id="d-ctabar"></div> |
| |
| 960 | −</main> |
| |
| 961 | |
1614 | |
| 962 | <!-- ======== VUE FAVORIS (/favoris) — ♥ « Mon univers Ka » (hub groupe-ka.com) ======== --> |
1615 | <!-- ======== VUE FAVORIS (/favoris) — ♥ « Mon univers Ka » (hub groupe-ka.com) ======== --> |
| 963 | <main id="view-favoris" class="hidden"> |
1616 | <main id="view-favoris" class="hidden"> |
| 1691 | } |
2344 | } |
| 1692 | |
2345 | |
| 1693 | /* ---------- fiche événement ---------- */ |
2346 | /* ---------- fiche événement ---------- */ |
| |
2347 | +/* ==================== fiche événement — refonte premium 2026-09-07 ========== |
| |
2348 | + Même socle que les fiches Lou-Ka v3 / Immo-Ka v3, en JS natif : héro |
| |
2349 | + (catégorie · source, prix, capsules date/statut, titre, résumé, image, |
| |
2350 | + actions) → En bref (constats déterministes) → navigation sticky (scroll-spy) |
| |
2351 | + → Quand et où (faits + carte Leaflet) → Programme (description, artistes, |
| |
2352 | + étiquettes) → Billets (prix, billetterie) → À voir aussi → Dossier → |
| |
2353 | + Sources. CTA sticky mobile, aside desktop, « Demander à Ka » (widget KA |
| |
2354 | + Agent). Ordre DOM = ordre visuel, aucun scrollIntoView à l'ouverture. */ |
| |
2355 | +const SK_ICO = { |
| |
2356 | + share: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="18" cy="5" r="2.5"/><circle cx="6" cy="12" r="2.5"/><circle cx="18" cy="19" r="2.5"/><path d="M8.2 10.8 15.8 6.3M8.2 13.2l7.6 4.5"/></svg>', |
| |
2357 | + ext: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.4 4h5.6v5.6"/><path d="M20 4 11.4 12.6"/><path d="M18.6 13.6V18a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7.4a2 2 0 0 1 2-2h4.4"/></svg>', |
| |
2358 | + spark: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 3l1.9 5.6 5.6 1.9-5.6 1.9L12 18l-1.9-5.6-5.6-1.9 5.6-1.9L12 3z"/><path d="M19 16l.8 2.2 2.2.8-2.2.8L19 22l-.8-2.2-2.2-.8 2.2-.8L19 16z"/></svg>', |
| |
2359 | + pin: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 21.2S5.4 15.7 5.4 10.8a6.6 6.6 0 0 1 13.2 0c0 4.9-6.6 10.4-6.6 10.4z"/><circle cx="12" cy="10.6" r="2.3"/></svg>', |
| |
2360 | + cal: '<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="4" y="5.6" width="16" height="14.8" rx="2"/><path d="M4 10.2h16M8.2 3.4v4M15.8 3.4v4"/></svg>', |
| |
2361 | + tag: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12.9 3.6 7.5 7.5a1.8 1.8 0 0 1 0 2.5l-6.8 6.8a1.8 1.8 0 0 1-2.5 0L3.6 12.9V3.6z"/><circle cx="8" cy="8" r="1.5"/></svg>', |
| |
2362 | + folder: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 6h6l2 2.5h10V19H3z"/></svg>', |
| |
2363 | + music: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>', |
| |
2364 | + ticket: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 9a2 2 0 0 0 0 6v3a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1v-3a2 2 0 0 0 0-6V6a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1z"/><path d="M13 5v14"/></svg>', |
| |
2365 | + alert: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 4.2 2.9 19.4h18.2z"/><path d="M12 10.2v4.4"/><path d="M12 17.4v.05"/></svg>', |
| |
2366 | + chev: '<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m9.5 5 7 7-7 7"/></svg>', |
| |
2367 | + people: '<svg width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="9" cy="8" r="3.2"/><path d="M3.6 20a5.4 5.4 0 0 1 10.8 0"/><path d="M15.4 5.4a3.2 3.2 0 0 1 0 5.9M17 14.8a5.4 5.4 0 0 1 3.4 5.2"/></svg>', |
| |
2368 | +}; |
| |
2369 | +const SK_STATE = { uid: null, cleanup: [] }; |
| |
2370 | + |
| |
2371 | +function skDays(ev){ |
| |
2372 | + if(!ev.start_date) return null; |
| |
2373 | + const d = new Date(`${ev.start_date}T12:00:00`), t = new Date(); t.setHours(12,0,0,0); |
| |
2374 | + return Math.round((d - t) / 86400000); |
| |
2375 | +} |
| |
2376 | +function skQuand(ev){ |
| |
2377 | + const n = skDays(ev); |
| |
2378 | + if(n == null) return { tone:"neutral", titre:"Date à confirmer", detail:"La source ne publie pas de date précise" }; |
| |
2379 | + const fin = ev.end_date && ev.end_date !== ev.start_date; |
| |
2380 | + const finN = fin ? Math.round((new Date(`${ev.end_date}T12:00:00`) - new Date(new Date().setHours(12,0,0,0))) / 86400000) : n; |
| |
2381 | + if(finN < 0) return { tone:"bad", titre:"Événement terminé", detail:`${fmtDate(ev.start_date, true)}${fin ? ` au ${fmtDate(ev.end_date, true)}` : ""}` }; |
| |
2382 | + if(n <= 0 && finN >= 0 && fin) return { tone:"good", titre:"En cours", detail:`Jusqu'au ${fmtDate(ev.end_date, true)}${ev.end_time ? ` · ${fmtTime(ev.end_time)}` : ""}` }; |
| |
2383 | + if(n === 0) return { tone:"good", titre:"C'est aujourd'hui", detail:`${fmtDate(ev.start_date, true)}${ev.start_time ? ` · ${fmtTime(ev.start_time)}` : ""}` }; |
| |
2384 | + if(n === 1) return { tone:"good", titre:"C'est demain", detail:`${fmtDate(ev.start_date, true)}${ev.start_time ? ` · ${fmtTime(ev.start_time)}` : ""}` }; |
| |
2385 | + const dow = new Date(`${ev.start_date}T12:00:00`).getDay(); |
| |
2386 | + if(n <= 7) return { tone:"good", titre:(dow === 0 || dow === 6) ? "Ce week-end" : `Dans ${n} jours`, detail:`${fmtDate(ev.start_date, true)}${ev.start_time ? ` · ${fmtTime(ev.start_time)}` : ""}` }; |
| |
2387 | + return { tone:"neutral", titre:`Dans ${n} jours`, detail:`${fmtDate(ev.start_date, true)}${fin ? ` au ${fmtDate(ev.end_date, true)}` : ""}${ev.start_time ? ` · ${fmtTime(ev.start_time)}` : ""}` }; |
| |
2388 | +} |
| |
2389 | +function skPrix(ev){ |
| |
2390 | + if(ev.is_free === true) return "Gratuit"; |
| |
2391 | + if(ev.price_min != null) return `Dès ${money(ev.price_min)}`; |
| |
2392 | + if(ev.is_free === false) return "Billetterie"; |
| |
2393 | + return "Voir la source"; |
| |
2394 | +} |
| |
2395 | +function skEnBref(ev){ |
| |
2396 | + const out = []; |
| |
2397 | + const q = skQuand(ev); out.push({ cle:"quand", ...q }); |
| |
2398 | + if(ev.status && STATUS_LABELS[ev.status]) |
| |
2399 | + out.push({ cle:"statut", tone: ev.status === "soldout" ? "warn" : "bad", titre: ev.status === "cancelled" ? "Événement annulé" : ev.status === "postponed" ? "Événement reporté" : "Complet — plus de billets", |
| |
2400 | + detail:"Statut publié par la source — vérifiez la fiche originale" }); |
| |
2401 | + if(ev.is_free === true) out.push({ cle:"prix", tone:"good", titre:"Entrée gratuite", detail:"Selon la source — inscription parfois requise" }); |
| |
2402 | + else if(ev.price_min != null) out.push({ cle:"prix", tone:"neutral", titre:`Billets dès ${money(ev.price_min)}`, detail: ev.price_label || "Prix publié par la billetterie, frais en sus possibles" }); |
| |
2403 | + else if(ev.is_free === false) out.push({ cle:"prix", tone:"neutral", titre:"Événement payant", detail:"Prix non publié — voir la billetterie" }); |
| |
2404 | + if(ev.venue || ev.city) out.push({ cle:"lieu", tone:"info", titre:[ev.venue, ev.city].filter(Boolean).join(" · "), detail:[ev.address, ev.region && ev.region !== ev.city ? ev.region : null].filter(Boolean).join(" · ") || "Lieu publié par la source" }); |
| |
2405 | + if(ev.artists && ev.artists.length) out.push({ cle:"artistes", tone:"info", titre:`À l'affiche : ${ev.artists.slice(0,3).join(", ")}${ev.artists.length > 3 ? ` +${ev.artists.length - 3}` : ""}`, detail:`${ev.artists.length} artiste${ev.artists.length > 1 ? "s" : ""} annoncé${ev.artists.length > 1 ? "s" : ""}` }); |
| |
2406 | + if(ev.audience) out.push({ cle:"public", tone:"neutral", titre:`Public : ${ev.audience}`, detail:"Indication de la source" }); |
| |
2407 | + return out.slice(0, 6); |
| |
2408 | +} |
| |
2409 | +function skBrief(items, compact){ |
| |
2410 | + const g = t => t === "good" ? "✓" : t === "bad" ? "✕" : t === "warn" ? "!" : "○"; |
| |
2411 | + return `<ul class="sk-brief">${items.map(c => `<li><span class="sk-brief-ico ${c.tone === "info" ? "neutral" : c.tone}" aria-hidden="true">${g(c.tone)}</span> |
| |
2412 | + <div><div class="sk-brief-t">${esc(c.titre)}</div>${!compact && c.detail ? `<div class="sk-brief-d">${esc(c.detail)}</div>` : ""}</div></li>`).join("")}</ul>`; |
| |
2413 | +} |
| |
2414 | +function skCard(id, title, ico, body, sub, aside){ |
| |
2415 | + return `<section id="sk-${id}" class="sk-card">${title ? `<div class="sk-card-head"><div><h2 class="sk-card-title">${ico || ""}${esc(title)}</h2>${sub ? `<p class="sk-card-sub">${sub}</p>` : ""}</div>${aside ? `<div class="sk-card-aside">${aside}</div>` : ""}</div>` : ""}${body}</section>`; |
| |
2416 | +} |
| |
2417 | +function skFact(ico, v, l){ return `<div class="sk-fact" role="listitem"><span class="sk-fact-ico" aria-hidden="true">${ico}</span><span class="sk-fact-txt"><div class="sk-fact-v" title="${esc(v)}">${esc(v)}</div><div class="sk-fact-l">${esc(l)}</div></span></div>`; } |
| |
2418 | +function skKv(k, v){ return `<div class="sk-kv"><span class="k">${esc(k)}</span><span class="v">${v}</span></div>`; } |
| |
2419 | +function skDetails(title, body, meta){ return `<details class="sk-details"><summary><span>${title}</span>${meta ? `<span class="sk-acc-meta">${esc(meta)}</span>` : ""}</summary><div class="sk-acc-inner">${body}</div></details>`; } |
| |
2420 | + |
| 1694 | async function showDetail(uid){ |
2421 | async function showDetail(uid){ |
| 1695 | let ev; |
2422 | let ev; |
| 1696 | try{ ev = await (await fetch(`/api/events/${encodeURIComponent(uid)}`)).json(); } |
2423 | try{ ev = await (await fetch(`/api/events/${encodeURIComponent(uid)}`)).json(); } |
| 1697 | catch(e){ go("/"); return; } |
2424 | catch(e){ go("/"); return; } |
| 1698 | if(ev.detail){ go("/"); return; } |
2425 | if(ev.detail){ go("/"); return; } |
| |
2426 | + SK_STATE.cleanup.forEach(f => { try{ f(); }catch(_){} }); SK_STATE.cleanup = []; SK_STATE.uid = ev.uid; |
| |
2427 | + FAV.meta[ev.uid] = favItem(ev); |
| 1699 | |
2428 | |
| 1700 | document.title = `${ev.title} — ${ev.city || "Québec"} | Sorti·Ka`; |
2429 | document.title = `${ev.title} — ${ev.city || "Québec"} | Sorti·Ka`; |
| 1701 | − $("d-img").innerHTML = ev.image |
2430 | + const cats = (ev.categories||[]).filter(c=>c!=="autre").map(c=>CAT_LABELS[c]||c); |
| 1702 | − ? `<img src="${esc(ev.image)}" alt="" onerror="this.remove()">` : ""; |
2431 | + const catTxt = cats.join(" · ") || "Événement"; |
| 1703 | − $("d-img").classList.toggle("noimg", !ev.image); |
2432 | + const src = SRC_LABELS[ev.source] || ev.source; |
| 1704 | − $("d-cats-label").textContent = (ev.categories||[]).filter(c=>c!=="autre") |
2433 | + const brief = skEnBref(ev); |
| 1705 | − .map(c=>CAT_LABELS[c]||c).join(" · ") || "Événement"; |
2434 | + const quand = skQuand(ev); |
| 1706 | − $("d-status").innerHTML = ev.status && STATUS_LABELS[ev.status] |
2435 | + const prix = skPrix(ev); |
| 1707 | − ? `<div class="status-banner status-banner--${esc(ev.status)}">${ |
2436 | + const resume = [ev.venue, ev.city, evDate(ev)].filter(Boolean); |
| 1708 | − ev.status==="cancelled" ? "Cet événement est annulé" |
2437 | + const geo = ev.lat && ev.lng; |
| 1709 | − : ev.status==="postponed" ? "Cet événement est reporté — vérifiez la nouvelle date chez la source" |
2438 | + const statusCap = ev.status && STATUS_LABELS[ev.status] ? `<span class="sk-capsule high"><b>${esc(STATUS_LABELS[ev.status])}</b></span>` : ""; |
| 1710 | − : "Complet — plus de billets disponibles"}</div>` : ""; |
2439 | + const dateCap = quand ? `<span class="sk-capsule ${quand.tone === "good" ? "good" : quand.tone === "bad" ? "high" : "date"}"><b>${esc(quand.titre)}</b></span>` : ""; |
| 1711 | − $("d-title").textContent = ev.title; |
2440 | + const shareBtn = (cls) => `<button type="button" class="${cls}" data-sk-share aria-label="Partager">${SK_ICO.share}</button>`; |
| 1712 | − $("d-fav").innerHTML = favBtn(ev, true); |
2441 | + const cta = (cls, txt) => `<a class="${cls}" href="${esc(ev.url)}" target="_blank" rel="noopener noreferrer">${txt} ${SK_ICO.ext}</a>`; |
| 1713 | − $("d-desc").textContent = ev.description || ""; |
2442 | + const nav = [["resume","Résumé"],["quand","Quand et où"],["programme","Programme"],["billets","Billets"],["similaires","À voir aussi"],["dossier","Dossier"],["sources","Sources"]]; |
| 1714 | − $("d-cats").innerHTML = (ev.raw_categories||[]).slice(0,5).filter(c=>c.length<40) |
2443 | + |
| 1715 | − .map(c=>`<span class="cat">${esc(c)}</span>`).join(""); |
2444 | + // --- faits « Quand et où » |
| 1716 | − |
| |
| 1717 | const facts = []; |
2445 | const facts = []; |
| 1718 | − facts.push(["Quand", dateBadge(ev, true)]); |
2446 | + if(ev.start_date) facts.push(skFact(SK_ICO.cal, fmtDate(ev.start_date, true), ev.end_date && ev.end_date !== ev.start_date ? `Du … au ${fmtDate(ev.end_date, true)}` : "Date")); |
| 1719 | − if(ev.artists && ev.artists.length) |
2447 | + if(ev.start_time) facts.push(skFact(SK_ICO.cal, `${fmtTime(ev.start_time)}${ev.end_time ? ` – ${fmtTime(ev.end_time)}` : ""}`, "Heure")); |
| 1720 | − facts.push(["À l'affiche", ev.artists.map(esc).join(", ")]); |
2448 | + if(ev.venue) facts.push(skFact(SK_ICO.pin, ev.venue, "Lieu")); |
| 1721 | − if(ev.venue) facts.push(["Lieu", esc(ev.venue)]); |
2449 | + if(ev.city) facts.push(skFact(SK_ICO.pin, ev.city, ev.region && ev.region !== ev.city ? `Ville · ${ev.region}` : "Ville")); |
| 1722 | − if(ev.address) facts.push(["Adresse", esc(ev.address)]); |
2450 | + if(ev.audience) facts.push(skFact(SK_ICO.people, ev.audience, "Public")); |
| 1723 | − if(ev.city) facts.push(["Ville", esc(ev.city)]); |
2451 | + if(ev.organizer) facts.push(skFact(SK_ICO.people, ev.organizer, "Organisé par")); |
| 1724 | − if(ev.region) facts.push(["Région", esc(ev.region)]); |
2452 | + const rows = []; |
| 1725 | − if(ev.is_free === true) facts.push(["Prix", `<span class="badge-free">Gratuit</span>`]); |
2453 | + if(ev.address) rows.push(skKv("Adresse", esc([ev.address, ev.city, ev.postal_code].filter(Boolean).join(", ")))); |
| 1726 | − else if(ev.price_min != null) facts.push(["Prix", `Dès ${ev.price_min.toFixed(2).replace(".",",")} $ CAD`]); |
2454 | + if(ev.tourist_region) rows.push(skKv("Région touristique", esc(ev.tourist_region))); |
| 1727 | − else if(ev.is_free === false) facts.push(["Prix", "Payant — voir la billetterie"]); |
2455 | + if(geo) rows.push(skKv("Itinéraire", `<a href="https://www.google.com/maps?q=${ev.lat},${ev.lng}" target="_blank" rel="noopener">Google Maps ↗</a> · <a href="https://maps.apple.com/?q=${ev.lat},${ev.lng}" target="_blank" rel="noopener">Plans ↗</a>`)); |
| 1728 | − if(ev.price_label) facts.push(["Détail prix", esc(ev.price_label)]); |
2456 | + |
| 1729 | − if(ev.audience) facts.push(["Public", esc(ev.audience)]); |
2457 | + // --- programme |
| 1730 | − if(ev.organizer) facts.push(["Organisé par", esc(ev.organizer)]); |
2458 | + const desc = (ev.description || "").trim(); |
| 1731 | − if(ev.lat && ev.lng) facts.push(["Carte", |
2459 | + const long = desc.length > 420; |
| 1732 | − `<a class="maplink" target="_blank" rel="noopener" href="https://www.google.com/maps?q=${ev.lat},${ev.lng}">Voir sur la carte ↗</a>`]); |
2460 | + const raw = (ev.raw_categories||[]).filter(c => c && c.length < 40).slice(0, 8); |
| 1733 | − $("d-facts").innerHTML = facts.map(([k,v]) => |
2461 | + |
| 1734 | − `<div class="fact"><span class="k">${k}</span><span class="v">${v}</span></div>`).join(""); |
2462 | + const html = ` |
| 1735 | − |
2463 | + <div class="sk-wrap"> |
| 1736 | − $("d-cta").href = ev.url; |
2464 | + <nav class="sk-crumbs" aria-label="Fil d'Ariane"><a data-nav href="/">Sorties</a><span aria-hidden="true">›</span>${ev.region ? `<a data-nav href="/region/${esc(kaSlug(ev.region))}">${esc(ev.region)}</a><span aria-hidden="true">›</span>` : ""}<span>${esc(ev.title)}</span></nav> |
| 1737 | − $("d-ctabar").innerHTML = `<div class="p"> |
2465 | + <div class="sk-grid"> |
| 1738 | − <b>${priceTxt(ev) || (ev.is_free === false ? "Payant — voir la billetterie" : "Voir la billetterie")}</b> |
2466 | + <div class="sk-main"> |
| 1739 | − <span>${evDate(ev)}</span></div> |
2467 | + <header class="sk-hero" aria-label="Résumé de l'événement"> |
| 1740 | − <a class="btn btn-cta" href="${esc(ev.url)}" target="_blank" rel="noopener">Billets ↗</a>`; |
2468 | + <div class="sk-kicker">${esc(catTxt)} · ${esc(src)}</div> |
| 1741 | − $("d-src").innerHTML = `<span class="klabel">Source & attribution</span> |
2469 | + <div class="sk-price">${esc(prix)}${ev.price_label && ev.price_min != null ? `<small>${esc(ev.price_label)}</small>` : ""}</div> |
| 1742 | − <div style="margin-top:6px;font-size:13px">${SRC_LABELS[ev.source]||ev.source}</div> |
2470 | + <div class="sk-price-row" style="margin-top:8px">${dateCap}${statusCap}${ev.is_free === true ? `<span class="sk-capsule good"><b>Gratuit</b></span>` : ""}</div> |
| 1743 | − <div style="font-family:var(--font-mono);font-size:10px;color:var(--ink-3);margin-top:4px"> |
2471 | + <h1 class="sk-h1">${esc(ev.title)}${resume.length ? `<span class="sk-city">${resume.map(esc).join(" · ")}</span>` : ""}</h1> |
| 1744 | − Capté le ${new Date((ev.updated_at||0)*1000).toLocaleDateString("fr-CA")} · |
2472 | + <div class="sk-image ${ev.image ? "" : "noimg"}">${ev.image ? `<img src="${esc(ev.image)}" alt="" onerror="this.parentNode.classList.add('noimg');this.remove()">` : esc(catTxt)}</div> |
| 1745 | − identifiant ${esc(ev.uid)}</div>`; |
2473 | + <div class="sk-actions" id="sk-actions">${favBtn(ev, true)}${shareBtn("sk-btn sk-btn-ghost sk-btn-icon")}${cta("sk-btn sk-btn-primary", ev.is_free === true ? "Voir la fiche originale" : "Billets")}</div> |
| |
2474 | + </header> |
| |
2475 | + ${skCard("resume", "En bref", "", skBrief(brief))} |
| |
2476 | + <nav class="sk-nav" aria-label="Sections de la fiche"><div class="sk-nav-track" id="sk-nav">${nav.map(([id,l], i) => `<a href="#sk-${id}" data-sk-nav="sk-${id}" class="${i === 0 ? "on" : ""}">${l}</a>`).join("")}</div></nav> |
| |
2477 | + ${skCard("quand", "Quand et où", SK_ICO.pin, `${facts.length ? `<div class="sk-facts" role="list">${facts.join("")}</div>` : ""}${rows.length ? `<div class="sk-facts-rows">${rows.join("")}</div>` : ""}${geo ? `<div class="sk-map" style="position:relative;border-radius:var(--sk-r-lg);overflow:hidden;border:1px solid var(--sk-border);margin-top:12px"><div id="sk-map" style="position:absolute;inset:0"></div></div><div class="sk-source"><span>Source : <b>OpenStreetMap</b> · position géocodée de l'adresse publiée</span></div>` : ""}`, ev.venue ? `${esc(ev.venue)}${ev.city ? ` — ${esc(ev.city)}` : ""}` : "")} |
| |
2478 | + ${skCard("programme", "Programme", SK_ICO.music, `${desc ? `<div class="sk-desc ${long ? "clamped" : ""}" id="sk-desc"><div class="sk-desc-body"><p>${esc(desc)}</p></div></div>${long ? `<button type="button" class="sk-more" data-sk-more aria-expanded="false">Lire la suite</button>` : ""}` : `<p class="sk-fine" style="margin-top:0">La source ne fournit pas de description pour cet événement.</p>`}${ev.artists && ev.artists.length ? `<h3 class="sk-card-sub sk-subtitle" id="artistes">À l'affiche <small>· ${ev.artists.length}</small></h3><div class="sk-amen" role="list">${ev.artists.map(a => `<div class="sk-amen-it" role="listitem"><span class="sk-amen-ico" aria-hidden="true">${SK_ICO.music}</span><span class="sk-amen-txt">${esc(a)}</span></div>`).join("")}</div>` : ""}${raw.length ? `<div class="sk-tags" style="margin-top:12px">${raw.map(c => `<span class="sk-tag n">${esc(c)}</span>`).join("")}</div>` : ""}`)} |
| |
2479 | + ${skCard("billets", "Billets et prix", SK_ICO.ticket, `<div class="sk-kpis cols-3"><div class="sk-kpi accent"><div class="sk-kpi-v">${esc(prix)}</div><div class="sk-kpi-l">${ev.is_free === true ? "Entrée" : ev.price_min != null ? "Prix d'entrée minimum" : "Tarification"}</div></div>${ev.price_label ? `<div class="sk-kpi"><div class="sk-kpi-v wrap">${esc(ev.price_label)}</div><div class="sk-kpi-l">Détail publié</div></div>` : ""}<div class="sk-kpi"><div class="sk-kpi-v wrap">${esc(src)}</div><div class="sk-kpi-l">Billetterie / source</div></div></div>${cta("sk-btn sk-btn-primary", ev.is_free === true ? "Fiche originale" : "Acheter des billets chez " + src).replace('class="sk-btn sk-btn-primary"', 'class="sk-btn sk-btn-primary" style="margin-top:12px;width:100%"')}<p class="sk-fine">Prix affichés par la source lors de la dernière synchronisation — frais de service et taxes en sus possibles. Sorti·Ka ne vend pas de billets.</p>`)} |
| |
2480 | + ${skCard("similaires", "À voir aussi", SK_ICO.tag, `<div class="grid" id="d-similar"><div class="sk-skel-lines" aria-busy="true"><div class="sk-skel"></div><div class="sk-skel"></div><div class="sk-skel short"></div></div></div>`, cats[0] ? `Autres sorties « ${esc(cats[0])} »${ev.region ? ` en ${esc(ev.region)}` : ""}` : "Autres sorties à proximité")} |
| |
2481 | + ${skCard("dossier", "Dossier de la fiche", SK_ICO.folder, `${skDetails(`${SK_ICO.people} Organisateur et source`, `<p style="margin:0 0 6px"><b style="font-size:15px">${esc(ev.organizer || src)}</b></p><p style="margin:0">Fiche publiée par <b>${esc(src)}</b>${ev.website ? ` · <a href="${esc(ev.website)}" target="_blank" rel="noopener noreferrer">site de l'événement ↗</a>` : ""}. Sorti·Ka est un agrégateur indépendant : billets, horaires et annulations relèvent de l'organisateur.</p>`, esc(ev.organizer || src))}${skDetails(`${SK_ICO.cal} Suivi Sorti·Ka`, `<div class="sk-facts-rows" style="margin-top:0">${skKv("Première observation", ev.first_seen ? new Date(ev.first_seen*1000).toLocaleDateString("fr-CA", {day:"numeric", month:"long", year:"numeric"}) : "—")}${skKv("Dernière synchronisation", ev.updated_at ? new Date(ev.updated_at*1000).toLocaleDateString("fr-CA", {day:"numeric", month:"long", year:"numeric"}) : "—")}${skKv("Statut", ev.active ? "Publié par la source" : "Retiré")}</div>`, ev.updated_at ? `synchro ${new Date(ev.updated_at*1000).toLocaleDateString("fr-CA")}` : "")}${skDetails(`${SK_ICO.tag} Identifiants`, `<div class="sk-facts-rows" style="margin-top:0">${skKv("Identifiant source", esc(ev.external_id || ""))}${skKv("Identifiant Sorti·Ka", esc(ev.uid))}${skKv("Fiche originale", `<a href="${esc(ev.url)}" target="_blank" rel="noopener noreferrer">${esc(src)} ↗</a>`)}</div>`, esc(ev.external_id || ""))}`, "Ce que Sorti·Ka observe réellement : organisateur, suivi, identifiants")} |
| |
2482 | + ${skCard("sources", "Sources et méthodologie", SK_ICO.folder, `<ul class="sk-sources"><li><span class="n"><a href="${esc(ev.url)}" target="_blank" rel="noopener noreferrer">${esc(src)}</a></span><span class="r">Titre, dates, lieu, prix, image et description (source originale)</span></li><li><span class="n">Sorti·Ka</span><span class="r">Catégorisation, géocodage, dédoublonnage entre sources, suivi des statuts — calculs maison, indicatifs</span></li>${geo ? `<li><span class="n">OpenStreetMap</span><span class="r">Fond de carte et position du lieu</span></li>` : ""}</ul><div class="sk-end" style="margin-top:14px"><a href="/#sources">${SK_ICO.folder}Sources<small>Toutes les sources Sorti·Ka</small></a><a data-nav href="/contact">${SK_ICO.alert}Signaler une erreur<small>Date, lieu, prix…</small></a><button type="button" data-sk-share>${SK_ICO.share}Partager<small>Lien de la fiche</small></button><a data-nav href="/stats">${SK_ICO.tag}Statistiques<small>Sorties par région</small></a></div><p class="sk-fine" style="margin-top:12px">Les dates, prix et disponibilités sont ceux affichés par la source — chaque fiche renvoie à la page originale. Sorti·Ka est un agrégateur indépendant.</p>`, "Chaque donnée de cette fiche renvoie à sa source ; les calculs Sorti·Ka sont indicatifs et documentés")} |
| |
2483 | + </div> |
| |
2484 | + <aside class="sk-aside" aria-label="Résumé et actions"><div class="sk-card sk-aside-card"> |
| |
2485 | + <div><div class="sk-price">${esc(prix)}</div><div class="sk-price-row" style="margin-top:8px">${dateCap}${statusCap}</div></div> |
| |
2486 | + <div class="sk-aside-addr"><b style="color:var(--sk-text)">${esc(ev.title)}</b><br>${resume.map(esc).join(" · ")}</div> |
| |
2487 | + ${cta("sk-btn sk-btn-primary", ev.is_free === true ? "Voir la fiche originale" : "Billets chez " + esc(src))} |
| |
2488 | + <div class="sk-actions" id="sk-aside-actions">${favBtn(ev, true)}${shareBtn("sk-btn sk-btn-ghost")}</div> |
| |
2489 | + <button type="button" class="sk-btn sk-btn-ghost sk-ka-inline" data-sk-ka>${SK_ICO.spark} Demander à Ka</button> |
| |
2490 | + ${brief.length ? `<hr class="sk-aside-sep">${skBrief(brief.slice(0, 4), true)}` : ""} |
| |
2491 | + <div class="sk-aside-meta">${ev.updated_at ? `Synchronisé le ${new Date(ev.updated_at*1000).toLocaleDateString("fr-CA")} · ` : ""}${esc(src)}</div> |
| |
2492 | + </div></aside> |
| |
2493 | + </div> |
| |
2494 | + </div> |
| |
2495 | + <div class="sk-cta-bar" id="sk-ctabar" aria-hidden="true"><div class="sk-cta-txt"><div class="sk-cta-price">${esc(prix)}</div><div class="sk-cta-sub ${quand.tone === "good" ? "good" : ""}">${esc(quand.titre)} · ${esc(ev.venue || ev.city || "")}</div></div>${cta("sk-btn sk-btn-primary", ev.is_free === true ? "Fiche" : "Billets")}</div> |
| |
2496 | + <button type="button" class="sk-ka-btn hide" id="sk-ka-btn" data-sk-ka aria-label="Demander à Ka, l'assistant Groupe KA">${SK_ICO.spark} Demander à Ka</button>`; |
| |
2497 | + |
| |
2498 | + const root = $("sk-root"); |
| |
2499 | + root.innerHTML = html; |
| |
2500 | + bindNav(root); |
| |
2501 | + // header compact : favoris + partage à côté de la marque (retirés en quittant la fiche) |
| |
2502 | + let hdr = $("sk-hdr"); |
| |
2503 | + if(!hdr){ hdr = document.createElement("div"); hdr.id = "sk-hdr"; hdr.className = "hdr-actions"; const b = document.querySelector(".header .brand"); b.parentNode.insertBefore(hdr, b.nextSibling); } |
| |
2504 | + hdr.innerHTML = `${favBtn(ev)}<button type="button" class="hdr-btn" data-sk-share aria-label="Partager">${SK_ICO.share}</button>`; |
| |
2505 | + favPaint(); |
| |
2506 | + |
| |
2507 | + // partage |
| |
2508 | + document.querySelectorAll("[data-sk-share]").forEach(b => b.onclick = async () => { |
| |
2509 | + const url = `https://www.sorti-ka.com/evenement/${encodeURIComponent(ev.uid)}`; |
| |
2510 | + try{ |
| |
2511 | + if(navigator.share){ await navigator.share({ title: `${ev.title} — Sorti·Ka`, url }); return; } |
| |
2512 | + await navigator.clipboard.writeText(url); toast("Lien copié"); |
| |
2513 | + }catch(_){} |
| |
2514 | + }); |
| |
2515 | + // description « Lire la suite » |
| |
2516 | + const more = root.querySelector("[data-sk-more]"); |
| |
2517 | + if(more) more.onclick = () => { const open = $("sk-desc").classList.toggle("clamped") === false; more.textContent = open ? "Réduire" : "Lire la suite"; more.setAttribute("aria-expanded", open); }; |
| |
2518 | + // navigation par sections : scroll-spy + défilement doux (jamais à l'ouverture) |
| |
2519 | + const navEl = $("sk-nav"); |
| |
2520 | + const links = [...navEl.querySelectorAll("a[data-sk-nav]")]; |
| |
2521 | + links.forEach(a => a.onclick = e => { e.preventDefault(); const t = $(a.dataset.skNav); if(t) t.scrollIntoView({ behavior:"smooth", block:"start" }); }); |
| |
2522 | + const visible = new Map(); |
| |
2523 | + const io = new IntersectionObserver(entries => { |
| |
2524 | + entries.forEach(en => visible.set(en.target.id, en.isIntersecting ? en.intersectionRatio : 0)); |
| |
2525 | + const first = nav.map(([id]) => "sk-" + id).find(id => (visible.get(id) || 0) > 0); |
| |
2526 | + if(first){ links.forEach(a => a.classList.toggle("on", a.dataset.skNav === first)); const on = navEl.querySelector(".on"); if(on){ const l = on.offsetLeft, r = l + on.offsetWidth; if(l < navEl.scrollLeft) navEl.scrollTo({ left: Math.max(0, l - 12), behavior:"smooth" }); else if(r > navEl.scrollLeft + navEl.clientWidth) navEl.scrollTo({ left: r - navEl.clientWidth + 12, behavior:"smooth" }); } } |
| |
2527 | + }, { rootMargin:"-120px 0px -55% 0px", threshold:[0, .1, .5] }); |
| |
2528 | + nav.forEach(([id]) => { const el = $("sk-" + id); if(el) io.observe(el); }); |
| |
2529 | + SK_STATE.cleanup.push(() => io.disconnect()); |
| |
2530 | + // CTA sticky + bouton Ka : après le héro |
| |
2531 | + const actions = $("sk-actions"), bar = $("sk-ctabar"), kab = $("sk-ka-btn"); |
| |
2532 | + const onScroll = () => { const past = actions.getBoundingClientRect().bottom < 0; bar.classList.toggle("show", past); bar.setAttribute("aria-hidden", !past); kab.classList.toggle("hide", !past); }; |
| |
2533 | + window.addEventListener("scroll", onScroll, { passive:true }); onScroll(); |
| |
2534 | + SK_STATE.cleanup.push(() => window.removeEventListener("scroll", onScroll)); |
| |
2535 | + // Demander à Ka |
| |
2536 | + root.querySelectorAll("[data-sk-ka]").forEach(b => b.onclick = () => skOpenKa(ev)); |
| |
2537 | + |
| |
2538 | + show("view-detail"); |
| |
2539 | + window.scrollTo({ top:0 }); |
| |
2540 | + |
| |
2541 | + // carte Leaflet (après l'affichage : le conteneur doit être mesurable) |
| |
2542 | + if(geo){ |
| |
2543 | + ensureLeaflet().then(() => { |
| |
2544 | + const m = L.map("sk-map", { zoomControl:true, scrollWheelZoom:false }).setView([ev.lat, ev.lng], 14); |
| |
2545 | + L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { attribution:"© <a href='https://www.openstreetmap.org/copyright'>OpenStreetMap</a>", maxZoom:19 }).addTo(m); |
| |
2546 | + L.marker([ev.lat, ev.lng]).addTo(m).bindPopup(`<b>${esc(ev.venue || ev.title)}</b><br>${esc([ev.address, ev.city].filter(Boolean).join(", "))}`); |
| |
2547 | + setTimeout(() => m.invalidateSize(), 120); |
| |
2548 | + SK_STATE.cleanup.push(() => { try{ m.remove(); }catch(_){} }); |
| |
2549 | + }).catch(() => { const w = $("sk-map"); if(w) w.parentNode.innerHTML = `<div class="sk-empty">Carte indisponible — vérifiez la connexion.</div>`; }); |
| |
2550 | + } |
| 1746 | |
2551 | |
| 1747 | // événements similaires : même catégorie prioritaire, sinon même ville |
2552 | // événements similaires : même catégorie prioritaire, sinon même ville |
| 1748 | const cat = (ev.categories||[]).filter(c=>c!=="autre")[0] || ""; |
2553 | const cat = (ev.categories||[]).filter(c=>c!=="autre")[0] || ""; |
| 1749 | − const q = new URLSearchParams({limit: 7}); |
2554 | + const q = new URLSearchParams({ limit: 7 }); |
| 1750 | if(cat) q.set("category", cat); else if(ev.city) q.set("city", ev.city); |
2555 | if(cat) q.set("category", cat); else if(ev.city) q.set("city", ev.city); |
| 1751 | if(ev.region && cat) q.set("region", ev.region); |
2556 | if(ev.region && cat) q.set("region", ev.region); |
| 1752 | try{ |
2557 | try{ |
| 1753 | const sim = await (await fetch(`/api/events?${q}`)).json(); |
2558 | const sim = await (await fetch(`/api/events?${q}`)).json(); |
| 1754 | − const others = sim.events.filter(e=>e.uid!==ev.uid).slice(0,6); |
2559 | + const others = sim.events.filter(e => e.uid !== ev.uid).slice(0, 6); |
| 1755 | − $("d-similar").innerHTML = others.map(card).join("") || |
2560 | + const host = $("d-similar"); |
| 1756 | − `<div class="empty">Rien de similaire pour l'instant.</div>`; |
2561 | + if(host && SK_STATE.uid === ev.uid){ host.innerHTML = others.map(card).join("") || `<div class="sk-empty">Rien de similaire pour l'instant.</div>`; bindNav(host); favPaint(); } |
| 1757 | − bindNav($("d-similar")); |
2562 | + }catch(e){ const host = $("d-similar"); if(host) host.innerHTML = ""; } |
| 1758 | − }catch(e){ $("d-similar").innerHTML = ""; } |
2563 | +} |
| 1759 | − |
2564 | + |
| 1760 | − show("view-detail"); |
2565 | +/* « ✦ Demander à Ka » : bottom sheet de démarrage → widget KA Agent (ka-agent.js) */ |
| 1761 | − window.scrollTo({top:0}); |
2566 | +const SK_SUGS = ["Cet événement vaut-il le détour ?", "Que faire autour avant ou après ?", "Trouve des sorties semblables ce week-end", "Y a-t-il des billets moins chers ?", "Résume le programme"]; |
| |
2567 | +function skEnvoyerKa(question){ |
| |
2568 | + const btn = document.querySelector(".kaa-btn"), ta = document.querySelector(".kaa-panel textarea"), send = document.querySelector(".kaa-in button"); |
| |
2569 | + if(!btn || !ta || !send) return false; |
| |
2570 | + btn.click(); ta.value = question; setTimeout(() => send.click(), 60); return true; |
| |
2571 | +} |
| |
2572 | +function skOpenKa(ev){ |
| |
2573 | + const ctx = `(Événement consulté sur Sorti·Ka : ${ev.title}${ev.venue ? ` — ${ev.venue}` : ""}${ev.city ? `, ${ev.city}` : ""}${ev.start_date ? ` — ${fmtDate(ev.start_date, true)}` : ""} — https://www.sorti-ka.com/evenement/${encodeURIComponent(ev.uid)})`; |
| |
2574 | + const old = $("sk-sheet"); if(old) old.remove(); |
| |
2575 | + const el = document.createElement("div"); el.id = "sk-sheet"; |
| |
2576 | + el.innerHTML = `<div class="sk-sheet-backdrop" data-close aria-hidden="true"></div> |
| |
2577 | + <div class="sk-sheet" role="dialog" aria-modal="true" aria-label="Demander à Ka" tabindex="-1"> |
| |
2578 | + <div class="sk-sheet-handle"></div> |
| |
2579 | + <div class="sk-sheet-head"><div><h3 class="sk-sheet-title">Demander à Ka</h3><p class="sk-sheet-sub">Assistant Groupe KA · connaît cette fiche</p></div><button type="button" class="sk-sheet-x" data-close aria-label="Fermer">✕</button></div> |
| |
2580 | + <div class="sk-sheet-body"> |
| |
2581 | + <div class="sk-ka-intro"><span class="sk-ka-avatar" aria-hidden="true">${SK_ICO.spark}</span><p>Je peux situer cette sortie, proposer quoi faire autour, comparer les billets et chercher des événements semblables partout au Québec.</p></div> |
| |
2582 | + <div class="sk-ka-ctx">${ev.image ? `<img src="${esc(ev.image)}" alt="">` : ""}<span style="min-width:0"><b>${esc(ev.title)}</b>${[ev.venue || ev.city, evDate(ev), skPrix(ev)].filter(Boolean).map(esc).join(" · ")}</span></div> |
| |
2583 | + <div class="sk-ka-sugs">${SK_SUGS.map(s => `<button type="button" class="sk-ka-sug" data-q="${esc(s)}">${esc(s)} ${SK_ICO.chev}</button>`).join("")}</div> |
| |
2584 | + <p class="sk-note warn hidden" id="sk-ka-err">L'assistant n'est pas encore chargé — réessayez dans un instant.</p> |
| |
2585 | + </div> |
| |
2586 | + <div class="sk-sheet-foot"><form class="sk-ka-in" id="sk-ka-form"><input placeholder="Posez votre question sur cette sortie…" aria-label="Votre question"><button type="submit" aria-label="Envoyer">${SK_ICO.chev}</button></form></div> |
| |
2587 | + </div>`; |
| |
2588 | + document.body.appendChild(el); |
| |
2589 | + document.documentElement.classList.add("ka-scroll-lock"); |
| |
2590 | + const close = () => { el.remove(); document.documentElement.classList.remove("ka-scroll-lock"); window.removeEventListener("keydown", onKey); }; |
| |
2591 | + const onKey = e => { if(e.key === "Escape") close(); }; |
| |
2592 | + window.addEventListener("keydown", onKey); |
| |
2593 | + el.querySelectorAll("[data-close]").forEach(b => b.onclick = close); |
| |
2594 | + const poser = q => { if(skEnvoyerKa(`${q}\n\n${ctx}`)) close(); else $("sk-ka-err").classList.remove("hidden"); }; |
| |
2595 | + el.querySelectorAll(".sk-ka-sug").forEach(b => b.onclick = () => poser(b.dataset.q)); |
| |
2596 | + $("sk-ka-form").onsubmit = e => { e.preventDefault(); const v = e.target.querySelector("input").value.trim(); if(v) poser(v); }; |
| |
2597 | + setTimeout(() => el.querySelector(".sk-sheet").focus(), 30); |
| 1762 | } |
2598 | } |
| 1763 | |
2599 | |
| 1764 | /* ==================== vue /stats — module ka-stats (vanilla + SVG) ========= |
2600 | /* ==================== vue /stats — module ka-stats (vanilla + SVG) ========= |
| 2661 | const VIEWS = ["view-list","view-detail","view-contact","view-stats","view-favoris"]; |
3497 | const VIEWS = ["view-list","view-detail","view-contact","view-stats","view-favoris"]; |
| 2662 | function show(id){ |
3498 | function show(id){ |
| 2663 | VIEWS.forEach(v => $(v).classList.toggle("hidden", v !== id)); |
3499 | VIEWS.forEach(v => $(v).classList.toggle("hidden", v !== id)); |
| |
3500 | + // fiche événement : fond papier, header compact, ticker/tabbar/bulle KA masqués |
| |
3501 | + document.body.classList.toggle("sk-fiche-page", id === "view-detail"); |
| |
3502 | + if(id !== "view-detail"){ const hd = $("sk-hdr"); if(hd) hd.remove(); } |
| |
3503 | + if(id !== "view-detail" && SK_STATE.cleanup.length){ SK_STATE.cleanup.forEach(f => { try{ f(); }catch(_){} }); SK_STATE.cleanup = []; } |
| 2664 | } |
3504 | } |
| 2665 | |
3505 | |
| 2666 | function showList(){ |
3506 | function showList(){ |
| 2713 | }); |
3553 | }); |
| 2714 | } |
3554 | } |
| 2715 | window.addEventListener("popstate", route); |
3555 | window.addEventListener("popstate", route); |
| 2716 | −$("back").onclick = () => go("/"); |
3556 | +/* (le lien « Toutes les sorties » de l'ancienne fiche est remplacé par le fil d'Ariane de la fiche v3) */ |
| 2717 | |
3557 | |
| 2718 | /* ---------- KA Nav v2 : menu mobile plein écran (2026-08-25) ---------- */ |
3558 | /* ---------- KA Nav v2 : menu mobile plein écran (2026-08-25) ---------- */ |
| 2719 | (function(){ |
3559 | (function(){ |
| 2720 | |
3560 | |