_DSCard.scss (16499B)
1 // Type sizes 2 /* stylelint-disable-next-line stylelint-plugin-mozilla/no-non-semantic-token-usage */ 3 $header-font-size: var(--font-size-large); 4 $header-line-height: normal; 5 /* stylelint-disable-next-line stylelint-plugin-mozilla/no-non-semantic-token-usage */ 6 $excerpt-font-size: var(--font-size-small); 7 $excerpt-line-height: normal; 8 $ds-card-image-gradient-fade: rgba(0, 0, 0, 0%); 9 $ds-card-image-gradient-solid: rgba(0, 0, 0, 100%); 10 11 .ds-card { 12 display: flex; 13 flex-direction: column; 14 position: relative; 15 // Bug 1914571: Reset the z-index threshold for topic labels 16 z-index: auto; 17 18 &.placeholder { 19 display: flex; 20 flex-direction: column; 21 gap: var(--space-small); 22 box-shadow: 0 2px 6px rgba(0, 0, 0, 15%); 23 border-radius: var(--border-radius-medium); 24 position: relative; 25 overflow: hidden; 26 27 .placeholder-fill { 28 background: var(--newtab-button-active-background); 29 border-radius: var(--border-radius-small); 30 } 31 32 .placeholder-image { 33 width: 100%; 34 height: 140px; 35 border-radius: var(--border-radius-medium) var(--border-radius-medium) 0 0; 36 } 37 38 .placeholder-label { 39 width: 40%; 40 height: var(--size-item-small); 41 margin-block-end: var(--space-small); 42 margin-inline: var(--space-large); 43 } 44 45 .placeholder-header { 46 width: 80%; 47 height: 20px; 48 margin-inline: var(--space-large); 49 } 50 51 .placeholder-description { 52 height: 60px; 53 margin-inline: var(--space-large); 54 margin-block-end: var(--space-large); 55 } 56 57 &.refined-cards { 58 .placeholder-image { 59 height: 150px; 60 } 61 62 .placeholder-description { 63 margin-block-end: var(--space-small); 64 } 65 66 .placeholder-header { 67 width: initial; 68 margin-block-end: var(--space-large); 69 } 70 } 71 } 72 73 &.placeholder-seen { 74 &::before { 75 content: ''; 76 display: block; 77 position: absolute; 78 inset-block-start: 0; 79 inset-inline-start: -100%; 80 height: 100%; 81 width: 100%; 82 background: linear-gradient( 83 90deg, 84 rgba(255, 255, 255, 0%) 0%, 85 var(--newtab-background-color-secondary) 50%, 86 rgba(255, 255, 255, 0%) 100% 87 ); 88 z-index: 2; 89 90 @media (prefers-reduced-motion: no-preference) { 91 animation: loading 1.5s infinite; 92 } 93 } 94 95 @keyframes loading { 96 0% { 97 inset-inline-start: -100%; 98 } 99 100 // We apply the same frame from 50-100% to account for a delay in a repeating animation. 101 50%, 102 100% { 103 inset-inline-start: 100%; 104 } 105 } 106 } 107 108 .img-wrapper { 109 width: 100%; 110 position: relative; 111 } 112 113 .card-stp-button-hover-background { 114 opacity: 0; 115 width: 100%; 116 position: absolute; 117 inset-block-start: 0; 118 transition: opacity; 119 transition-duration: 0s; 120 padding-block-start: 50%; 121 pointer-events: none; 122 background: $black-40; 123 border-radius: var(--border-radius-medium) var(--border-radius-medium) 0 0; 124 125 .card-stp-button-position-wrapper { 126 position: absolute; 127 inset-inline-end: var(--space-small); 128 inset-block-start: var(--space-small); 129 display: flex; 130 justify-content: end; 131 align-items: center; 132 } 133 134 .context-menu-position-container { 135 position: relative; 136 } 137 138 .context-menu { 139 margin-inline-start: var(--space-large); 140 inset-inline-start: auto; 141 position: absolute; 142 // Bug 1967304 - Custom number (20px) 143 inset-block-start: calc(var(--space-xsmall) + var(--space-large)); 144 } 145 146 button, 147 .context-menu { 148 pointer-events: auto; 149 } 150 151 button { 152 cursor: pointer; 153 } 154 } 155 156 // Override note: The colors set here are intentionally static 157 // due to transparency issues over images. 158 .context-menu-button { 159 position: static; 160 transition: none; 161 border-radius: var(--border-radius-small); 162 background-color: var(--newtab-button-static-background); 163 164 &:hover { 165 background-color: var(--newtab-button-static-hover-background); 166 167 &:active { 168 background-color: var(--newtab-button-static-active-background); 169 } 170 } 171 172 &:focus-visible { 173 outline: 2px solid var(--newtab-button-focus-border); 174 background-color: var(--newtab-button-static-focus-background); 175 } 176 } 177 178 &.last-item { 179 .card-stp-button-hover-background { 180 .context-menu { 181 margin-inline-start: auto; 182 margin-inline-end: var(--space-large); 183 } 184 } 185 } 186 187 // The active class is added when the context menu is open. 188 &.active, 189 &:focus-within, 190 &:hover { 191 .card-stp-button-hover-background { 192 display: block; 193 opacity: 1; 194 transition-duration: 0.3s; 195 196 .context-menu-button { 197 opacity: 1; 198 transform: scale(1); 199 } 200 } 201 202 h3 { 203 color: var(--newtab-primary-action-background); 204 } 205 } 206 207 &:active { 208 h3 { 209 color: var(--newtab-primary-element-active-color); 210 } 211 } 212 213 .img { 214 aspect-ratio: 2/1; 215 216 img { 217 border-radius: var(--border-radius-small); 218 box-shadow: $shadow-image-inset; 219 } 220 } 221 222 .ds-card-link { 223 display: flex; 224 flex-direction: column; 225 align-items: initial; 226 text-decoration: none; 227 grid-template-columns: auto 1fr; 228 gap: inherit; 229 flex-grow: 1; 230 231 &:focus { 232 @include ds-focus; 233 234 transition: none; 235 } 236 } 237 238 .ds-card-topic { 239 position: absolute; 240 z-index: 1; 241 background: light-dark(#F0F0F4, var(--newtab-background-color-secondary)); 242 border-radius: var(--border-radius-small); 243 color: var(--newtab-text-primary-color); 244 padding: var(--space-small); 245 margin: var(--space-small); 246 font-size: var(--font-size-small); 247 } 248 249 .meta { 250 display: flex; 251 justify-content: space-between; 252 flex-direction: column; 253 padding: var(--space-medium) var(--space-large); 254 flex-grow: 1; 255 256 .info-wrap { 257 flex-grow: 1; 258 } 259 260 .title { 261 // show only 3 lines of copy 262 @include limit-visible-lines(3, $header-line-height, $header-font-size); 263 264 margin-block: 0; 265 font-weight: var(--heading-font-weight); 266 } 267 268 .excerpt { 269 // show only 3 lines of copy 270 @include limit-visible-lines(3, $excerpt-line-height, $excerpt-font-size); 271 } 272 273 .source-wrapper { 274 color: var(--newtab-text-secondary-text); 275 display: flex; 276 margin-block-end: var(--space-xxsmall); 277 align-items: center; 278 279 img { 280 border-radius: var(--border-radius-small); 281 margin-inline-end: var(--space-small); 282 } 283 } 284 285 .source { 286 -webkit-line-clamp: 1; 287 font-size: var(--font-size-small); 288 color: var(--newtab-text-secondary-color); 289 290 span { 291 display: inline-block; 292 } 293 } 294 295 .new-sponsored-label { 296 font-size: var(--font-size-small); 297 margin-block-end: var(--space-xxsmall); 298 } 299 } 300 301 &.ds-card-title-lines-2 .meta .title { 302 // show only 2 lines of copy 303 @include limit-visible-lines(2, $header-line-height, $header-font-size); 304 } 305 306 &.ds-card-title-lines-1 .meta .title { 307 // show only 1 line of copy 308 @include limit-visible-lines(1, $header-line-height, $header-font-size); 309 } 310 311 &.ds-card-desc-lines-2 .meta .excerpt { 312 // show only 2 lines of copy 313 @include limit-visible-lines(2, $excerpt-line-height, $excerpt-font-size); 314 } 315 316 &.ds-card-desc-lines-1 .meta .excerpt { 317 // show only 1 line of copy 318 @include limit-visible-lines(1, $excerpt-line-height, $excerpt-font-size); 319 } 320 321 &.ds-card-compact-image .img { 322 padding-block-start: 47%; 323 } 324 325 &.ds-card-image-gradient { 326 img { 327 mask-image: linear-gradient( 328 to top, 329 $ds-card-image-gradient-fade, 330 $ds-card-image-gradient-solid 40px 331 ); 332 } 333 334 .meta { 335 padding: var(--space-xxsmall) var(--space-large) var(--space-medium); 336 } 337 } 338 339 &.ds-card-cta-button.variant-a, 340 &.ds-card-cta-button.variant-b { 341 .img { 342 padding-block-start: 52.4%; 343 } 344 345 .story-sponsored-label { 346 margin: var(--space-small) 0 0; 347 } 348 349 .source { 350 text-decoration: underline; 351 } 352 353 .story-footer { 354 display: flex; 355 flex-wrap: wrap; 356 justify-content: space-between; 357 align-items: center; 358 gap: 0 var(--space-small); 359 margin-block-start: 0; 360 } 361 362 .story-cta-button { 363 cursor: inherit; 364 background: var(--button-background-color); 365 border-radius: var(--border-radius-small); 366 border: none; 367 padding: var(--space-xsmall) var(--space-large); 368 font-size: var(--font-size-small); 369 font-weight: var(--font-weight-semibold); 370 min-height: var(--size-item-large); 371 min-width: 97px; 372 color: var(--newtab-text-primary-color); 373 margin-block-start: var(--space-small); 374 375 &:hover { 376 background: var(--button-background-color-hover); 377 } 378 } 379 380 .cta-header { 381 background: var(--button-background-color); 382 font-size: var(--font-size-root); 383 font-weight: var(--heading-font-weight); 384 text-align: end; 385 padding: var(--space-xsmall) var(--space-large); 386 color: var(--newtab-text-primary-color); 387 min-height: var(--size-item-large); 388 } 389 } 390 391 h3 { 392 font-size: $header-font-size; 393 color: var(--newtab-text-primary-color); 394 } 395 396 p { 397 font-size: $excerpt-font-size; 398 color: var(--newtab-text-primary-color); 399 margin: 0; 400 } 401 } 402 403 // Class is applied to .ds-card element 404 // See _CardSections.scss for large and small card style mixins 405 .sections-card-ui { 406 // Loading Animation 407 &.placeholder { 408 box-shadow: 0 2px 6px #15141A24; 409 border-radius: var(--border-radius-large); 410 } 411 412 .ds-card-grid & { 413 @include newtab-card-style; 414 415 &:not(.placeholder) { 416 box-shadow: 0 1px 2px 0 rgba(58, 57, 68, 20%); 417 border-radius: var(--border-radius-large); 418 419 &.active, 420 &:focus-within, 421 &:hover { 422 box-shadow: 0 2px 14px 0 var(--newtab-section-card-box-shadow-color); 423 z-index: 1; 424 } 425 426 // This is higher to keep the context menu (when open) above any other cards 427 &.active { 428 z-index: 2; 429 } 430 431 .img-wrapper > .ds-image.img > img { 432 border-radius: var(--border-radius-large) var(--border-radius-large) 0 0; 433 } 434 } 435 436 @media (forced-colors: active) { 437 &:not(.placeholder) { 438 border: var(--border-width) solid var(--border-color-card); 439 } 440 441 &:not(.placeholder):hover { 442 --newtab-background-color-secondary: SelectedItemText; 443 --newtab-text-secondary-color: SelectedItem; 444 445 color: SelectedItem; 446 border-color: var(--border-color-interactive-hover); 447 448 .meta .title { 449 color: var(--link-color-hover); 450 } 451 } 452 453 .meta .title { 454 text-decoration: underline; 455 color: var(--link-color); 456 } 457 } 458 459 .meta { 460 padding: var(--space-large); 461 462 .title { 463 // show only 3 lines of copy 464 -webkit-line-clamp: 3; 465 font-size: var(--font-size-root); 466 margin-block-end: var(--space-small); 467 font-weight: var(--heading-font-weight); 468 } 469 470 .excerpt { 471 // show only 3 lines of copy 472 -webkit-line-clamp: 3; 473 font-size: var(--font-size-small); 474 } 475 476 .source { 477 -webkit-line-clamp: 1; 478 font-size: var(--font-size-small); 479 } 480 481 // Sponsored by text 482 .story-footer { 483 justify-content: flex-start; 484 display: grid; 485 height: 28px; 486 align-content: center; 487 margin-block-start: var(--space-small); 488 } 489 490 .story-sponsored-label { 491 line-height: unset; 492 font-size: var(--font-size-small); 493 } 494 } 495 496 .sections-card-footer { 497 margin-block-start: var(--space-small); 498 position: relative; 499 min-height: 28px; 500 } 501 502 .ds-card-topic { 503 display: grid; 504 align-content: center; 505 height: 28px; 506 font-size: var(--font-size-small); 507 color: var(--newtab-text-topic-label-color); 508 margin: initial; 509 padding: initial; 510 background-color: initial; 511 } 512 513 .card-stp-button-hover-background { 514 border-radius: var(--border-radius-large) var(--border-radius-large) 0 0; 515 background-color: var(--button-background-color-ghost); 516 } 517 518 .ds-card-link:focus { 519 border-radius: var(--border-radius-large); 520 } 521 } 522 } 523 524 .ds-card-grid, 525 .ds-section-grid { 526 // Intentionally duplicated classname to increase 527 // specificity to override .sections-card-ui styles 528 .ds-card.ds-spoc-rectangle.ds-spoc-rectangle { 529 box-shadow: none; 530 background: none; 531 532 .ds-image { 533 padding-block-start: 83.4%; 534 } 535 536 .card-stp-button-hover-background { 537 padding-block-start: 83.4%; 538 } 539 540 .img-wrapper .ds-image img { 541 border-radius: var(--border-radius-medium); 542 } 543 544 .meta { 545 padding-inline: 0; 546 padding-block: var(--space-medium); 547 548 .title { 549 text-transform: uppercase; 550 font-size: var(--font-size-small); 551 font-weight: var(--font-weight); 552 color: var(--newtab-text-secondary-color); 553 } 554 555 .excerpt { 556 display: none; 557 } 558 } 559 560 .card-stp-button-hover-background { 561 border-radius: var(--border-radius-medium); 562 } 563 564 &.sections-card-ui { 565 .img-wrapper .ds-image img { 566 border-radius: var(--border-radius-large); 567 } 568 } 569 570 &.sections-card-ui:hover { 571 box-shadow: none; 572 573 .img-wrapper .ds-image img { 574 box-shadow: 0 2px 14px 0 var(--newtab-section-card-box-shadow-color); 575 } 576 } 577 578 &.refined-cards { 579 @include newtab-card-style; 580 581 .img-wrapper .ds-image img { 582 border-end-start-radius: 0; 583 border-end-end-radius: 0; 584 } 585 586 &:hover .img-wrapper .ds-image img { 587 box-shadow: none; 588 } 589 590 .meta { 591 padding: var(--space-small) var(--space-large); 592 padding-block-end: 0; 593 594 } 595 596 .info-wrap { 597 margin-block-start: auto; 598 } 599 600 .meta .title { 601 text-transform: none; 602 } 603 604 .sections-card-footer { 605 display: none; 606 } 607 608 .card-stp-button-position-wrapper { 609 z-index: 10; 610 inset-block-end: 0; 611 position: absolute; 612 613 } 614 615 .card-stp-button-position-wrapper .context-menu-position-container { 616 align-self: flex-start; 617 padding-block-start: var(--space-medium); 618 } 619 } 620 } 621 622 } 623 624 .ds-card-grid .refined-cards { 625 .meta { 626 color: var(--newtab-text-primary-color); 627 padding: var(--space-small) var(--space-large); 628 629 .excerpt { 630 display: none; 631 } 632 } 633 634 .sections-card-footer { 635 display: flex; 636 justify-content: space-between; 637 pointer-events: none; 638 max-width: 230px; 639 margin-block-start: var(--space-xsmall); 640 641 .source-wrapper { 642 margin-block-end: 0; 643 margin-inline-end: var(--space-xxsmall); 644 max-width: 175px; 645 } 646 } 647 648 &:has(.story-footer .story-sponsored-label) { 649 .sections-card-footer { 650 display: none; 651 } 652 653 .card-stp-button-position-wrapper { 654 inset-block-end: var(--space-small); 655 } 656 } 657 658 .story-footer { 659 margin-block: 0 var(--space-xsmall); 660 } 661 662 .card-stp-button-hover-background { 663 height: 100%; 664 padding-block-start: 0; 665 background: transparent; 666 667 .card-stp-button-position-wrapper { 668 inset-block-start: unset; 669 // this value needs to equal the current padding of the card 670 inset-block-end: var(--space-medium); 671 inset-inline-end: var(--space-large); 672 background: var(--button-background-color-ghost); 673 } 674 } 675 676 .context-menu-button { 677 background-color: var(--button-background-color-ghost); 678 679 @media (forced-colors: active) { 680 border: var(--border-width) solid var(--button-border-color-ghost); 681 } 682 } 683 684 &:hover, 685 &.active { 686 h3 { 687 color: var(--color-accent-primary); 688 } 689 690 .context-menu-button:hover { 691 background-color: var(--button-background-color-ghost-hover); 692 693 @media (forced-colors: active) { 694 border-color: var(--button-border-color-ghost-hover); 695 fill: var(--button-text-color-ghost-hover); 696 } 697 698 &:active { 699 background-color: var(--button-background-color-ghost-active); 700 } 701 } 702 703 .context-menu-button:focus-visible { 704 outline: 2px solid var(--newtab-button-focus-border); 705 background-color: var(--newtab-button-static-focus-background); 706 } 707 } 708 709 .sections-card-footer { 710 .source { 711 display: block; 712 } 713 } 714 }