@layer components { /* List page tab bar — single-line horizontal scroll, matches .app-tabs pattern. The active tab is scrolled into view by initListTabs on mount. */ .app-list-tabs { position: relative; display: flex; flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; -webkit-overflow-scrolling: touch; scroll-behavior: smooth; scroll-snap-type: x proximity; margin-bottom: var(--app-spacing); border-bottom: 1px solid var(--app-list-tabs-border); scrollbar-width: none; } .app-list-tabs::-webkit-scrollbar { display: none; } .app-list-tabs button, .app-list-tabs a { background: transparent; border: 0; padding: 5px 10px 5px 10px; color: var(--app-list-tabs-muted); cursor: pointer; font-weight: var(--font-medium); border-bottom: 2px solid transparent; text-decoration: none; flex-shrink: 0; white-space: nowrap; scroll-snap-align: start; } .app-list-tabs button:hover, .app-list-tabs button:focus-visible, .app-list-tabs a:hover, .app-list-tabs a:focus-visible { color: var(--app-color); } .app-list-tabs button.is-active, .app-list-tabs a.is-active { color: var(--app-color); border-color: var(--app-list-tabs-active); } /* Gradient fade masks — toggled by initListTabs via has-overflow/at-start/at-end. Uses mask-image on the scroll container itself, no wrapper needed. */ .app-list-tabs.has-overflow:not(.at-start):not(.at-end) { mask-image: linear-gradient( to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100% ); -webkit-mask-image: linear-gradient( to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100% ); } .app-list-tabs.has-overflow.at-start:not(.at-end) { mask-image: linear-gradient( to right, black 0, black calc(100% - 24px), transparent 100% ); -webkit-mask-image: linear-gradient( to right, black 0, black calc(100% - 24px), transparent 100% ); } .app-list-tabs.has-overflow:not(.at-start).at-end { mask-image: linear-gradient( to right, transparent 0, black 24px, black 100% ); -webkit-mask-image: linear-gradient( to right, transparent 0, black 24px, black 100% ); } }