70 lines
2.3 KiB
CSS
70 lines
2.3 KiB
CSS
* {
|
||
box-sizing: border-box;
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
/*
|
||
* AppLink is the only place link affordance (color, underline) is decided —
|
||
* this reset keeps a bare <a> (e.g. inside rich text) from inheriting the
|
||
* browser's default blue/underline before AppLink's own styling applies.
|
||
*/
|
||
a {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
}
|
||
|
||
::selection {
|
||
background-color: var(--bal-primary-soft);
|
||
color: var(--bal-text-primary);
|
||
}
|
||
|
||
/*
|
||
* Directional icons (back/chevron_start, …) are authored for LTR and mirror
|
||
* under RTL. AppIcon sets `data-icon-directional` for every name registered
|
||
* in AppIcon/config.ts's DIRECTIONAL_ICONS — this is the only flip rule in
|
||
* the app; never hand-roll a per-component mirror.
|
||
*/
|
||
[dir='rtl'] [data-icon-directional] {
|
||
transform: scaleX(-1);
|
||
}
|
||
|
||
/*
|
||
* App-wide motion pass (phase 12) — one restrained language: a calm 150–200ms fade + small slide on
|
||
* route-group content and skeleton→content swaps. `key`-triggered remounts (RouteFadeIn) or a plain
|
||
* mount (a skeleton branch replaced by a populated one) both replay this the same way — there is
|
||
* exactly one animation definition for both cases, never a per-screen bespoke one.
|
||
*/
|
||
@keyframes bal-fade-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(4px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
[data-bal-route-fade] {
|
||
animation: bal-fade-in var(--bal-motion-base) var(--bal-easing-standard);
|
||
}
|
||
|
||
/*
|
||
* The single reduced-motion gate for the whole app (client/CLAUDE.md "Golden rules" — CSS over JS for
|
||
* theme mechanics). This is the ONE place `prefers-reduced-motion: reduce` is handled — every animation
|
||
* and transition this phase adds (the route fade above, MUI's own Dialog/Drawer/Menu/Collapse/Fade
|
||
* transitions, the admin config-history/ExplainerCard/EscrowExplainer chevron rotations) collapses to
|
||
* an effectively-instant appearance. Do not add a second, component-local reduced-motion check anywhere
|
||
* else — extend this rule instead if a new motion primitive needs the same treatment.
|
||
*/
|
||
@media (prefers-reduced-motion: reduce) {
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
animation-duration: 0.01ms !important;
|
||
animation-iteration-count: 1 !important;
|
||
transition-duration: 0.01ms !important;
|
||
scroll-behavior: auto !important;
|
||
}
|
||
}
|