_Weather.scss (18941B)
1 // Custom font sizing for weather widget 2 :root { 3 --newtab-weather-content-font-size: var(--font-size-small); 4 --newtab-weather-sponsor-font-size: 8px; 5 } 6 7 .weather { 8 font-size: inherit; 9 display: inline-block; 10 margin-inline-start: 0; 11 position: absolute; 12 inset-inline-end: var(--space-xxlarge); 13 inset-block-start: var(--space-xxlarge); 14 margin-block-start: 0; 15 z-index: 1; 16 17 @media (min-width: $break-point-layout-variant) { 18 inset-inline-end: var(--space-large); 19 } 20 21 @media (min-width: $break-point-large) { 22 inset-inline-end: var(--space-xxlarge); 23 } 24 25 // Variant with the weather in the header of a section 26 &.section-weather { 27 position: initial; 28 margin-inline-start: var(--space-medium); 29 30 .weatherInfoLink { 31 max-width: unset; 32 } 33 } 34 35 // Edge case: users with weather enabled/search disabled 36 .no-search & { 37 position: absolute; 38 inset-block-start: var(--space-xxlarge); 39 margin-block-start: 0; 40 margin-inline-start: 0; 41 inset-inline-end: var(--space-large); 42 43 @media (min-width: $break-point-small) { 44 inset-inline-end: var(--space-xxlarge); 45 } 46 47 @media (min-width: $break-point-layout-variant) { 48 inset-inline-end: var(--space-large); 49 } 50 51 @media (min-width: $break-point-large) { 52 inset-inline-end: var(--space-xxlarge); 53 } 54 } 55 56 .context-menu { 57 inset-inline-end: 100%; 58 inset-inline-start: auto; 59 margin-inline-end: var(--space-xsmall); 60 } 61 62 } 63 64 .weather-placeholder { 65 width: 240px; 66 height: 98px; 67 padding: var(--space-small) var(--space-medium); 68 border-radius: var(--border-radius-medium); 69 background: var(--newtab-background-color-secondary); 70 display: flex; 71 overflow: hidden; 72 73 .placeholder-image { 74 height: 100%; 75 width: 80px; 76 margin-inline-end: var(--space-medium); 77 flex-shrink: 0; 78 } 79 80 .placeholder-context { 81 width: 100%; 82 display: flex; 83 flex-direction: column; 84 } 85 86 .placeholder-header { 87 height: 45px; 88 width: 100%; 89 margin-block-end: var(--space-small); 90 } 91 92 .placeholder-description { 93 flex-grow: 1; 94 width: 100%; 95 } 96 97 .placeholder-fill { 98 color: var(--newtab-text-primary-color); 99 background: var(--newtab-button-active-background); 100 border-radius: var(--border-radius-small); 101 } 102 103 &.placeholder-seen { 104 &::before { 105 content: ''; 106 display: block; 107 position: absolute; 108 inset-block-start: 0; 109 inset-inline-start: -100%; 110 height: 100%; 111 width: 100%; 112 background: linear-gradient(90deg, rgba(255, 255, 255, 0%) 0%, var(--newtab-background-color-secondary) 50%, rgba(255, 255, 255, 0%) 100%); 113 z-index: 2; 114 115 @media (prefers-reduced-motion: no-preference) { 116 animation: loading 1.5s infinite; 117 } 118 } 119 120 @keyframes loading { 121 0% { 122 inset-inline-start: -100%; 123 } 124 125 // We apply the same frame from 50-100% to account for a delay in a repeating animation. 126 50%, 100% { 127 inset-inline-start: 100%; 128 } 129 } 130 } 131 } 132 133 // Bug 1959189 - Show mobile QR code modal toggle next to weather widget 134 .has-mobile-download-promo { 135 --mobile-download-promo-width: var(--space-xxlarge); 136 137 .weather { 138 @media (min-width: $break-point-medium) { 139 inset-inline-end: calc(var(--mobile-download-promo-width) + var(--space-medium)); 140 } 141 142 @media (min-width: $break-point-layout-variant) { 143 inset-inline-end: calc(var(--space-xxlarge) + var(--mobile-download-promo-width) + var(--space-medium)); 144 } 145 } 146 147 // Layout when search has been turned off. It will show one breakpoint later than `has-search` 148 &.no-search .weather { 149 @media (min-width: $break-point-large) { 150 inset-inline-end: calc(var(--space-xxlarge) + var(--mobile-download-promo-width) + var(--space-medium)); 151 } 152 } 153 } 154 155 // Edge case: users with weather enabled/search enabled 156 .has-weather.has-search { 157 // Edge case: medium screens where we hide the weather icon and 158 // detail info row for overlap issues 159 .weatherDetailedSummaryRow { 160 display: block; 161 162 @media (min-width: $break-point-medium) { 163 display: none; 164 } 165 166 @media (min-width: $break-point-large) { 167 display: block; 168 } 169 } 170 171 .weatherIconCol { 172 display: flex; 173 174 @media (min-width: $break-point-medium) { 175 display: none; 176 } 177 178 @media (min-width: $break-point-large) { 179 display: flex; 180 } 181 } 182 } 183 184 // Unavailable / Error State 185 .weatherNotAvailable { 186 font-size: var(--newtab-weather-content-font-size); 187 align-items: center; 188 border-radius: var(--border-radius-medium); 189 height: 52px; 190 max-width: 205px; 191 display: none; 192 193 @media (min-width: $break-point-large) { 194 display: flex 195 } 196 197 &:hover { 198 background-color: var(--button-background-color-ghost-hover); 199 } 200 201 &:active { 202 background-color: var(--button-background-color-ghost-active); 203 } 204 205 .icon { 206 margin-inline-start: var(--space-small); 207 min-width: var(--size-item-small); 208 } 209 210 p { 211 margin-inline-start: var(--space-small); 212 } 213 214 .weatherButtonContextMenuWrapper { 215 align-self: stretch; 216 padding-inline: var(--space-small); 217 } 218 219 // Bug 1908010 - This overwrites the design system color because of a 220 // known transparency issue with color-mix syntax when a wallpaper is set 221 .lightWallpaper &, 222 .darkWallpaper & { 223 background-color: var(--newtab-weather-background-color); 224 225 @media (prefers-contrast) { 226 background-color: var(--background-color-box); 227 } 228 } 229 } 230 231 .weatherCard { 232 margin-block-end: var(--space-xsmall); 233 display: flex; 234 flex-wrap: nowrap; 235 align-items: stretch; 236 border-radius: var(--border-radius-medium); 237 238 &:hover, &:focus-within { 239 ~ .weatherSponsorText { 240 visibility: visible; 241 } 242 } 243 244 &:has(.staticWeatherInfo) { 245 &:hover { 246 box-shadow: none; 247 248 ~ .weatherSponsorText { 249 visibility: hidden; 250 } 251 } 252 } 253 254 &:hover { 255 box-shadow: var(--box-shadow-card); 256 } 257 258 a { 259 color: var(--text-color); 260 } 261 262 } 263 264 .weatherSponsorText { 265 visibility: hidden; 266 font-size: var(--newtab-weather-sponsor-font-size); 267 color: var(--newtab-contextual-text-primary-color); 268 float: inline-end; 269 270 // Contrast fix for users who have wallpapers set 271 @include wallpaper-contrast-fix; 272 273 span { 274 color: var(--text-color-deemphasized); 275 inset-inline-end: 0; 276 } 277 } 278 279 .weatherOptIn { 280 position: absolute; 281 inset-block-end: calc(var(--space-medium) * -1.5); 282 inset-inline-start: calc(var(--space-xxlarge) * -9); 283 284 dialog { 285 background: var(--newtab-background-color-secondary); 286 border: 1px solid var(--border-color-card); 287 border-radius: var(--border-radius-medium); 288 box-shadow: var(--box-shadow-card); 289 display: flex; 290 width: 332px; 291 292 .weatherOptInImg { 293 -webkit-mask: url('chrome://browser/skin/weather/mostly-sunny.svg') no-repeat center; 294 mask: url('chrome://browser/skin/weather/mostly-sunny.svg') no-repeat center; 295 background-color: var(--button-icon-fill); 296 mask-size: cover; 297 margin-inline-end: var(--space-medium); 298 height: var(--icon-size-xlarge); 299 width: var(--icon-size-xlarge); 300 } 301 302 &:focus-visible { 303 outline: var(--focus-outline); 304 305 &::after { 306 border-block-end: var(--focus-outline); 307 border-inline-end: var(--focus-outline); 308 } 309 } 310 } 311 312 dialog .weatherOptInContent { 313 display: flex; 314 flex-direction: column; 315 justify-content: space-between; 316 317 h3 { 318 font-size: var(--button-font-size); 319 font-weight: var(--heading-font-weight); 320 margin-block: 0 var(--space-medium); 321 } 322 323 moz-button-group { 324 align-self: flex-end; 325 326 moz-button:first-of-type { 327 margin-inline-end: var(--space-small); 328 } 329 } 330 } 331 332 @media (min-width: $break-point-large) { 333 inset-block-end: calc(var(--space-medium) * -1); 334 inset-inline-start: calc(var(--space-xxlarge) * -5.5); 335 } 336 } 337 338 // Arrow pointed upwards from the right side of the dialog 339 dialog { 340 &::after { 341 content: ''; 342 position: absolute; 343 inset-block-start: -9%; 344 inset-inline-end: 5%; 345 transform: translateX(-50%) rotate(225deg); 346 height: 16px; 347 width: 16px; 348 background: var(--newtab-background-color-secondary); 349 box-shadow: 4px 4px 6px -2px var(--box-shadow-card); 350 border-inline-end: 1px solid var(--border-color-card); 351 border-block-end: 1px solid var(--border-color-card); 352 } 353 354 &:dir(rtl)::after { 355 border-inline-start: 1px solid var(--border-color-card); 356 border-block-end: 1px solid var(--border-color-card); 357 border-inline-end: none; 358 inset-inline-end: 10%; 359 } 360 361 } 362 363 .weatherInfoLink, .weatherButtonContextMenuWrapper { 364 appearance: none; 365 background-color: var(--background-color-ghost); 366 border: 0; 367 padding: var(--space-small); 368 cursor: pointer; 369 370 &:hover { 371 background-color: var(--newtab-background-color-secondary); 372 373 &::after { 374 background-color: transparent 375 } 376 377 &:active { 378 background-color: var(--button-background-color-ghost-active); 379 } 380 } 381 382 // Bug 1908010 - This overwrites the design system color because of a 383 // known transparency issue with color-mix syntax when a wallpaper is set 384 .lightWallpaper &, 385 .darkWallpaper & { 386 background-color: var(--newtab-weather-background-color); 387 388 &:hover { 389 background-color: var(--newtab-button-static-hover-background); 390 } 391 392 &:hover:active { 393 background-color: var(--newtab-button-static-active-background); 394 } 395 396 @media (prefers-contrast) { 397 background-color: var(--background-color-box); 398 } 399 } 400 } 401 402 .weatherInfoLink { 403 display: flex; 404 gap: var(--space-medium); 405 padding: var(--space-small) var(--space-medium); 406 border-start-start-radius: var(--border-radius-medium); 407 border-start-end-radius: 0; 408 border-end-end-radius: 0; 409 border-end-start-radius: var(--border-radius-medium); 410 text-decoration: none; 411 color: var(--text-color); 412 min-width: 130px; 413 max-width: 190px; 414 text-overflow: ellipsis; 415 416 @media(min-width: $break-point-medium) { 417 min-width: unset; 418 } 419 420 &:hover ~.weatherButtonContextMenuWrapper { 421 &::after { 422 background-color: transparent 423 } 424 } 425 426 &:focus-visible { 427 border-radius: var(--border-radius-medium); 428 outline: var(--focus-outline); 429 z-index: 1; 430 431 ~ .weatherButtonContextMenuWrapper { 432 &::after { 433 background-color: transparent 434 } 435 } 436 } 437 } 438 439 .weatherInfoLink.staticWeatherInfo { 440 .weatherIcon { 441 filter: opacity(60%); 442 } 443 444 .weatherText { 445 color: var(--text-color-disabled) 446 } 447 448 &:hover, 449 &:active { 450 box-shadow: none; 451 cursor: default; 452 background-color: var(--newtab-weather-background-color); 453 } 454 } 455 456 .weatherButtonContextMenuWrapper { 457 position: relative; 458 cursor: pointer; 459 border-start-start-radius: 0; 460 border-start-end-radius: var(--border-radius-medium); 461 border-end-end-radius: var(--border-radius-medium); 462 border-end-start-radius: 0; 463 display: flex; 464 align-items: stretch; 465 width: 50px; 466 padding: 0; 467 468 &::after { 469 content: ''; 470 inset-inline-start: 0; 471 inset-block-start: var(--space-small); 472 height: calc(100% - 20px); 473 width: 1px; 474 background-color: var(--newtab-button-static-background); 475 display: block; 476 position: absolute; 477 z-index: 0; 478 } 479 480 &:hover { 481 &::after { 482 background-color: transparent 483 } 484 } 485 486 &:has(:focus-visible) { 487 border-radius: var(--border-radius-medium); 488 outline: var(--focus-outline); 489 490 &::after { 491 background-color: transparent 492 } 493 } 494 } 495 496 .weatherButtonContextMenu { 497 background-image: url('chrome://global/skin/icons/more.svg'); 498 background-repeat: no-repeat; 499 background-size: var(--size-item-small) auto; 500 background-position: center; 501 background-color: transparent; 502 cursor: pointer; 503 fill: var(--icon-color); 504 -moz-context-properties: fill; 505 width: 100%; 506 height: 100%; 507 border: 0; 508 appearance: none; 509 min-width: var(--size-item-large); 510 511 &:focus { 512 outline: none; 513 } 514 } 515 516 .weatherText { 517 height: min-content; 518 } 519 520 .weatherCityRow, .weatherForecastRow, .weatherDetailedSummaryRow { 521 display: flex; 522 justify-content: space-between; 523 align-items: center; 524 gap: var(--space-small); 525 } 526 527 .weatherForecastRow { 528 text-transform: uppercase; 529 font-weight: var(--font-weight-semibold); 530 } 531 532 .weatherCityRow { 533 color: var(--text-color-deemphasized); 534 } 535 536 .weatherCity { 537 -webkit-line-clamp: 1; 538 text-overflow: ellipsis; 539 overflow: hidden; 540 word-break: break-word; 541 font-size: var(--font-size-small); 542 } 543 544 // Add additional margin if detailed summary is in view 545 .weatherCityRow + .weatherDetailedSummaryRow { 546 margin-block-start: var(--space-xsmall); 547 } 548 549 .weatherDetailedSummaryRow { 550 font-size: var(--newtab-weather-content-font-size); 551 gap: var(--space-large); 552 } 553 554 .weatherHighLowTemps { 555 display: inline-flex; 556 gap: var(--space-xxsmall); 557 text-transform: uppercase; 558 word-spacing: var(--space-xxsmall); 559 margin-inline-end: var(--space-small); 560 } 561 562 .weatherTextSummary { 563 display: inline; 564 text-align: center; 565 max-width: 90px; 566 } 567 568 .weatherTemperature { 569 font-size: var(--font-size-large); 570 } 571 572 573 // Weather Symbol Icons 574 .weatherIconCol { 575 width: var(--size-item-large); 576 height: var(--size-item-large); 577 aspect-ratio: 1; 578 display: flex; 579 align-items: center; 580 justify-content: center; 581 align-self: center; 582 } 583 584 .weatherIcon { 585 width: var(--size-item-large); 586 height: auto; 587 vertical-align: middle; 588 589 @media (prefers-contrast) { 590 -moz-context-properties: fill, stroke; 591 fill: currentColor; 592 stroke: currentColor; 593 } 594 595 &.iconId1 { 596 content: url('chrome://browser/skin/weather/sunny.svg'); 597 } 598 599 &.iconId2 { 600 content: url('chrome://browser/skin/weather/mostly-sunny.svg'); 601 } 602 603 &:is(.iconId3, .iconId4, .iconId6) { 604 content: url('chrome://browser/skin/weather/partly-sunny.svg'); 605 } 606 607 &.iconId5 { 608 content: url('chrome://browser/skin/weather/hazy-sunshine.svg'); 609 } 610 611 &:is(.iconId7, .iconId8) { 612 content: url('chrome://browser/skin/weather/cloudy.svg'); 613 } 614 615 &.iconId11 { 616 content: url('chrome://browser/skin/weather/fog.svg'); 617 } 618 619 &.iconId12 { 620 content: url('chrome://browser/skin/weather/showers.svg'); 621 } 622 623 &:is(.iconId13, .iconId14) { 624 content: url('chrome://browser/skin/weather/mostly-cloudy-with-showers.svg'); 625 } 626 627 &.iconId15 { 628 content: url('chrome://browser/skin/weather/thunderstorms.svg'); 629 } 630 631 &:is(.iconId16, .iconId17) { 632 content: url('chrome://browser/skin/weather/mostly-cloudy-with-thunderstorms.svg'); 633 } 634 635 &.iconId18 { 636 content: url('chrome://browser/skin/weather/rain.svg'); 637 } 638 639 &:is(.iconId19, .iconId20, .iconId25) { 640 content: url('chrome://browser/skin/weather/flurries.svg'); 641 } 642 643 &.iconId21 { 644 content: url('chrome://browser/skin/weather/partly-sunny-with-flurries.svg'); 645 } 646 647 &:is(.iconId22, .iconId23) { 648 content: url('chrome://browser/skin/weather/snow.svg'); 649 } 650 651 &:is(.iconId24, .iconId31) { 652 content: url('chrome://browser/skin/weather/ice.svg'); 653 } 654 655 &:is(.iconId26, .iconId29) { 656 content: url('chrome://browser/skin/weather/freezing-rain.svg'); 657 } 658 659 &.iconId30 { 660 content: url('chrome://browser/skin/weather/hot.svg'); 661 } 662 663 &.iconId32 { 664 content: url('chrome://browser/skin/weather/windy.svg'); 665 } 666 667 &.iconId33 { 668 content: url('chrome://browser/skin/weather/night-clear.svg'); 669 } 670 671 &:is(.iconId34, .iconId35, .iconId36, .iconId38) { 672 content: url('chrome://browser/skin/weather/night-mostly-clear.svg'); 673 } 674 675 &.iconId37 { 676 content: url('chrome://browser/skin/weather/night-hazy-moonlight.svg'); 677 } 678 679 &:is(.iconId39, .iconId40) { 680 content: url('chrome://browser/skin/weather/night-partly-cloudy-with-showers.svg'); 681 height: var(--size-item-large); 682 } 683 684 &:is(.iconId41, .iconId42) { 685 content: url('chrome://browser/skin/weather/night-partly-cloudy-with-thunderstorms.svg'); 686 } 687 688 &:is(.iconId43, .iconId44) { 689 content: url('chrome://browser/skin/weather/night-mostly-cloudy-with-flurries.svg'); 690 } 691 } 692 693 .location-input-wrapper { 694 background-color: light-dark(var(--color-white), var(--newtab-background-color-secondary)); 695 color: var(--newtab-text-primary-color); 696 border-radius: var(--border-radius-medium); 697 padding: var(--space-small); 698 position: relative; 699 700 // Bug 1908010 - This overwrites the design system color because of a 701 // known transparency issue with color-mix syntax when a wallpaper is set 702 .lightWallpaper &, 703 .darkWallpaper & { 704 background-color: var(--newtab-weather-background-color); 705 706 &:hover { 707 background-color: var(--newtab-button-static-hover-background); 708 } 709 710 &:hover:active { 711 background-color: var(--newtab-button-static-active-background); 712 } 713 714 @media (prefers-contrast) { 715 background-color: var(--background-color-box); 716 } 717 } 718 719 .search-icon { 720 content: url('chrome://global/skin/icons/search-glass.svg'); 721 -moz-context-properties: fill; 722 fill: var(--icon-color); 723 position: absolute; 724 inset-block-start: 50%; 725 transform: translateY(-50%); 726 inset-inline-start: var(--space-large); 727 } 728 729 .close-icon { 730 position: absolute; 731 inset-block-start: 50%; 732 transform: translateY(-50%); 733 inset-inline-end: var(--space-medium); 734 735 &:focus-visible { 736 outline: var(--focus-outline); 737 } 738 } 739 740 input { 741 border-radius: var(--border-radius-medium); 742 background-color: light-dark(var(--color-white), var(--newtab-background-color-secondary)); 743 padding: var(--space-small) var(--space-xxlarge); 744 border: 1px solid var(--border-color); 745 746 &:focus-visible { 747 outline: var(--focus-outline); 748 } 749 } 750 } 751 752 // Bug 1914193 - Only show the temperature on the smallest breakpoint and 753 // return to default view on medium breakpoints 754 .has-weather.has-search, 755 .has-weather { 756 .weatherCityRow, 757 .weatherButtonContextMenuWrapper { 758 display: none; 759 760 @media(min-width: $break-point-large) { 761 display: flex; 762 } 763 } 764 765 // Edge case: Show weather icon at a later breakpoint 766 // then the temperature and city name 767 .weatherIconCol { 768 display: none; 769 770 @media(min-width: $break-point-widest) { 771 display: flex; 772 } 773 } 774 775 // Edge case: Show detailed view at a later breakpoint 776 // then the temperature and city name 777 .weatherDetailedSummaryRow { 778 display: none; 779 780 @media(min-width: $break-point-widest) { 781 display: block; 782 } 783 } 784 785 .weatherCard { 786 min-height: 55px; 787 } 788 789 .weatherInfoLink { 790 min-width: auto; 791 max-width: none; 792 793 @media(min-width: $break-point-widest) { 794 min-width: 130px; 795 max-width: 190px; 796 } 797 } 798 799 .weatherForecastRow { 800 margin-block: var(--space-small); 801 802 @media(min-width: $break-point-large) { 803 margin-block: unset; 804 } 805 } 806 807 .weatherSponsorText { 808 position: relative; 809 810 span { 811 position: absolute; 812 white-space: nowrap; 813 inset-block-start: var(--space-small); 814 815 @media(min-width: $break-point-large) { 816 inset-block-start: unset; 817 position: relative; 818 } 819 } 820 } 821 }