1$top-sites-size: $grid-unit;
2$top-sites-border-radius: 4px;
3$top-sites-title-height: 30px;
4$top-sites-vertical-space: 8px;
5$screenshot-size: cover;
6$rich-icon-size: 96px;
7$default-icon-wrapper-size: 42px;
8$default-icon-size: 32px;
9$default-icon-offset: 6px;
10$half-base-gutter: $base-gutter / 2;
11$hover-transition-duration: 150ms;
12
13.top-sites {
14  // Take back the margin from the bottom row of vertical spacing as well as the
15  // extra whitespace below the title text as it's vertically centered.
16  margin-bottom: $section-spacing - ($top-sites-vertical-space + $top-sites-title-height / 3);
17}
18
19.top-sites-list {
20  list-style: none;
21  margin: 0 (-$half-base-gutter);
22  padding: 0;
23
24  // Two columns
25  @media (max-width: $break-point-medium) {
26    > :nth-child(2n+1) {
27      @include context-menu-open-middle;
28    }
29
30    > :nth-child(2n) {
31      @include context-menu-open-left;
32    }
33  }
34
35  // Four columns
36  @media (min-width: $break-point-medium) and (max-width: $break-point-large) {
37    :nth-child(4n) {
38      @include context-menu-open-left;
39    }
40  }
41  @media (min-width: $break-point-medium) and (max-width: $break-point-medium + $card-width) {
42    :nth-child(4n+3) {
43      @include context-menu-open-left;
44    }
45  }
46
47  // Six columns
48  @media (min-width: $break-point-large) and (max-width: $break-point-large + 2 * $card-width) {
49    :nth-child(6n) {
50      @include context-menu-open-left;
51    }
52  }
53  @media (min-width: $break-point-large) and (max-width: $break-point-large + $card-width) {
54    :nth-child(6n+5) {
55      @include context-menu-open-left;
56    }
57  }
58
59  // Eight columns
60  @media (min-width: $break-point-widest) and (max-width: $break-point-widest + 2 * $card-width) {
61    :nth-child(8n) {
62      @include context-menu-open-left;
63    }
64  }
65  @media (min-width: $break-point-widest) and (max-width: $break-point-widest + $card-width) {
66    :nth-child(8n+7) {
67      @include context-menu-open-left;
68    }
69  }
70
71  .hide-for-narrow {
72    display: none;
73  }
74
75  @media (min-width: $break-point-medium) {
76    .hide-for-narrow {
77      display: inline-block;
78    }
79  }
80
81  @media (min-width: $break-point-large) {
82    .hide-for-narrow {
83      display: none;
84    }
85  }
86
87  @media (min-width: $break-point-widest) {
88    .hide-for-narrow {
89      display: inline-block;
90    }
91  }
92
93  li {
94    margin: 0 0 $top-sites-vertical-space;
95  }
96
97  &:not(.dnd-active) {
98    .top-site-outer:-moz-any(.active, :focus, :hover) {
99      .tile {
100        @include fade-in;
101      }
102
103      @include context-menu-button-hover;
104    }
105  }
106}
107
108// container for drop zone
109.top-site-outer {
110  padding: 0 $half-base-gutter;
111  display: inline-block;
112
113  // container for context menu
114  .top-site-inner {
115    position: relative;
116
117    > a {
118      color: inherit;
119      display: block;
120      outline: none;
121
122      &:-moz-any(.active, :focus) {
123        .tile {
124          @include fade-in;
125        }
126      }
127    }
128  }
129
130  @include context-menu-button;
131
132  .tile { // sass-lint:disable-block property-sort-order
133    border-radius: $top-sites-border-radius;
134    box-shadow: inset $inner-box-shadow, var(--newtab-card-shadow);
135    cursor: pointer;
136    height: $top-sites-size;
137    position: relative;
138    width: $top-sites-size;
139
140    // For letter fallback
141    align-items: center;
142    color: var(--newtab-text-secondary-color);
143    display: flex;
144    font-size: 32px;
145    font-weight: 200;
146    justify-content: center;
147    text-transform: uppercase; // sass-lint:disable-line no-disallowed-properties
148    transition: box-shadow $hover-transition-duration;
149
150    &::before {
151      content: attr(data-fallback);
152    }
153  }
154
155  .screenshot {
156    background-color: $white;
157    background-position: top left;
158    background-size: $screenshot-size;
159    border-radius: $top-sites-border-radius;
160    box-shadow: inset $inner-box-shadow;
161    height: 100%;
162    left: 0;
163    opacity: 0;
164    position: absolute;
165    top: 0;
166    transition: opacity 1s;
167    width: 100%;
168
169    &.active {
170      opacity: 1;
171    }
172  }
173
174  // Some common styles for all icons (rich and default) in top sites
175  .top-site-icon {
176    background-color: var(--newtab-topsites-background-color);
177    background-position: center center;
178    background-repeat: no-repeat;
179    border-radius: $top-sites-border-radius;
180    box-shadow: var(--newtab-topsites-icon-shadow);
181    position: absolute;
182  }
183
184  .rich-icon {
185    background-size: cover;
186    height: 100%;
187    inset-inline-start: 0;
188    top: 0;
189    width: 100%;
190  }
191
192  .default-icon,
193  .search-topsite {
194    background-size: $default-icon-size;
195    bottom: -$default-icon-offset;
196    height: $default-icon-wrapper-size;
197    inset-inline-end: -$default-icon-offset;
198    width: $default-icon-wrapper-size;
199
200    // for corner letter fallback
201    align-items: center;
202    display: flex;
203    font-size: 20px;
204    justify-content: center;
205
206    &[data-fallback]::before {
207      content: attr(data-fallback);
208    }
209  }
210
211  .search-topsite {
212    background-image: url('#{$image-path}glyph-search-16.svg');
213    background-size: 26px;
214    background-color: $blue-60;
215    border-radius: $default-icon-wrapper-size;
216    -moz-context-properties: fill;
217    fill: $white;
218    box-shadow: var(--newtab-card-shadow);
219    transition-duration: $hover-transition-duration;
220    transition-property: background-size, bottom, inset-inline-end, height, width;
221  }
222
223  &:hover .search-topsite {
224    $hover-icon-wrapper-size: $default-icon-wrapper-size + 4;
225    $hover-icon-offset: -$default-icon-offset - 3;
226
227    background-size: 28px;
228    border-radius: $hover-icon-wrapper-size;
229    bottom: $hover-icon-offset;
230    height: $hover-icon-wrapper-size;
231    inset-inline-end: $hover-icon-offset;
232    width: $hover-icon-wrapper-size;
233  }
234
235  // We want all search shortcuts to have a white background in case they have transparency.
236  &.search-shortcut {
237    .rich-icon {
238      background-color: $white;
239    }
240  }
241
242  .title {
243    color: var(--newtab-topsites-label-color);
244    font: message-box;
245    height: $top-sites-title-height;
246    line-height: $top-sites-title-height;
247    text-align: center;
248    width: $top-sites-size;
249    position: relative;
250
251    .icon {
252      fill: var(--newtab-icon-tertiary-color);
253      inset-inline-start: 0;
254      position: absolute;
255      top: 10px;
256    }
257
258    span {
259      height: $top-sites-title-height;
260      display: block;
261      overflow: hidden;
262      text-overflow: ellipsis;
263      white-space: nowrap;
264    }
265
266    &.pinned {
267      span {
268        padding: 0 13px;
269      }
270    }
271  }
272
273  .edit-button {
274    background-image: url('#{$image-path}glyph-edit-16.svg');
275  }
276
277  &.placeholder {
278    .tile {
279      box-shadow: inset $inner-box-shadow;
280    }
281
282    .screenshot {
283      display: none;
284    }
285  }
286
287  &.dragged {
288    .tile {
289      background: $grey-20;
290      box-shadow: none;
291
292      *,
293      &::before {
294        display: none;
295      }
296    }
297
298    .title {
299      visibility: hidden;
300    }
301  }
302}
303
304.edit-topsites-wrapper {
305  .modal {
306    box-shadow: $shadow-secondary;
307    left: 0;
308    margin: 0 auto;
309    max-height: calc(100% - 40px);
310    position: fixed;
311    right: 0;
312    top: 40px;
313    width: $wrapper-default-width;
314
315    @media (min-width: $break-point-medium) {
316      width: $wrapper-max-width-medium;
317    }
318
319    @media (min-width: $break-point-large) {
320      width: $wrapper-max-width-large;
321    }
322  }
323}
324
325.topsite-form {
326  $form-width: 300px;
327  $form-spacing: 32px;
328
329  .section-title {
330    font-size: 16px;
331    margin: 0 0 16px;
332  }
333
334  .form-input-container {
335    max-width: $form-width + 3 * $form-spacing + $rich-icon-size;
336    margin: 0 auto;
337    padding: $form-spacing;
338
339    .top-site-outer {
340      pointer-events: none;
341    }
342  }
343
344  .search-shortcuts-container {
345    max-width: 700px;
346    margin: 0 auto;
347    padding: $form-spacing;
348
349    > div {
350      margin-inline-end: -39px;
351    }
352
353    .top-site-outer {
354      margin-inline-start: 0;
355      margin-inline-end: 39px;
356    }
357  }
358
359  .top-site-outer {
360    padding: 0;
361    margin: 24px 0 0;
362    margin-inline-start: $form-spacing;
363  }
364
365  .fields-and-preview {
366    display: flex;
367  }
368
369  label {
370    font-size: $section-title-font-size;
371  }
372
373  .form-wrapper {
374    width: 100%;
375
376    .field {
377      position: relative;
378
379      .icon-clear-input {
380        position: absolute;
381        transform: translateY(-50%);
382        top: 50%;
383        inset-inline-end: 8px;
384      }
385    }
386
387    .url {
388      input:dir(ltr) {
389        padding-right: 32px;
390      }
391
392      input:dir(rtl) {
393        padding-left: 32px;
394
395        &:not(:placeholder-shown) {
396          direction: ltr;
397          text-align: right;
398        }
399      }
400    }
401
402    .enable-custom-image-input {
403      display: inline-block;
404      font-size: 13px;
405      margin-top: 4px;
406      cursor: pointer;
407    }
408
409    .custom-image-input-container {
410      margin-top: 4px;
411
412      .loading-container {
413        width: 16px;
414        height: 16px;
415        overflow: hidden;
416        position: absolute;
417        transform: translateY(-50%);
418        top: 50%;
419        inset-inline-end: 8px;
420      }
421
422      // This animation is derived from Firefox's tab loading animation
423      // See https://searchfox.org/mozilla-central/rev/b29daa46443b30612415c35be0a3c9c13b9dc5f6/browser/themes/shared/tabs.inc.css#208-216
424      .loading-animation {
425        @keyframes tab-throbber-animation {
426          100% { transform: translateX(-960px); }
427        }
428
429        @keyframes tab-throbber-animation-rtl {
430          100% { transform: translateX(960px); }
431        }
432
433        width: 960px;
434        height: 16px;
435        -moz-context-properties: fill;
436        fill: $blue-50;
437        background-image: url('chrome://browser/skin/tabbrowser/loading.svg');
438        animation: tab-throbber-animation 1.05s steps(60) infinite;
439
440        &:dir(rtl) {
441          animation-name: tab-throbber-animation-rtl;
442        }
443      }
444    }
445
446    input {
447      &[type='text'] {
448        background-color: var(--newtab-textbox-background-color);
449        border: $input-border;
450        margin: 8px 0;
451        padding: 0 8px;
452        height: 32px;
453        width: 100%;
454        font-size: 15px;
455
456        &:focus {
457          border: $input-border-active;
458          box-shadow: var(--newtab-textbox-focus-boxshadow);
459        }
460
461        &[disabled] {
462          border: $input-border;
463          box-shadow: none;
464          opacity: 0.4;
465        }
466      }
467    }
468
469    .invalid {
470      input {
471        &[type='text'] {
472          border: $input-error-border;
473          box-shadow: $input-error-boxshadow;
474        }
475      }
476    }
477
478    .error-tooltip {
479      animation: fade-up-tt 450ms;
480      background: $red-60;
481      border-radius: 2px;
482      color: $white;
483      inset-inline-start: 3px;
484      padding: 5px 12px;
485      position: absolute;
486      top: 44px;
487      z-index: 1;
488
489      // tooltip caret
490      &::before {
491        background: $red-60;
492        bottom: -8px;
493        content: '.';
494        height: 16px;
495        inset-inline-start: 12px;
496        position: absolute;
497        text-indent: -999px;
498        top: -7px;
499        transform: rotate(45deg);
500        white-space: nowrap;
501        width: 16px;
502        z-index: -1;
503      }
504    }
505  }
506
507  .actions {
508    justify-content: flex-end;
509
510    button {
511      margin-inline-start: 10px;
512      margin-inline-end: 0;
513    }
514  }
515
516  @media (max-width: $break-point-medium) {
517    .fields-and-preview {
518      flex-direction: column;
519
520      .top-site-outer {
521        margin-inline-start: 0;
522      }
523    }
524  }
525
526  // prevent text selection of keyword label when clicking to select
527  .title {
528    -moz-user-select: none;
529  }
530
531  // CSS styled checkbox
532  [type='checkbox']:not(:checked),
533  [type='checkbox']:checked {
534    inset-inline-start: -9999px;
535    position: absolute;
536  }
537
538  [type='checkbox']:not(:checked) + label,
539  [type='checkbox']:checked + label {
540    cursor: pointer;
541    display: block;
542    position: relative;
543  }
544
545  $checkbox-offset: -8px;
546
547  [type='checkbox']:not(:checked) + label::before,
548  [type='checkbox']:checked + label::before {
549    background: var(--newtab-background-color);
550    border: $input-border;
551    border-radius: $border-radius;
552    content: '';
553    height: 21px;
554    left: $checkbox-offset;
555    position: absolute;
556    top: $checkbox-offset;
557    width: 21px;
558    z-index: 1;
559
560    [dir='rtl'] & {
561      left: auto;
562      right: $checkbox-offset;
563    }
564  }
565
566  // checkmark
567  [type='checkbox']:not(:checked) + label::after,
568  [type='checkbox']:checked + label::after {
569    background: url('chrome://global/skin/icons/check.svg') no-repeat center center; // sass-lint:disable-line no-url-domains
570    content: '';
571    height: 21px;
572    left: $checkbox-offset;
573    position: absolute;
574    top: $checkbox-offset;
575    width: 21px;
576    -moz-context-properties: fill;
577    fill: var(--newtab-link-primary-color);
578    z-index: 2;
579
580    [dir='rtl'] & {
581      left: auto;
582      right: $checkbox-offset;
583    }
584  }
585
586  // when selected, highlight the tile
587  [type='checkbox']:checked + label {
588    .tile {
589      box-shadow: 0 0 0 2px var(--newtab-link-primary-color);
590    }
591  }
592
593  // checkmark changes
594  [type='checkbox']:not(:checked) + label::after {
595    opacity: 0;
596  }
597
598  [type='checkbox']:checked + label::after {
599    opacity: 1;
600  }
601
602  // accessibility
603  [type='checkbox']:checked:focus + label::before,
604  [type='checkbox']:not(:checked):focus + label::before {
605    border: 1px dotted var(--newtab-link-primary-color);
606  }
607}
608
609//used for tooltips below form element
610@keyframes fade-up-tt {
611  0% {
612    opacity: 0;
613    transform: translateY(15px);
614  }
615
616  100% {
617    opacity: 1;
618    transform: translateY(0);
619  }
620}
621