2026-04-20 09:20:50 +00:00
|
|
|
@import "tailwindcss";
|
|
|
|
|
@import "tw-animate-css";
|
2026-05-01 19:10:25 +00:00
|
|
|
@import "./custom-fonts.css";
|
2026-04-20 09:20:50 +00:00
|
|
|
@plugin "@tailwindcss/typography";
|
|
|
|
|
|
|
|
|
|
@custom-variant dark (&:is(.dark *));
|
|
|
|
|
|
|
|
|
|
@theme inline {
|
|
|
|
|
--color-background: hsl(var(--background));
|
|
|
|
|
--color-foreground: hsl(var(--foreground));
|
|
|
|
|
--color-border: hsl(var(--border));
|
|
|
|
|
--color-input: hsl(var(--input));
|
|
|
|
|
--color-ring: hsl(var(--ring));
|
|
|
|
|
|
|
|
|
|
--color-card: hsl(var(--card));
|
|
|
|
|
--color-card-foreground: hsl(var(--card-foreground));
|
|
|
|
|
--color-card-border: hsl(var(--card-border));
|
|
|
|
|
|
|
|
|
|
--color-popover: hsl(var(--popover));
|
|
|
|
|
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
|
|
|
--color-popover-border: hsl(var(--popover-border));
|
|
|
|
|
|
|
|
|
|
--color-primary: hsl(var(--primary));
|
|
|
|
|
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
|
|
|
--color-primary-border: var(--primary-border);
|
|
|
|
|
|
|
|
|
|
--color-secondary: hsl(var(--secondary));
|
|
|
|
|
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
|
|
|
--color-secondary-border: var(--secondary-border);
|
|
|
|
|
|
|
|
|
|
--color-muted: hsl(var(--muted));
|
|
|
|
|
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
|
|
|
--color-muted-border: var(--muted-border);
|
|
|
|
|
|
|
|
|
|
--color-accent: hsl(var(--accent));
|
|
|
|
|
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
|
|
|
--color-accent-border: var(--accent-border);
|
|
|
|
|
|
|
|
|
|
--color-destructive: hsl(var(--destructive));
|
|
|
|
|
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
|
|
|
--color-destructive-border: var(--destructive-border);
|
|
|
|
|
|
|
|
|
|
--color-sidebar: hsl(var(--sidebar));
|
|
|
|
|
--color-sidebar-foreground: hsl(var(--sidebar-foreground));
|
|
|
|
|
--color-sidebar-border: hsl(var(--sidebar-border));
|
|
|
|
|
--color-sidebar-primary: hsl(var(--sidebar-primary));
|
|
|
|
|
--color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
|
|
|
|
|
--color-sidebar-primary-border: var(--sidebar-primary-border);
|
|
|
|
|
--color-sidebar-accent: hsl(var(--sidebar-accent));
|
|
|
|
|
--color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
|
|
|
|
|
--color-sidebar-accent-border: var(--sidebar-accent-border);
|
|
|
|
|
--color-sidebar-ring: hsl(var(--sidebar-ring));
|
|
|
|
|
|
|
|
|
|
--font-sans: var(--app-font-sans);
|
|
|
|
|
--font-serif: var(--app-font-serif);
|
|
|
|
|
--font-mono: var(--app-font-mono);
|
|
|
|
|
|
|
|
|
|
--radius-sm: calc(var(--radius) - 4px);
|
|
|
|
|
--radius-md: calc(var(--radius) - 2px);
|
|
|
|
|
--radius-lg: var(--radius);
|
|
|
|
|
--radius-xl: calc(var(--radius) + 4px);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-20 10:25:54 +00:00
|
|
|
:root {
|
|
|
|
|
/* Light, calm, premium SaaS palette */
|
|
|
|
|
--background: 210 40% 98%; /* #F8FAFC */
|
|
|
|
|
--foreground: 222 47% 11%; /* slate-900 */
|
|
|
|
|
--card: 0 0% 100%; /* #FFFFFF */
|
|
|
|
|
--card-foreground: 222 47% 11%;
|
|
|
|
|
--popover: 0 0% 100%;
|
|
|
|
|
--popover-foreground: 222 47% 11%;
|
2026-05-05 07:51:36 +00:00
|
|
|
--primary: 218 70% 15%; /* #0B1E3F */
|
2026-04-20 10:25:54 +00:00
|
|
|
--primary-foreground: 0 0% 100%;
|
|
|
|
|
--secondary: 173 80% 40%; /* teal-500 */
|
|
|
|
|
--secondary-foreground: 0 0% 100%;
|
|
|
|
|
--muted: 210 40% 96%;
|
|
|
|
|
--muted-foreground: 215 16% 47%; /* slate-500 */
|
2026-04-29 17:48:51 +00:00
|
|
|
--accent: 210 40% 96%; /* slate-100 — matches sidebar hover */
|
|
|
|
|
--accent-foreground: 222 47% 11%; /* slate-900 */
|
2026-04-20 10:25:54 +00:00
|
|
|
--destructive: 0 84% 60%;
|
|
|
|
|
--destructive-foreground: 0 0% 100%;
|
|
|
|
|
--border: 214 32% 91%; /* #E2E8F0 */
|
|
|
|
|
--input: 214 32% 91%;
|
2026-05-05 07:51:36 +00:00
|
|
|
--ring: 218 70% 15%;
|
2026-04-20 10:25:54 +00:00
|
|
|
|
|
|
|
|
--sidebar: 0 0% 100%;
|
|
|
|
|
--sidebar-foreground: 222 47% 11%;
|
|
|
|
|
--sidebar-border: 214 32% 91%;
|
2026-05-05 07:51:36 +00:00
|
|
|
--sidebar-primary: 218 70% 15%;
|
2026-04-20 10:25:54 +00:00
|
|
|
--sidebar-primary-foreground: 0 0% 100%;
|
|
|
|
|
--sidebar-accent: 210 40% 96%;
|
|
|
|
|
--sidebar-accent-foreground: 222 47% 11%;
|
2026-05-05 07:51:36 +00:00
|
|
|
--sidebar-ring: 218 70% 15%;
|
2026-04-20 10:25:54 +00:00
|
|
|
|
2026-05-01 19:55:39 +00:00
|
|
|
/*
|
|
|
|
|
* Site-wide default font. DIN Next LT Arabic ships locally via
|
|
|
|
|
* `custom-fonts.css` (loaded on the line `@import "./custom-fonts.css"`
|
|
|
|
|
* at the top of this file), so this resolves immediately without a
|
|
|
|
|
* Google Fonts roundtrip. The remaining fallbacks are kept so the
|
|
|
|
|
* page remains readable while the @font-face files are still being
|
|
|
|
|
* fetched on a cold cache (font-display: swap).
|
|
|
|
|
*/
|
|
|
|
|
--app-font-sans: "DIN Next LT Arabic", "Tajawal", system-ui, sans-serif;
|
2026-04-20 09:20:50 +00:00
|
|
|
--app-font-serif: Georgia, serif;
|
2026-05-01 19:55:39 +00:00
|
|
|
--app-font-mono: Menlo, Consolas, monospace;
|
2026-04-20 09:20:50 +00:00
|
|
|
--radius: 1rem;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@layer base {
|
|
|
|
|
* {
|
|
|
|
|
@apply border-border;
|
|
|
|
|
}
|
|
|
|
|
body {
|
2026-04-20 10:25:54 +00:00
|
|
|
@apply font-sans antialiased text-foreground;
|
|
|
|
|
background-color: #F8FAFC;
|
2026-04-20 09:20:50 +00:00
|
|
|
}
|
2026-05-10 08:56:17 +00:00
|
|
|
html,
|
|
|
|
|
body {
|
2026-05-10 09:29:05 +00:00
|
|
|
overflow-x: clip;
|
2026-05-10 08:56:17 +00:00
|
|
|
}
|
2026-05-10 11:33:44 +00:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* #460: On iOS Safari (iPad/iPhone), the URL bar only auto-collapses
|
|
|
|
|
* when the document is actually scrollable. Pages with short content
|
|
|
|
|
* (Services grid, Notifications list, an empty Notes tab, etc.) fit
|
|
|
|
|
* entirely within the viewport, so Safari has no scroll trigger and
|
|
|
|
|
* the URL bar stays pinned — wasting screen real estate.
|
|
|
|
|
*
|
|
|
|
|
* We force the document to always be ~1px taller than the small
|
|
|
|
|
* viewport (`100svh` = the viewport height *with* the URL bar
|
|
|
|
|
* visible, so the +1px gap stays constant whether the bar is shown
|
|
|
|
|
* or hidden). That tiny extra height is enough for Safari to enable
|
|
|
|
|
* its URL-bar-collapse gesture on every page.
|
|
|
|
|
*
|
|
|
|
|
* Scoped to touch devices via `(hover: none) and (pointer: coarse)`
|
|
|
|
|
* so desktop browsers never get a stray scrollbar on short pages.
|
|
|
|
|
*/
|
|
|
|
|
@media (hover: none) and (pointer: coarse) {
|
|
|
|
|
html,
|
|
|
|
|
body {
|
|
|
|
|
min-height: calc(100svh + 1px);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-20 09:20:50 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-20 10:25:54 +00:00
|
|
|
/* Soft glassmorphism — light, very subtle blur */
|
2026-04-20 09:20:50 +00:00
|
|
|
.glass-panel {
|
2026-04-20 10:25:54 +00:00
|
|
|
background: rgba(255, 255, 255, 0.7);
|
|
|
|
|
backdrop-filter: blur(12px) saturate(140%);
|
|
|
|
|
-webkit-backdrop-filter: blur(12px) saturate(140%);
|
|
|
|
|
border: 1px solid #E2E8F0;
|
|
|
|
|
box-shadow: 0 8px 30px rgba(15, 23, 42, 0.05);
|
2026-04-20 09:20:50 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-20 10:25:54 +00:00
|
|
|
/* Light gradient background with floating blobs (Apple / SaaS style) */
|
2026-04-20 09:20:50 +00:00
|
|
|
.os-bg {
|
2026-04-20 10:25:54 +00:00
|
|
|
position: relative;
|
|
|
|
|
background-color: #F8FAFC;
|
2026-04-20 09:20:50 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-20 10:25:54 +00:00
|
|
|
.os-bg::before,
|
|
|
|
|
.os-bg::after {
|
|
|
|
|
content: "";
|
|
|
|
|
position: fixed;
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
z-index: 0;
|
|
|
|
|
border-radius: 9999px;
|
|
|
|
|
filter: blur(80px);
|
|
|
|
|
opacity: 0.55;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.os-bg::before {
|
|
|
|
|
width: 520px;
|
|
|
|
|
height: 520px;
|
|
|
|
|
top: -160px;
|
|
|
|
|
left: -120px;
|
|
|
|
|
background: radial-gradient(circle at 30% 30%, #C7D2FE 0%, #A5B4FC 40%, transparent 70%);
|
|
|
|
|
animation: blobFloat 18s ease-in-out infinite alternate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.os-bg::after {
|
|
|
|
|
width: 560px;
|
|
|
|
|
height: 560px;
|
|
|
|
|
bottom: -200px;
|
|
|
|
|
right: -160px;
|
|
|
|
|
background: radial-gradient(circle at 60% 60%, #A7F3D0 0%, #99F6E4 35%, transparent 70%);
|
|
|
|
|
animation: blobFloat 22s ease-in-out infinite alternate-reverse;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.os-bg > * {
|
|
|
|
|
position: relative;
|
|
|
|
|
z-index: 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes blobFloat {
|
|
|
|
|
0% { transform: translate(0, 0) scale(1); }
|
|
|
|
|
50% { transform: translate(30px, -20px) scale(1.05); }
|
|
|
|
|
100% { transform: translate(-20px, 25px) scale(0.98); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Gradient icon tile helpers */
|
|
|
|
|
.icon-tile {
|
|
|
|
|
display: inline-flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: center;
|
|
|
|
|
border-radius: 1rem;
|
2026-05-05 07:51:36 +00:00
|
|
|
box-shadow: 0 6px 18px rgba(11, 30, 63, 0.18);
|
2026-04-20 10:25:54 +00:00
|
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
|
|
|
}
|
|
|
|
|
.icon-tile:hover {
|
|
|
|
|
transform: translateY(-2px);
|
2026-05-05 07:51:36 +00:00
|
|
|
box-shadow: 0 10px 24px rgba(11, 30, 63, 0.22);
|
2026-04-20 10:25:54 +00:00
|
|
|
}
|
|
|
|
|
.icon-tile-blue { background: linear-gradient(135deg, #60A5FA, #3B82F6); }
|
|
|
|
|
.icon-tile-purple { background: linear-gradient(135deg, #C084FC, #8B5CF6); }
|
|
|
|
|
.icon-tile-green { background: linear-gradient(135deg, #34D399, #10B981); }
|
|
|
|
|
.icon-tile-orange { background: linear-gradient(135deg, #FDBA74, #F59E0B); }
|
|
|
|
|
.icon-tile-pink { background: linear-gradient(135deg, #F9A8D4, #EC4899); }
|
|
|
|
|
.icon-tile-teal { background: linear-gradient(135deg, #5EEAD4, #14B8A6); }
|
|
|
|
|
|
|
|
|
|
/* Top bar variant — flat very-light glass, no heavy border */
|
|
|
|
|
.topbar-glass {
|
|
|
|
|
background: rgba(255, 255, 255, 0.75);
|
|
|
|
|
backdrop-filter: blur(16px) saturate(160%);
|
|
|
|
|
-webkit-backdrop-filter: blur(16px) saturate(160%);
|
|
|
|
|
border-bottom: 1px solid rgba(226, 232, 240, 0.7);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Floating dock — macOS-like but lighter */
|
|
|
|
|
.dock-glass {
|
|
|
|
|
background: rgba(255, 255, 255, 0.65);
|
|
|
|
|
backdrop-filter: blur(20px) saturate(180%);
|
|
|
|
|
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
|
|
|
|
border: 1px solid rgba(226, 232, 240, 0.9);
|
|
|
|
|
box-shadow: 0 12px 40px rgba(15, 23, 42, 0.08);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Card hover lift */
|
|
|
|
|
.card-hover {
|
|
|
|
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
|
|
|
}
|
|
|
|
|
.card-hover:hover {
|
|
|
|
|
transform: translateY(-2px);
|
|
|
|
|
box-shadow: 0 14px 36px rgba(15, 23, 42, 0.08);
|
2026-04-20 09:20:50 +00:00
|
|
|
}
|
2026-04-20 12:33:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Animated login art — flowing gradient lines + drifting orbs */
|
|
|
|
|
.art-gradient {
|
|
|
|
|
background:
|
|
|
|
|
radial-gradient(60% 80% at 20% 20%, hsl(217 91% 30% / 0.55), transparent 70%),
|
|
|
|
|
radial-gradient(60% 80% at 80% 70%, hsl(262 83% 35% / 0.55), transparent 70%),
|
|
|
|
|
radial-gradient(50% 70% at 50% 100%, hsl(172 70% 30% / 0.45), transparent 70%),
|
|
|
|
|
linear-gradient(160deg, hsl(222 47% 8%), hsl(222 47% 14%));
|
|
|
|
|
animation: artBgShift 18s ease-in-out infinite alternate;
|
|
|
|
|
}
|
|
|
|
|
@keyframes artBgShift {
|
|
|
|
|
0% { filter: hue-rotate(0deg) saturate(1); }
|
|
|
|
|
100% { filter: hue-rotate(15deg) saturate(1.15); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.art-orb {
|
|
|
|
|
filter: blur(60px);
|
|
|
|
|
opacity: 0.55;
|
|
|
|
|
mix-blend-mode: screen;
|
|
|
|
|
will-change: transform;
|
|
|
|
|
}
|
|
|
|
|
.art-orb-a {
|
|
|
|
|
background: radial-gradient(circle, hsl(217 91% 60%), transparent 70%);
|
|
|
|
|
animation: artOrbFloatA 14s ease-in-out infinite alternate;
|
|
|
|
|
}
|
|
|
|
|
.art-orb-b {
|
|
|
|
|
background: radial-gradient(circle, hsl(262 83% 70%), transparent 70%);
|
|
|
|
|
animation: artOrbFloatB 17s ease-in-out infinite alternate;
|
|
|
|
|
}
|
|
|
|
|
.art-orb-c {
|
|
|
|
|
background: radial-gradient(circle, hsl(172 70% 55%), transparent 70%);
|
|
|
|
|
animation: artOrbFloatC 20s ease-in-out infinite alternate;
|
|
|
|
|
}
|
|
|
|
|
@keyframes artOrbFloatA {
|
|
|
|
|
0% { transform: translate(0, 0) scale(1); }
|
|
|
|
|
100% { transform: translate(80px, 60px) scale(1.15); }
|
|
|
|
|
}
|
|
|
|
|
@keyframes artOrbFloatB {
|
|
|
|
|
0% { transform: translate(0, 0) scale(1); }
|
|
|
|
|
100% { transform: translate(-60px, -50px) scale(1.1); }
|
|
|
|
|
}
|
|
|
|
|
@keyframes artOrbFloatC {
|
|
|
|
|
0% { transform: translate(0, 0) scale(1); }
|
|
|
|
|
100% { transform: translate(40px, -70px) scale(1.2); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.art-line {
|
|
|
|
|
stroke-dasharray: 600;
|
|
|
|
|
stroke-dashoffset: 600;
|
|
|
|
|
stroke-width: 2.5;
|
|
|
|
|
animation: artLineDraw 8s ease-in-out infinite;
|
|
|
|
|
filter: drop-shadow(0 0 8px hsl(217 91% 60% / 0.9));
|
|
|
|
|
}
|
|
|
|
|
.art-line-1 { animation-delay: 0s; }
|
|
|
|
|
.art-line-2 { animation-delay: 1.2s; }
|
|
|
|
|
.art-line-3 { animation-delay: 2.4s; }
|
|
|
|
|
.art-line-4 { animation-delay: 3.6s; }
|
|
|
|
|
.art-line-5 { animation-delay: 4.8s; }
|
|
|
|
|
@keyframes artLineDraw {
|
|
|
|
|
0% { stroke-dashoffset: 600; opacity: 0; }
|
|
|
|
|
20% { opacity: 1; }
|
|
|
|
|
60% { stroke-dashoffset: 0; opacity: 1; }
|
|
|
|
|
100% { stroke-dashoffset: -600; opacity: 0; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.art-particle {
|
|
|
|
|
position: absolute;
|
|
|
|
|
width: 4px;
|
|
|
|
|
height: 4px;
|
|
|
|
|
border-radius: 9999px;
|
|
|
|
|
background: white;
|
|
|
|
|
box-shadow: 0 0 12px 2px white;
|
|
|
|
|
opacity: 0;
|
|
|
|
|
animation: artParticleFloat 6s ease-in-out infinite;
|
|
|
|
|
}
|
|
|
|
|
@keyframes artParticleFloat {
|
|
|
|
|
0% { opacity: 0; transform: translateY(0) scale(0.8); }
|
|
|
|
|
50% { opacity: 0.9; transform: translateY(-30px) scale(1.1); }
|
|
|
|
|
100% { opacity: 0; transform: translateY(-60px) scale(0.8); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
|
|
|
.art-gradient,
|
|
|
|
|
.art-orb,
|
|
|
|
|
.art-line,
|
|
|
|
|
.art-particle {
|
|
|
|
|
animation: none !important;
|
|
|
|
|
}
|
|
|
|
|
.art-line { stroke-dashoffset: 0; opacity: 1; }
|
|
|
|
|
}
|
2026-04-21 17:39:31 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Hide scrollbars site-wide while keeping scroll functionality */
|
|
|
|
|
* {
|
|
|
|
|
scrollbar-width: none;
|
|
|
|
|
-ms-overflow-style: none;
|
|
|
|
|
}
|
|
|
|
|
*::-webkit-scrollbar {
|
|
|
|
|
width: 0;
|
|
|
|
|
height: 0;
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-30 06:39:46 +00:00
|
|
|
/*
|
|
|
|
|
* Prevent iOS Safari from auto-zooming the page when the user taps into
|
|
|
|
|
* a form field. iOS only triggers zoom when the focused control's
|
|
|
|
|
* computed font-size is < 16px, so we force a 16px minimum on iOS.
|
|
|
|
|
*
|
|
|
|
|
* Scoped via `@supports (-webkit-touch-callout: none)`, which is only
|
|
|
|
|
* true on iOS Safari (iPhone + iPad). Desktop, Android, and other
|
|
|
|
|
* browsers are unaffected, so visual typography is unchanged elsewhere.
|
|
|
|
|
*/
|
|
|
|
|
@supports (-webkit-touch-callout: none) {
|
|
|
|
|
input,
|
|
|
|
|
textarea,
|
|
|
|
|
select,
|
|
|
|
|
[contenteditable="true"] {
|
|
|
|
|
font-size: 16px !important;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 12:26:38 +00:00
|
|
|
/*
|
|
|
|
|
* #344: Attention-grabbing blink for the "starts in N minutes" headline
|
|
|
|
|
* inside the floating UpcomingMeetingAlert. Tailwind's `animate-pulse`
|
|
|
|
|
* only fades to opacity 0.5, which doesn't read as a true blink, so we
|
|
|
|
|
* ship a dedicated keyframe that drops to 0.15 and back. Respects the
|
|
|
|
|
* user's reduced-motion preference by stopping at full opacity.
|
|
|
|
|
*/
|
|
|
|
|
@keyframes em-blink {
|
|
|
|
|
0%, 100% { opacity: 1; }
|
|
|
|
|
50% { opacity: 0.15; }
|
|
|
|
|
}
|
|
|
|
|
.em-blink {
|
|
|
|
|
animation: em-blink 1s ease-in-out infinite;
|
|
|
|
|
}
|
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
|
|
|
.em-blink { animation: none; opacity: 1; }
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-03 15:55:29 +00:00
|
|
|
/*
|
|
|
|
|
* #350 (browser print): When the user prints the Executive Meetings
|
|
|
|
|
* schedule via the browser (Ctrl+P / "Save as PDF"), Chrome sometimes
|
|
|
|
|
* falls back to a system font that has Arabic glyphs but no GSUB
|
|
|
|
|
* shaping table. The result is Arabic text rendered as isolated,
|
|
|
|
|
* unconnected letterforms — and because the browser then runs the
|
|
|
|
|
* bidi algorithm on those isolated glyphs, the text appears reversed
|
|
|
|
|
* (e.g. "قائمة" prints as "ةمئاق").
|
|
|
|
|
*
|
2026-05-03 18:37:48 +00:00
|
|
|
* Fix: in print mode, force every element onto DIN Next LT Arabic
|
|
|
|
|
* (the app's primary Arabic font, which has a full GSUB shaping
|
|
|
|
|
* table). Combined with `font-display: block` in custom-fonts.css
|
|
|
|
|
* and `<link rel="preload">` in index.html, this ensures Chrome
|
|
|
|
|
* never falls back to a system font during the print snapshot. We
|
|
|
|
|
* also explicitly enable common-ligatures and contextual-alternates
|
|
|
|
|
* (`liga`, `calt`) which drive Arabic joining, and pin direction to
|
|
|
|
|
* RTL when the page is in Arabic so Chrome doesn't mis-resolve bidi
|
|
|
|
|
* for cells whose first glyph is Latin.
|
2026-05-03 15:55:29 +00:00
|
|
|
*/
|
|
|
|
|
@media print {
|
|
|
|
|
html, body, body * {
|
2026-05-03 18:37:48 +00:00
|
|
|
font-family: "DIN Next LT Arabic", sans-serif !important;
|
2026-05-03 15:55:29 +00:00
|
|
|
font-feature-settings: "liga" 1, "calt" 1, "rlig" 1 !important;
|
|
|
|
|
-webkit-font-feature-settings: "liga" 1, "calt" 1, "rlig" 1 !important;
|
|
|
|
|
text-rendering: optimizeLegibility;
|
|
|
|
|
}
|
|
|
|
|
html[dir="rtl"] #executive-schedule-printable {
|
|
|
|
|
direction: rtl;
|
|
|
|
|
unicode-bidi: isolate;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|