|
@@ -0,0 +1,164 @@
|
|
|
|
|
+/* ===========================================
|
|
|
|
|
+ VIEWPORT FITTING: MANDATORY BASE STYLES
|
|
|
|
|
+ Include this ENTIRE file in every presentation.
|
|
|
|
|
+ These styles ensure slides fit exactly in the viewport.
|
|
|
|
|
+ =========================================== */
|
|
|
|
|
+
|
|
|
|
|
+/* 1. Lock html/body to viewport */
|
|
|
|
|
+html, body {
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+html {
|
|
|
|
|
+ scroll-snap-type: y mandatory;
|
|
|
|
|
+ scroll-behavior: smooth;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 2. Each slide = exact viewport height */
|
|
|
|
|
+.slide {
|
|
|
|
|
+ width: 100vw;
|
|
|
|
|
+ height: 100vh;
|
|
|
|
|
+ height: 100dvh; /* Dynamic viewport height for mobile browsers */
|
|
|
|
|
+ overflow: hidden; /* CRITICAL: Prevent ANY overflow */
|
|
|
|
|
+ scroll-snap-align: start;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 3. Content container with flex for centering */
|
|
|
|
|
+.slide-content {
|
|
|
|
|
+ flex: 1;
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ max-height: 100%;
|
|
|
|
|
+ overflow: hidden; /* Double-protection against overflow */
|
|
|
|
|
+ padding: var(--slide-padding);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 4. ALL typography uses clamp() for responsive scaling */
|
|
|
|
|
+:root {
|
|
|
|
|
+ /* Titles scale from mobile to desktop */
|
|
|
|
|
+ --title-size: clamp(1.5rem, 5vw, 4rem);
|
|
|
|
|
+ --h2-size: clamp(1.25rem, 3.5vw, 2.5rem);
|
|
|
|
|
+ --h3-size: clamp(1rem, 2.5vw, 1.75rem);
|
|
|
|
|
+
|
|
|
|
|
+ /* Body text */
|
|
|
|
|
+ --body-size: clamp(0.75rem, 1.5vw, 1.125rem);
|
|
|
|
|
+ --small-size: clamp(0.65rem, 1vw, 0.875rem);
|
|
|
|
|
+
|
|
|
|
|
+ /* Spacing scales with viewport */
|
|
|
|
|
+ --slide-padding: clamp(1rem, 4vw, 4rem);
|
|
|
|
|
+ --content-gap: clamp(0.5rem, 2vw, 2rem);
|
|
|
|
|
+ --element-gap: clamp(0.25rem, 1vw, 1rem);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 5. Cards/containers use viewport-relative max sizes */
|
|
|
|
|
+.card, .container, .content-box {
|
|
|
|
|
+ max-width: min(90vw, 1000px);
|
|
|
|
|
+ max-height: min(80vh, 700px);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 6. Lists auto-scale with viewport */
|
|
|
|
|
+.feature-list, .bullet-list {
|
|
|
|
|
+ gap: clamp(0.4rem, 1vh, 1rem);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.feature-list li, .bullet-list li {
|
|
|
|
|
+ font-size: var(--body-size);
|
|
|
|
|
+ line-height: 1.4;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 7. Grids adapt to available space */
|
|
|
|
|
+.grid {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
|
|
|
|
|
+ gap: clamp(0.5rem, 1.5vw, 1rem);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 8. Images constrained to viewport */
|
|
|
|
|
+img, .image-container {
|
|
|
|
|
+ max-width: 100%;
|
|
|
|
|
+ max-height: min(50vh, 400px);
|
|
|
|
|
+ object-fit: contain;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===========================================
|
|
|
|
|
+ RESPONSIVE BREAKPOINTS
|
|
|
|
|
+ Aggressive scaling for smaller viewports
|
|
|
|
|
+ =========================================== */
|
|
|
|
|
+
|
|
|
|
|
+/* Short viewports (< 700px height) */
|
|
|
|
|
+@media (max-height: 700px) {
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --slide-padding: clamp(0.75rem, 3vw, 2rem);
|
|
|
|
|
+ --content-gap: clamp(0.4rem, 1.5vw, 1rem);
|
|
|
|
|
+ --title-size: clamp(1.25rem, 4.5vw, 2.5rem);
|
|
|
|
|
+ --h2-size: clamp(1rem, 3vw, 1.75rem);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Very short viewports (< 600px height) */
|
|
|
|
|
+@media (max-height: 600px) {
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --slide-padding: clamp(0.5rem, 2.5vw, 1.5rem);
|
|
|
|
|
+ --content-gap: clamp(0.3rem, 1vw, 0.75rem);
|
|
|
|
|
+ --title-size: clamp(1.1rem, 4vw, 2rem);
|
|
|
|
|
+ --body-size: clamp(0.7rem, 1.2vw, 0.95rem);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Hide non-essential elements */
|
|
|
|
|
+ .nav-dots, .keyboard-hint, .decorative {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Extremely short (landscape phones, < 500px height) */
|
|
|
|
|
+@media (max-height: 500px) {
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --slide-padding: clamp(0.4rem, 2vw, 1rem);
|
|
|
|
|
+ --title-size: clamp(1rem, 3.5vw, 1.5rem);
|
|
|
|
|
+ --h2-size: clamp(0.9rem, 2.5vw, 1.25rem);
|
|
|
|
|
+ --body-size: clamp(0.65rem, 1vw, 0.85rem);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Narrow viewports (< 600px width) */
|
|
|
|
|
+@media (max-width: 600px) {
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --title-size: clamp(1.25rem, 7vw, 2.5rem);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* Stack grids vertically */
|
|
|
|
|
+ .grid {
|
|
|
|
|
+ grid-template-columns: 1fr;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* ===========================================
|
|
|
|
|
+ REDUCED MOTION
|
|
|
|
|
+ Respect user preferences
|
|
|
|
|
+ =========================================== */
|
|
|
|
|
+@media (prefers-reduced-motion: reduce) {
|
|
|
|
|
+ *, *::before, *::after {
|
|
|
|
|
+ animation-duration: 0.01ms !important;
|
|
|
|
|
+ transition-duration: 0.2s !important;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ html {
|
|
|
|
|
+ scroll-behavior: auto;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* Large viewports (≥ 1600px — projectors, 4K displays) */
|
|
|
|
|
+@media (min-width: 1600px) {
|
|
|
|
|
+ :root {
|
|
|
|
|
+ --title-size: clamp(1.5rem, 5vw, 6rem);
|
|
|
|
|
+ --h2-size: clamp(1.25rem, 3.5vw, 3.5rem);
|
|
|
|
|
+ --h3-size: clamp(1rem, 2.5vw, 2.5rem);
|
|
|
|
|
+ --body-size: clamp(0.75rem, 1.5vw, 1.5rem);
|
|
|
|
|
+ --small-size: clamp(0.65rem, 1vw, 1.125rem);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|