2026-05-28 07:11:34 +00:00

452 lines
12 KiB
CSS

@import 'tailwind/_base.css';
@import 'tailwind/_components.css';
@import 'tailwind/_utilities.css';
@import 'intro.js/introjs.css';
@import '_checkbox-radio-switch.css';
@import '_progress.css';
@import '_scrollbars.css';
@import '_table.css';
@import '_helper.css';
@import '_calendar.css';
@import '_select-dropdown.css';
@import '_theme.css';
@import '_rich-text.css';
/* ═══════════════════════════════════════════════════════════════════
Custom Font Declarations
═══════════════════════════════════════════════════════════════════ */
@font-face {
font-family: 'Maple';
src: url('/fonts/MapleMedium.otf') format('opentype');
}
/* Page transition timing - single source of truth */
:root {
--crossfade-duration: 700ms;
/* Smooth easing: slow start, gentle acceleration, soft landing */
/* Chrome/Firefox: Material Design standard easing */
--crossfade-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
/* Safari-specific easing - Safari's bezier curve rendering is different,
use a simpler curve that Safari handles more smoothly */
@supports (-webkit-touch-callout: none) {
:root {
/* Safari: use ease-in-out which Safari renders more consistently */
--crossfade-easing: cubic-bezier(0.42, 0, 0.58, 1);
}
}
/* Firefox-specific optimizations */
@-moz-document url-prefix() {
:root {
/* Firefox handles the standard easing well, but we can optimize */
--crossfade-easing: cubic-bezier(0.4, 0, 0.2, 1);
}
}
.introjs-tooltip {
@apply min-w-[400px] max-w-[480px] p-2 !important;
}
.good-img {
@apply -mt-96 !important;
}
.end-img {
@apply -mt-72 !important;
}
.introjs-button {
@apply bg-blue-600 text-white !important;
text-shadow: none !important;
}
.introjs-bullets ul li a.active {
@apply bg-blue-600 !important;
}
.introjs-prevbutton {
@apply bg-transparent border border-blue-600 text-blue-600 !important;
}
/* Page crossfade animation keyframes - Safari optimized */
@-webkit-keyframes page-crossfade-in {
from {
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes page-crossfade-in {
from {
opacity: 0;
transform: translate3d(0, 0, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes page-crossfade-out {
from {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes page-crossfade-out {
from {
opacity: 1;
transform: translate3d(0, 0, 0);
}
to {
opacity: 0;
transform: translate3d(0, 0, 0);
}
}
/* Fade from black animation - black overlay fades out 1 → 0 */
/* Page has already switched, black covers it then reveals new content */
@keyframes fade-from-black {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
/* Crossfade animation classes - GPU accelerated for all browsers */
/* Duration controlled by --transition-duration (from JS) or --crossfade-duration (CSS variable) */
/* This allows the hierarchical transition settings to override the default CSS duration */
.animate-crossfade-in {
/* Explicit initial state prevents flash during animation setup */
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Full animation property for maximum browser compatibility */
-webkit-animation-name: page-crossfade-in;
animation-name: page-crossfade-in;
-webkit-animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
-webkit-animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-play-state: running;
animation-play-state: running;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
/* Optimize compositing */
will-change: opacity;
contain: layout style paint;
}
.animate-crossfade-out {
/* Explicit initial state prevents flash during animation setup */
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Full animation property for maximum browser compatibility */
-webkit-animation-name: page-crossfade-out;
animation-name: page-crossfade-out;
-webkit-animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
-webkit-animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-play-state: running;
animation-play-state: running;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
/* Optimize compositing */
will-change: opacity;
contain: layout style paint;
}
/* Safari-specific GPU compositing optimization */
@supports (-webkit-touch-callout: none) {
.animate-crossfade-in,
.animate-crossfade-out {
/* Force GPU layer creation in Safari */
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
/* Isolate the layer for better compositing */
isolation: isolate;
/* Use will-change instead of perspective for GPU acceleration */
will-change: opacity, transform;
}
}
/* Firefox-specific optimizations */
@-moz-document url-prefix() {
.animate-crossfade-in,
.animate-crossfade-out {
/* Firefox handles animations well but benefits from layer isolation */
will-change: opacity, transform;
}
}
/* Fade from black animation class - for smooth page transitions via black overlay */
/* Black starts opaque (hiding page switch), then fades out to reveal new page */
.animate-fade-from-black {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-animation-name: fade-from-black;
animation-name: fade-from-black;
-webkit-animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
animation-duration: var(--transition-duration, var(--crossfade-duration, 700ms));
-webkit-animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
animation-timing-function: var(
--transition-easing,
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1))
);
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
will-change: opacity;
contain: layout style paint;
}
/* Transition-based crossfade (Safari-optimized alternative to animations) */
/* Use this for better Safari stability - transitions don't have the "snap" issue
when state changes because they interpolate between current and target values */
.crossfade-transition {
transition: opacity var(--crossfade-duration, 700ms)
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1));
-webkit-transition: opacity var(--crossfade-duration, 700ms)
var(--crossfade-easing, cubic-bezier(0.4, 0, 0.2, 1));
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
will-change: opacity;
}
/* Safari-specific optimization for transitions */
@supports (-webkit-touch-callout: none) {
.crossfade-transition {
isolation: isolate;
will-change: opacity, transform;
}
}
/* =============================================================
Page Transition Animations (Slide, Zoom)
These animations support the hierarchical transition settings:
Global → Project → Element cascade with configurable:
- Duration: --transition-duration CSS variable
- Easing: --transition-easing CSS variable
- Overlay Color: --overlay-color CSS variable (used by TransitionBlackOverlay)
Animation classes use these variables when present, falling back
to --crossfade-duration/--crossfade-easing for compatibility.
============================================================= */
/* Element appear animation keyframes - Safari optimized */
@-webkit-keyframes element-fade-in {
from {
opacity: 0;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes element-fade-in {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes element-slide-up {
from {
opacity: 0;
-webkit-transform: translate3d(0, 20px, 0);
transform: translate3d(0, 20px, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes element-slide-up {
from {
opacity: 0;
transform: translate3d(0, 20px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes element-slide-down {
from {
opacity: 0;
-webkit-transform: translate3d(0, -20px, 0);
transform: translate3d(0, -20px, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes element-slide-down {
from {
opacity: 0;
transform: translate3d(0, -20px, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes element-slide-left {
from {
opacity: 0;
-webkit-transform: translate3d(20px, 0, 0);
transform: translate3d(20px, 0, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes element-slide-left {
from {
opacity: 0;
transform: translate3d(20px, 0, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes element-slide-right {
from {
opacity: 0;
-webkit-transform: translate3d(-20px, 0, 0);
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 1;
-webkit-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
}
@keyframes element-slide-right {
from {
opacity: 0;
transform: translate3d(-20px, 0, 0);
}
to {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
@-webkit-keyframes element-scale-in {
from {
opacity: 0;
-webkit-transform: scale3d(0.8, 0.8, 1);
transform: scale3d(0.8, 0.8, 1);
}
to {
opacity: 1;
-webkit-transform: scale3d(1, 1, 1);
transform: scale3d(1, 1, 1);
}
}
@keyframes element-scale-in {
from {
opacity: 0;
transform: scale3d(0.8, 0.8, 1);
}
to {
opacity: 1;
transform: scale3d(1, 1, 1);
}
}
/* Instrument Sans font utilities */
.font-instrument-condensed {
font-family: 'Instrument Sans Variable', sans-serif;
font-stretch: 75%;
}
.font-instrument {
font-family: 'Instrument Sans Variable', sans-serif;
font-stretch: 100%;
}
/* iOS Safari: Hide native video play button overlay
These selectors target WebKit-specific pseudo-elements that appear
when autoplay is blocked or when iOS detects an unmuted video */
video::-webkit-media-controls-start-playback-button {
display: none !important;
-webkit-appearance: none;
}
video::-webkit-media-controls-overlay-play-button {
display: none !important;
-webkit-appearance: none;
}
/* Prevent controls from appearing on autoplay fail */
video::-webkit-media-controls-panel {
display: none !important;
-webkit-appearance: none;
}
video::-webkit-media-controls {
display: none !important;
}