|
46 | 46 | @layer base { |
47 | 47 | html { |
48 | 48 | @apply scroll-smooth; |
| 49 | + /* Lock html to the viewport — all scrolling is handled by .app-scroll-region */ |
| 50 | + overflow: hidden; |
| 51 | + height: 100%; |
49 | 52 | } |
50 | 53 |
|
51 | 54 | body { |
52 | 55 | @apply bg-surface-white text-ink-900 font-sans antialiased text-base leading-relaxed; |
| 56 | + /* Prevent body from generating its own scrollbar */ |
| 57 | + overflow: hidden; |
| 58 | + height: 100%; |
53 | 59 | } |
54 | 60 |
|
55 | 61 | /* ── Typography Scale (Syne Display + Manrope Body) ── */ |
|
119 | 125 | } |
120 | 126 |
|
121 | 127 | /* ============================================================================ |
122 | | - CUSTOM SCROLLBAR — Branded Floating Pill |
123 | | - Works on: Chrome, Edge, Brave (WebKit/Blink) |
124 | | - Strategy: transparent track + narrow pill thumb via border-clip trick |
| 128 | + CUSTOM SCROLLBAR — ClientEcho Signature Rail |
| 129 | + Design Language: Monochrome precision. Ink-on-glass. Editorial restraint. |
| 130 | + ──────────────────────────────────────────────────────────────────────────── |
| 131 | + Architecture: |
| 132 | + Track : 8px wide, transparent — blends into any background |
| 133 | + Thumb : ink-900 pill with 2.5px inset border — appears as a 3px rail |
| 134 | + States : default → hover → active progressively increase opacity |
| 135 | + Easing : spring cubic-bezier(0.16, 1, 0.3, 1) — matches FadeInUp system |
| 136 | + Rhyming tokens: |
| 137 | + border-radius: 9999px — echoes navbar badge, CTA buttons, feature icons |
| 138 | + ink-900 (#2D2D2D) — same as heading text, logo, icon fills |
125 | 139 | ============================================================================ */ |
126 | 140 |
|
127 | | -/* ── Base Scrollbar Styling ── */ |
| 141 | +/* ── Global fallback (modals, overflow containers not using .app-scroll-region) ── */ |
128 | 142 | ::-webkit-scrollbar { |
129 | 143 | width: 8px; |
130 | 144 | height: 8px; |
131 | 145 | } |
132 | 146 |
|
| 147 | +/* Kill the native ▲▼ arrow buttons on ALL scrollbars */ |
| 148 | +::-webkit-scrollbar-button { |
| 149 | + display: none; |
| 150 | + height: 0; |
| 151 | + width: 0; |
| 152 | +} |
| 153 | + |
133 | 154 | ::-webkit-scrollbar-track { |
134 | 155 | background: transparent; |
135 | 156 | } |
136 | 157 |
|
137 | 158 | ::-webkit-scrollbar-thumb { |
138 | | - background-color: rgba(45, 45, 45, 0.2); |
| 159 | + background: rgba(45, 45, 45, 0.22); |
139 | 160 | background-clip: padding-box; |
| 161 | + /* Integer-only border — sub-pixel values are silently ignored by Chrome */ |
| 162 | + border: 2px solid transparent; |
140 | 163 | border-radius: 9999px; |
| 164 | + transition: background 0.2s cubic-bezier(0.16, 1, 0.3, 1); |
141 | 165 | } |
142 | 166 |
|
143 | 167 | ::-webkit-scrollbar-thumb:hover { |
144 | | - background-color: rgba(45, 45, 45, 0.4); |
| 168 | + background: rgba(45, 45, 45, 0.5); |
| 169 | + background-clip: padding-box; |
145 | 170 | } |
146 | 171 |
|
147 | | -/* ── Light Surface Scrollbar (Landing + Creator Dashboard) ── */ |
| 172 | +/* ── Primary landing page scrollbar ── */ |
| 173 | +/* |
| 174 | + Dual-surface challenge: thumb must read clearly on |
| 175 | + • Dark hero : #33363B (ink-800) |
| 176 | + • Light body : #FFFFFF and #EFF3F6 |
| 177 | +
|
| 178 | + Solution: Frosted glass track tint + high-contrast thumb |
| 179 | + • Track gets a faint rgba(239,243,246,0.08) wash — barely there on light, |
| 180 | + creates a subtle recessed groove on dark sections |
| 181 | + • Thumb is solid ink-900 at 0.72 opacity — confident on both surfaces |
| 182 | + • Inset: 2.5px — the pill appears 3px wide, narrow & editorial |
| 183 | +*/ |
148 | 184 | .app-scroll-region::-webkit-scrollbar { |
149 | | - width: 10px; |
| 185 | + width: 8px; |
| 186 | +} |
| 187 | + |
| 188 | +/* Hide the native arrow buttons on the main scroll container too */ |
| 189 | +.app-scroll-region::-webkit-scrollbar-button { |
| 190 | + display: none; |
| 191 | + height: 0; |
150 | 192 | } |
151 | 193 |
|
152 | 194 | .app-scroll-region::-webkit-scrollbar-track { |
153 | | - background: transparent; |
| 195 | + background: rgba(239, 243, 246, 0.06); |
154 | 196 | border-radius: 9999px; |
| 197 | + /* margin is NOT supported on scrollbar track — removed */ |
155 | 198 | } |
156 | 199 |
|
157 | 200 | .app-scroll-region::-webkit-scrollbar-thumb { |
158 | | - /* Reliable cross-browser approach: mid-opacity dark pill. |
159 | | - rgba(80,80,80,0.35) sits between dark and light — |
160 | | - visible on both #33363B hero and #EFF3F6 surface-light sections. */ |
161 | | - background-color: rgba(80, 80, 80, 0.35); |
| 201 | + background: rgba(45, 45, 45, 0.72); |
162 | 202 | background-clip: padding-box; |
163 | | - border: 3px solid transparent; |
| 203 | + /* Integer borders only — Chrome ignores sub-pixel scrollbar values */ |
| 204 | + border: 2px solid transparent; |
164 | 205 | border-radius: 9999px; |
165 | | - min-height: 40px; |
166 | | - transition: background-color 0.25s ease; |
| 206 | + min-height: 44px; |
| 207 | + transition: background 0.22s cubic-bezier(0.16, 1, 0.3, 1), |
| 208 | + border-width 0.22s cubic-bezier(0.16, 1, 0.3, 1); |
167 | 209 | } |
168 | 210 |
|
169 | 211 | .app-scroll-region::-webkit-scrollbar-thumb:hover { |
170 | | - background-color: rgba(60, 60, 60, 0.6); |
| 212 | + background: rgba(45, 45, 45, 0.88); |
| 213 | + background-clip: padding-box; |
| 214 | + /* Tighten inset on hover — thumb widens as micro-feedback */ |
| 215 | + border: 1px solid transparent; |
171 | 216 | } |
172 | 217 |
|
173 | 218 | .app-scroll-region::-webkit-scrollbar-thumb:active { |
174 | | - background-color: rgba(40, 40, 40, 0.8); |
| 219 | + background: rgba(45, 45, 45, 0.97); |
| 220 | + background-clip: padding-box; |
| 221 | + border: 1px solid transparent; |
| 222 | +} |
| 223 | + |
| 224 | +/* |
| 225 | + CRITICAL: Chrome 121+ treats scrollbar-width/scrollbar-color as taking full |
| 226 | + precedence over ::-webkit-scrollbar pseudo-elements on the SAME element. |
| 227 | + If both are present, Chrome IGNORES the webkit rules and renders a native scrollbar. |
| 228 | + Fix: gate Firefox-only properties behind @supports (-moz-appearance:none). |
| 229 | +*/ |
| 230 | +@supports (-moz-appearance: none) { |
| 231 | + /* Firefox only — webkit pseudo-elements don't exist here */ |
| 232 | + .app-scroll-region { |
| 233 | + scrollbar-width: thin; |
| 234 | + scrollbar-color: rgba(45, 45, 45, 0.65) transparent; |
| 235 | + } |
175 | 236 | } |
176 | 237 |
|
177 | | -/* Firefox */ |
178 | | -.app-scroll-region { |
179 | | - scrollbar-width: thin; |
180 | | - scrollbar-color: rgba(45, 45, 45, 0.22) transparent; |
| 238 | +/* ── Admin dark-surface scrollbar ── */ |
| 239 | +.app-scroll-region--dark::-webkit-scrollbar-button { |
| 240 | + display: none; |
| 241 | + height: 0; |
181 | 242 | } |
182 | 243 |
|
183 | | -/* ── Dark Surface Scrollbar (Admin Dashboard) ── */ |
184 | 244 | .app-scroll-region--dark::-webkit-scrollbar-thumb { |
185 | | - background-color: rgba(255, 255, 255, 0.16); |
| 245 | + background: rgba(255, 255, 255, 0.28); |
186 | 246 | background-clip: padding-box; |
187 | | - border: 3px solid transparent; |
| 247 | + border: 2px solid transparent; |
188 | 248 | border-radius: 9999px; |
189 | | - min-height: 40px; |
190 | | - transition: background-color 0.2s ease; |
| 249 | + min-height: 44px; |
| 250 | + transition: background 0.22s cubic-bezier(0.16, 1, 0.3, 1), |
| 251 | + border-width 0.22s cubic-bezier(0.16, 1, 0.3, 1); |
191 | 252 | } |
192 | 253 |
|
193 | 254 | .app-scroll-region--dark::-webkit-scrollbar-thumb:hover { |
194 | | - background-color: rgba(255, 255, 255, 0.35); |
| 255 | + background: rgba(255, 255, 255, 0.52); |
| 256 | + background-clip: padding-box; |
| 257 | + border: 1px solid transparent; |
195 | 258 | } |
196 | 259 |
|
197 | 260 | .app-scroll-region--dark::-webkit-scrollbar-thumb:active { |
198 | | - background-color: rgba(255, 255, 255, 0.55); |
| 261 | + background: rgba(255, 255, 255, 0.78); |
| 262 | + background-clip: padding-box; |
| 263 | + border: 1px solid transparent; |
199 | 264 | } |
200 | 265 |
|
201 | | -.app-scroll-region--dark { |
202 | | - scrollbar-color: rgba(255, 255, 255, 0.16) transparent; |
| 266 | +@supports (-moz-appearance: none) { |
| 267 | + .app-scroll-region--dark { |
| 268 | + scrollbar-color: rgba(255, 255, 255, 0.28) transparent; |
| 269 | + } |
203 | 270 | } |
204 | 271 |
|
205 | 272 | /* ── Generic .custom-scrollbar class (modals, drawers, table overflow) ── */ |
|
0 commit comments