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