| @@ -29,9 +29,9 @@ | ||
| 29 | 29 | --primary-hover: #1E9089; |
| 30 | 30 | --primary-tint: #E6F5F3; |
| 31 | 31 | --on-primary: #FFFFFF; |
| 32 | 32 | /* Text/heading colour for content sitting ON a primary/info tint. */ |
| 33 | - --on-tint: #1E8079; | |
| 33 | + --on-tint: #1A7770; /* 4.79:1 on --primary-tint, 5.37:1 on --paper — small Pro badge text sits on the tint */ | |
| 34 | 34 | --primary-glow: 0 2px 12px rgba(42, 167, 160, .30); |
| 35 | 35 | |
| 36 | 36 | /* Surfaces */ |
| 37 | 37 | --canvas: #FBFBFC; |
| @@ -78,8 +78,14 @@ | ||
| 78 | 78 | --danger-tint: #FDECEC; |
| 79 | 79 | --info: #2AA7A0; |
| 80 | 80 | --info-tint: #E6F5F3; |
| 81 | 81 | |
| 82 | + /* Add-on: something sold separately from Pro (DESIGN.md §24.50). Orange so | |
| 83 | + it never reads as Pro's teal or the warning amber. --addon is text: 5.6:1 | |
| 84 | + on --addon-tint, 6.4:1 on --paper. */ | |
| 85 | + --addon: #9A4A0B; | |
| 86 | + --addon-tint: #FEF1E6; | |
| 87 | + | |
| 82 | 88 | /* Deep-sea rail (deliberately not near-black, to separate from WP's menu) */ |
| 83 | 89 | --rail-top: #14211F; |
| 84 | 90 | --rail-bottom: #0D1615; |
| 85 | 91 | --rail-text: #9FADAB; |
| @@ -127,8 +133,10 @@ | ||
| 127 | 133 | --info-tint: #0E2622; |
| 128 | 134 | --success-tint: #12251F; |
| 129 | 135 | --warning-tint: #251C0F; |
| 130 | 136 | --danger-tint: #2A1516; |
| 137 | + --addon: #FDBA74; | |
| 138 | + --addon-tint: #2A1A0E; | |
| 131 | 139 | } |
| 132 | 140 | |
| 133 | 141 | /* ---- Signature motion (used by the shell + later screens) -------------- */ |
| 134 | 142 | @keyframes xspeed-boltpulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.82); } } |
| @@ -133,15 +141,39 @@ | ||
| 133 | 141 | /* ---- Signature motion (used by the shell + later screens) -------------- */ |
| 134 | 142 | @keyframes xspeed-boltpulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .45; transform: scale(.82); } } |
| 135 | 143 | @keyframes xspeed-sweep { 0% { background-position: -220px 0; } 100% { background-position: 320px 0; } } |
| 136 | 144 | @keyframes xspeed-ringfill { from { stroke-dashoffset: 326.7; } to { stroke-dashoffset: 26.1; } } |
| 145 | +@keyframes xspeed-drain { from { transform: scaleX(1); } to { transform: scaleX(0); } } | |
| 146 | +@keyframes xspeed-pop { from { opacity: 0; transform: scale(.6); } to { opacity: 1; transform: none; } } | |
| 137 | 147 | |
| 138 | 148 | /* Signature-motion utility classes (reduced-motion aware via the rule below). */ |
| 139 | 149 | .xspeed-anim-boltpulse { animation: xspeed-boltpulse 1.8s ease-in-out infinite; } |
| 140 | 150 | .xspeed-anim-sweep { background-size: 220px 100%; animation: xspeed-sweep 1.5s linear infinite; } |
| 151 | +/* Purge result (§24.38). The resting state is the END state, so the reduced-motion | |
| 152 | + rule below leaves the hairline undrawn and the icon simply present. */ | |
| 153 | +.xspeed-anim-drain { transform: scaleX(0); transform-origin: left; animation: xspeed-drain .6s cubic-bezier(.3, .7, .3, 1) both; } | |
| 154 | +.xspeed-anim-pop { animation: xspeed-pop .2s ease-out both; } | |
| 141 | 155 | |
| 142 | 156 | @media (prefers-reduced-motion: reduce) { |
| 143 | 157 | #xspeed-app [class*="xspeed-anim"] { animation: none !important; } |
| 158 | +} | |
| 159 | + | |
| 160 | +/* ---- Loader bar + live dot (DESIGN.md §24.55) ----------------------------- */ | |
| 161 | +/* | |
| 162 | + * A thin indeterminate bar for a wait with no progress to report, and a | |
| 163 | + * pulsing dot beside a status line that keeps updating on its own. Both are | |
| 164 | + * CSS here rather than Tailwind utilities because they need a pseudo-element | |
| 165 | + * and keyframes. Tokens only: --line, --primary, --success, --radius-pill. | |
| 166 | + */ | |
| 167 | +@keyframes xspeed-blink { 50% { opacity: .25; } } | |
| 168 | +@keyframes xspeed-slide { 0% { transform: translateX(-100%); } 100% { transform: translateX(300%); } } | |
| 169 | +#xspeed-app .xspeed-loader-bar { height: 3px; border-radius: var(--radius-pill); background: var(--line); overflow: hidden; position: relative; max-width: 320px; } | |
| 170 | +#xspeed-app .xspeed-loader-bar::after { content: ""; position: absolute; inset: 0; width: 35%; border-radius: var(--radius-pill); background: var(--primary); animation: xspeed-slide 1.6s ease-in-out infinite; } | |
| 171 | +#xspeed-app .xspeed-live-dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--primary); margin-top: 6px; animation: xspeed-blink 1.6s ease-in-out infinite; } | |
| 172 | +#xspeed-app .xspeed-live-dot.is-done { background: var(--success); animation: none; } | |
| 173 | +@media (prefers-reduced-motion: reduce) { | |
| 174 | + #xspeed-app .xspeed-live-dot, #xspeed-app .xspeed-loader-bar::after { animation: none; } | |
| 175 | + #xspeed-app .xspeed-loader-bar::after { width: 100%; opacity: .4; } | |
| 144 | 176 | } |
| 145 | 177 | |
| 146 | 178 | /* ---- MCP discovery card (Overview, disconnected) ----------------------- */ |
| 147 | 179 | /* |