]> git.openstreetmap.org Git - rails.git/blob - app/assets/stylesheets/common.scss
Move role colors to css
[rails.git] / app / assets / stylesheets / common.scss
1 @use "sass:map";
2 @import "parameters";
3 @import "bootstrap";
4 @import "rails_bootstrap_forms";
5 @import "colors";
6
7 /* Styles common to large and small screens */
8
9 /* Default rules for the body of every page */
10
11 body {
12   font-size: $typeheight;
13   --dark-mode-map-filter: none;
14 }
15
16 time[title] {
17   text-decoration: underline dotted;
18 }
19
20 /* Utility for de-emphasizing content */
21
22 .text-body-secondary a {
23   color: $blue;
24 }
25
26 /* Bootstrap contextual table classes overrides in dark mode */
27
28 @include color-mode(dark) {
29   .table-primary {
30     --bs-table-bg: rgb(var(--bs-primary-rgb), .25);
31   }
32   .table-secondary {
33     --bs-table-bg: rgb(var(--bs-secondary-rgb), .25);
34   }
35   .table-success {
36     --bs-table-bg: rgb(var(--bs-success-rgb), .25);
37   }
38   .table-primary, .table-secondary, .table-success {
39     --bs-table-color: initial;
40     border-color: inherit;
41   }
42 }
43
44 /* Utility for delayed loading spinner */
45
46 .delayed-fade-in {
47   animation: 300ms linear forwards delayed-fade-in;
48 }
49
50 @keyframes delayed-fade-in {
51   0%   { opacity: 0 }
52   66%  { opacity: 0 }
53   100% { opacity: 1 }
54 }
55
56 /* Bootstrap close button overrides for nested light/dark themes */
57
58 [data-bs-theme="dark"],
59 [data-bs-theme] [data-bs-theme="dark"] {
60   --bs-btn-close-filter: invert(1) grayscale(100%) brightness(200%);
61 }
62
63 [data-bs-theme="light"],
64 [data-bs-theme] [data-bs-theme="light"] {
65   --bs-btn-close-filter: none;
66 }
67
68 /* Rules for the header */
69
70 #menu-icon {
71   display: none;
72   position: absolute;
73   top: 0;
74   right: 0;
75   background: image-url("menu-icon.svg") no-repeat;
76   background-size: 30px 30px;
77   width: 30px;
78   height: 30px;
79   margin: 14px 10px 0 0;
80   opacity: 0.6;
81 }
82
83 @include color-mode(dark) {
84   #menu-icon {
85     filter: invert(1);
86   }
87 }
88
89 header {
90   height: $headerHeight;
91   position: relative;
92   font-size: 14px;
93
94   > * {
95     padding: $lineheight * 0.5;
96   }
97
98   h1 {
99     height: $headerHeight;
100     font-size: 18px;
101   }
102
103   .btn {
104     font-size: 14px;
105   }
106
107   .username {
108     max-width: 12em;
109   }
110 }
111
112 nav.primary {
113   #edit_tab .btn-outline-primary {
114     @include button-outline-variant($green, $color-hover: $white, $active-color: $white);
115   }
116
117   .disabled {
118     .btn-outline-primary {
119       color: $grey;
120       cursor: default;
121
122       &:hover {
123         background-color: lighten($green, 30%);
124       }
125     }
126   }
127
128   // Small tweaks to the toggle to stop the primary colour showing through
129   // when the menu is shown
130   .show > .btn-outline-primary.dropdown-toggle {
131     background-color: $green;
132     border-color: $green;
133
134     &:focus {
135       box-shadow: 0 0 0 0.2rem fade-out($green, 0.5);
136     }
137   }
138 }
139
140 nav.secondary {
141   .nav-link {
142     padding: 0 0.3rem;
143   }
144
145   > ul {
146     height: 1.5em;
147   }
148 }
149
150 nav.primary, nav.secondary {
151   .dropdown-item {
152     &:hover, &:active {
153       background-color: $green;
154       color: white;
155     }
156   }
157 }
158
159 #compact-secondary-nav {
160   display: none;
161 }
162
163 body.small-nav {
164   #menu-icon {
165     display: block;
166   }
167
168   header {
169     flex-direction: column;
170     height: auto;
171     min-height: $headerHeight;
172
173     &.closed nav {
174       display: none !important;
175     }
176
177     .search_forms {
178       display: block;
179     }
180
181     .username {
182       max-width: unset;
183     }
184   }
185
186   #sidebar .search_forms {
187     display: none;
188   }
189
190   nav.primary {
191     margin-right: 0;
192     padding: 0;
193
194     #edit_tab {
195       width: 100%;
196       padding: 10px;
197     }
198   }
199
200   nav.secondary {
201     flex-direction: column;
202
203     > ul {
204       height: auto;
205       justify-content: center;
206     }
207
208     .user-menu, .login-menu {
209       width: 100%;
210     }
211   }
212
213   #compact-secondary-nav {
214     display: none;
215   }
216
217   .compact-hide {
218     display: inline-block;
219   }
220
221   .overlay-sidebar #sidebar .welcome {
222     display: none;
223   }
224
225   .overlay-sidebar #sidebar #banner {
226     display: none;
227   }
228 }
229
230 /* Rules for language selector */
231
232 button.d-md-none[data-bs-target="#select_language_dialog"] {
233   right: 50px;
234   top: 11px;
235 }
236
237 .select_language_list {
238   column-width: 160px;
239
240   small {
241     font-size: 10px;
242   }
243 }
244
245 /* Utility for styling notification numbers */
246
247 .count-number {
248   background: transparentize(lighten($green, 25%), .25);
249   color: $gray-800;
250   font-weight: $font-weight-normal;
251 }
252
253 /* Rules for Leaflet maps */
254
255 .leaflet-top.leaflet-right,
256 .leaflet-top.leaflet-left {
257   height: 100%;
258   column-gap: 10px;
259   display: flex;
260   flex-direction: column;
261   flex-wrap: wrap-reverse;
262 }
263
264 .leaflet-control .control-button {
265   display: block;
266   height: 40px;
267   width: 40px;
268   color: white;
269   padding: 10px;
270   background-color: rgba(0,0,0,.6);
271   outline: none;
272
273   &:hover,
274   &:focus {
275     background-color: black;
276   }
277
278   &.disabled,
279   &.leaflet-disabled {
280     background-color: rgba(0,0,0,.5);
281     cursor: default;
282   }
283
284   &-first {
285     border-start-start-radius: 4px;
286   }
287
288   &-last {
289     border-end-start-radius: 4px;
290     margin-bottom: 10px;
291   }
292 }
293
294 .leaflet-control.active .control-button {
295   background-color: $vibrant-green;
296 }
297
298 /* Rules for the sidebar and main map area */
299
300 .map-layout {
301   #content {
302     overflow: hidden;
303     position: absolute;
304     top: $headerHeight;
305     bottom: 0;
306     width: 100%;
307   }
308
309   #sidebar, #map {
310     position: relative;
311     height: 100%;
312     overflow-x: hidden;
313     overflow-y: auto;
314   }
315
316   #sidebar {
317     float: left;
318     width: $sidebarWidth;
319   }
320
321   .overlay-sidebar #sidebar {
322     position: absolute;
323     height: auto;
324     overflow: hidden;
325
326     #banner {
327       display: block;
328     }
329
330     .welcome {
331       display: block;
332     }
333
334     .sidebar-close-controls,
335     #sidebar_loader,
336     #sidebar_content {
337       display: none;
338     }
339   }
340
341   .welcome {
342     display: none;
343   }
344
345   #banner {
346     display: none;
347
348     img {
349       display: block;
350       width: $sidebarWidth;
351     }
352   }
353
354   #map {
355     height: 100%;
356     overflow: hidden;
357
358     &.query-active {
359       cursor: help;
360     }
361
362     &.query-disabled {
363       cursor: not-allowed;
364     }
365
366     .leaflet-marker-draggable {
367       cursor: move;
368     }
369
370     .query-marker {
371       animation: 1500ms forwards query-marker-fade;
372
373       @keyframes query-marker-fade {
374         to { opacity: 0 }
375       }
376     }
377   }
378
379   #map-ui {
380     display: none;
381     position: relative;
382     float: right;
383     width: 250px;
384     height: 100%;
385     overflow: auto;
386   }
387 }
388
389 @include media-breakpoint-down(md) {
390   body.map-layout {
391     #sidebar, #map {
392       position: relative;
393       overflow-x: hidden;
394       width: 100%;
395       height: 50%;
396     }
397
398     #map-ui {
399       width: 100%;
400       height: 50%;
401       overflow-y: scroll;
402     }
403
404     .overlay-sidebar.overlay-right-sidebar {
405       #sidebar {
406         position: absolute;
407         width: 350px;
408         height: auto;
409         overflow: hidden;
410       }
411
412       #map {
413         height: 100%;
414       }
415     }
416   }
417 }
418
419 .layers-ui {
420   .base-layers > * {
421     height: 3.5rem;
422
423     > .btn {
424       box-sizing: content-box;
425       top: - map.get($border-widths, 4);
426       left: - map.get($border-widths, 4);
427       --bs-btn-border-color: var(--bs-body-bg);
428     }
429     > .btn:hover {
430       --bs-btn-border-color: var(--bs-primary-border-subtle);
431     }
432   }
433
434   .overlay-layers {
435     .form-check.disabled { color: $darkgrey; }
436   }
437 }
438
439 .share-ui {
440   #mapnik_scale {
441     width: 100px;
442   }
443 }
444
445 .leaflet-top {
446   top: 10px !important;
447   .leaflet-control {
448     margin-right: 0px !important;
449     margin-top: 0px !important;
450   }
451 }
452
453 .leaflet-popup-scrolled {
454   padding-right: $lineheight;
455   border-bottom: 0px !important;
456   border-top: 0px !important;
457 }
458
459 .leaflet-popup-content-wrapper, .leaflet-popup-tip,
460 .leaflet-contextmenu, .leaflet-contextmenu-item,
461 .leaflet-control-attribution, .leaflet-control-scale-line {
462   @extend .bg-body, .text-body;
463 }
464
465 .leaflet-control-attribution, .leaflet-control-scale-line {
466   @extend .bg-opacity-75;
467   text-shadow: none !important;
468 }
469
470 .leaflet-contextmenu-item.over {
471   @extend .bg-body-secondary, .border-secondary, .border-opacity-10;
472 }
473
474 .leaflet-popup-content-wrapper {
475   @extend .rounded-1;
476
477   a {
478     color: var(--bs-link-color) !important;
479   }
480 }
481
482 @include color-mode(dark) {
483   .leaflet-container .leaflet-control-attribution a {
484     color: var(--bs-link-color);
485   }
486
487   .leaflet-control-scale-line {
488     border-color: rgba(var(--bs-light-rgb), .75) !important;
489   }
490 }
491
492 @mixin dark-map-color-scheme {
493   .leaflet-tile-container,
494   #legend .filtered-image {
495     filter: var(--dark-mode-map-filter);
496   }
497
498   .leaflet-tile-container .leaflet-tile {
499     filter: none;
500   }
501 }
502
503 body[data-map-theme="dark"] {
504   @include dark-map-color-scheme;
505 }
506
507 @include color-mode(dark) {
508   body:not([data-map-theme]) {
509     @include dark-map-color-scheme;
510   }
511 }
512
513 /* Rules for attribution text under the main map shown on printouts */
514
515 .donate-attr { color: darken($green, 10%) !important; }
516
517 /* Temporary label size override until we remove site-wide font customisation */
518
519 form {
520   label {
521     font-size: 16px;
522   }
523   .col-form-label {
524     font-size: 16px;
525   }
526 }
527
528 /* Stop bootstrap 5 from floating legends when they don't need to be */
529 legend {
530   float: none;
531 }
532
533 /* Override the text colour for primary and secondary buttons, to match our
534    bootstrap 4 colours. Note this has accessibility issues, which is why
535    bootstrap 5 calculates black as the appropriate colour, and we should
536    reconsider our colours at some point with that in mind. */
537
538 .btn-primary {
539   @include button-variant($primary, $primary, $color: $white, $hover-color: $white, $active-color: $white, $disabled-color: $white);
540 }
541
542 .btn-secondary {
543   @include button-variant($secondary, $secondary, $color: $white, $hover-color: $white, $active-color: $white, $disabled-color: $white);
544 }
545
546 .btn-outline-secondary {
547   @include button-outline-variant($secondary, $color-hover: $white, $active-color: $white);
548 }
549
550 /* Rules for the search and direction forms */
551
552 header .search_forms,
553 .directions_form {
554   display: none;
555 }
556
557 .search_form {
558   .describe_location {
559     font-size: 10px;
560   }
561
562   input:not(:placeholder-shown) + .input-group-text .describe_location {
563     display: none;
564   } 
565 }
566
567 /* Rules for routing */
568
569 td.distance {
570     font-size: x-small;
571 }
572 tr.turn {
573     cursor: pointer;
574 }
575
576 .routing_marker_column {
577   margin-left: .35rem;
578   margin-right: .35rem;
579   width: 15px;
580
581   img {
582     cursor: move;
583   }
584 }
585
586 /* Rules for the history sidebar */
587
588 .changeset-above-sidebar-viewport {
589   --changeset-border-color: #CC6655;
590   --changeset-fill-color: #DDBBBB;
591   --changeset-outline-color: #FFF4F4;
592 }
593 .changeset-in-sidebar-viewport {
594   --changeset-border-color: #FF9500;
595   --changeset-fill-color: #FFFFAF;
596   --changeset-outline-color: #FFFFFF;
597   &.changeset-highlight-outline {
598     filter: drop-shadow(0px 0px 2px rgba(0, 0, 0, .75));
599   }
600 }
601 .changeset-below-sidebar-viewport {
602   --changeset-border-color: #8888AA;
603   --changeset-fill-color: #CCCCDD;
604   --changeset-outline-color: #F4F4FF;
605 }
606 .changeset-highlight-outline {
607   filter: drop-shadow(0px 0px 2px rgba(0, 0, 0, .25));
608 }
609
610 #sidebar .changesets {
611   .changeset-color-hint-bar {
612     height: 2px;
613     background: var(--changeset-border-color);
614   }
615
616   li {
617     &.selected {
618       @extend :hover;
619     }
620
621     a.stretched-link > bdi, a:not(.stretched-link), [title] {
622       position: relative;
623       z-index: 2; /* needs to be higher than Bootstrap's stretched link ::after z-index */
624     }
625   }
626 }
627
628 #sidebar .changeset_line .changeset_num_comments {
629   min-width: 2.5em;
630 }
631
632 /* Rules for the browse sidebar */
633
634 #sidebar_content {
635   .browse-tag-list {
636     table-layout: fixed;
637
638     tr > *:not([colspan]) {
639       white-space: pre-wrap;
640       word-wrap: break-word;
641       word-break: break-word;
642     }
643
644     tr:last-child > * {
645       border-bottom: 0;
646     }
647   }
648
649   .browse-element-list {
650     line-height: 1.25rem;
651
652     .browse-icon {
653       height: 1.25rem;
654     }
655
656     .d-flex > .browse-icon {
657       height: max(20px, 1.25rem);
658     }
659   }
660
661   .query-results {
662     display: none;
663   }
664 }
665
666 @include color-mode(dark) {
667   #sidebar_content .browse-element-list .browse-icon-invertible {
668     filter: invert(.8) hue-rotate(180deg);
669   }
670 }
671
672 /* Force LTR/RTL alignment for placeholder text */
673
674 .form-control::placeholder {
675   text-align: left;
676 }
677
678 /* Rules for export sidebar */
679
680 .export_form {
681   .export_area_inputs {
682     input[type="text"] {
683       width: 100px;
684     }
685   }
686
687   .export_boxy {
688     > * {
689         margin: -1px;
690     }
691   }
692 }
693
694 /* Rules for edit pages */
695
696 .site-edit {
697   #content {
698     position: absolute;
699     top: $headerHeight;
700     bottom: 0;
701     width: 100%;
702   }
703 }
704
705 /* Rules for non-map content pages */
706
707 .content-inner {
708   max-width: 960px;
709   padding: $lineheight;
710 }
711
712 /* Rules for login and signup pages */
713
714 .sessions-new, .users-new, .users-create {
715   #content .content-inner {
716     max-width: 760px;
717   }
718 }
719
720 .header-illustration {
721   background-position: right;
722   background-repeat: no-repeat;
723   position: relative;
724   min-height: 200px;
725   width: 100%;
726   left: 0;
727   bottom: 0;
728
729   &.new-user-main {
730     background-image: image-url("sign-up-illustration.svg");
731     background-position-x: 70px;
732   }
733
734   &.confirm-main {
735     background-image: image-url("confirm-illustration.svg");
736   }
737
738   &.new-user-terms {
739     background-image: image-url("terms-illustration.svg");
740   }
741 }
742
743 [dir=rtl] .header-illustration {
744   transform: scaleX(-1);
745
746   h1 {
747     transform: scaleX(-1);
748   }
749
750   ul {
751     transform: scaleX(-1);
752   }
753 }
754
755 /* Rules for small maps in content areas */
756
757 .content_map {
758   height: 200px;
759   margin-bottom: $lineheight;
760 }
761
762 @include media-breakpoint-up(md) {
763   .content_map {
764     height: 400px;
765   }
766 }
767
768 /* Rules for the user map */
769
770 .content_map .leaflet-popup-content {
771   margin: $spacer;
772 }
773
774 /* Rules for user popups on maps */
775
776 .user_popup {
777   p {
778     margin: 0 0 5px 0 !important;
779     font-size: 12px;
780   }
781 }
782
783 /* Rules for the diary entry page */
784
785 .diary_entries {
786   #map {
787     height: 400px;
788     display: none;
789   }
790   .diary-comment .col-auto {
791     width: 62px;
792   }
793   .diary-comment .col {
794     max-width: 690px;
795   }
796 }
797
798 /* Rules for the issues page */
799
800 .issues.issues-index {
801   td.reporting_users {
802     max-width: 5rem;
803   }
804 }
805
806 /* Rules for the account confirmation page */
807
808 .accounts-terms-show {
809   .legale {
810     padding: $lineheight;
811     margin-bottom: $lineheight;
812     overflow: auto;
813     height: 20em;
814
815     li {
816       list-style: inherit;
817     }
818
819     ol ol {
820       list-style-type: lower-alpha;
821     }
822   }
823 }
824
825 /* Rules for user images */
826
827 img.user_image {
828   max-width: 100px;
829   max-height: 100px;
830 }
831
832 img.user_thumbnail {
833   max-width: 50px;
834   max-height: 50px;
835 }
836
837 img.user_thumbnail_tiny {
838   width: 25px;
839   height: 25px;
840   object-fit: contain;
841 }
842
843 /* General styles for action lists / subnavs */
844
845 nav.secondary-actions {
846   margin-left: -11px;
847   overflow: hidden;
848   > ul {
849     display: flex;
850     flex-direction: row;
851     flex-wrap: wrap;
852     margin-bottom: 0;
853     margin-left: -1px;
854     padding: 0;
855     > li {
856       flex-basis: auto;
857       list-style: none;
858       border-left: 1px solid $grey;
859       padding-left: $lineheight * 0.5;
860       margin-right: $lineheight * 0.5;
861       margin-bottom: $lineheight * 0.125;
862     }
863   }
864 }
865
866 div.secondary-actions {
867   padding: 10px;
868   text-align: center;
869 }
870
871 /* Rules for rich text */
872
873 .richtext {
874   code {
875     background: var(--bs-secondary-bg);
876     padding: 2px 3px;
877   }
878
879   pre {
880     background: var(--bs-secondary-bg);
881     padding: 2px 3px;
882     white-space: pre-wrap;
883
884     code {
885       padding: 0;
886     }
887   }
888
889   img {
890     padding: $lineheight;
891     background-color: var(--bs-tertiary-bg);
892     display: block;
893     max-width: 100%;
894     margin: auto;
895   }
896
897   blockquote {
898     border-left: $lineheight solid var(--bs-tertiary-bg);
899     padding-left: $lineheight;
900     margin: 0;
901     color: var(--bs-secondary-color);
902   }
903 }
904
905 /* Rules for the "About" page */
906
907 .site-about #content {
908   .content-inner {
909     max-width: 760px;
910   }
911
912   .attr {
913     margin-top: -20px;
914
915     h1 {
916       span {
917         color: $vibrant-green;
918       }
919     }
920
921     .user-image {
922       height: 150px;
923       background-position: 0 50%;
924       background-repeat: no-repeat;
925       background-image: image-url('about/osm.png');
926       background-size: cover;
927       background-color: $vibrant-green;
928     }
929
930     .byosm {
931       background: $vibrant-green;
932     }
933
934     .byosm span {
935       display: inline-block;
936       width: 1em;
937       margin-left: -1em;
938     }
939   }
940 }
941
942 /* Rules for tables with usernames */
943
944 .messages-table .username,
945 #block_list .username {
946   max-width: 20em;
947 }
948
949 /* Rules for navigation tabs */
950
951 .nav-tabs .username {
952   max-width: 20em;
953 }
954
955 .bg-body-secondary .nav-tabs {
956   --bs-border-color: var(--bs-secondary-border-subtle);
957   --bs-secondary-bg: var(--bs-secondary-border-subtle);
958   margin-bottom: -1px;
959 }
960
961 /* Rules for traces */
962
963 img.trace_image {
964   mix-blend-mode: darken;
965 }
966
967 @include color-mode(dark) {
968   img.trace_image {
969     filter: invert(1);
970     mix-blend-mode: lighten;
971   }
972 }
973
974 /* Rules for the heatmap */
975
976 .heatmap {
977   grid-template-columns: auto;
978   grid-auto-columns: minmax(1em, 1fr);
979   grid-template-rows: auto;
980   grid-auto-rows: minmax(1em, 1fr);
981   font-size: x-small;
982   gap: 0.3em;
983
984   [data-date], [data-date] span {
985     display: block;
986     aspect-ratio: 1;
987     border-radius: 25%;
988   }
989
990   [data-date] {
991     background-color: #ededed;
992     span {
993       background-color: #14432a;
994     }
995     &[data-count] {
996       background-color: #4dd05a;
997     }
998     &:hover {
999       box-shadow: 0px 0px 0px 1px #8884;
1000     }
1001   }
1002 }
1003
1004 @include color-mode(dark) {
1005   .heatmap {
1006     [data-date] {
1007       background-color: #2d333b;
1008       span {
1009         background-color: #4dd05a;
1010       }
1011       &[data-count] {
1012         background-color: #14432a;
1013       }
1014     }
1015   }
1016 }
1017
1018 .tooltip.wide {
1019   --bs-tooltip-max-width: none;
1020 }