diff --git a/SKILL.md b/SKILL.md index 37d3073d..c117df8f 100644 --- a/SKILL.md +++ b/SKILL.md @@ -310,6 +310,7 @@ Before writing any HTML, analyze the content and plan each slide. For each slide - Add detailed comments explaining each section - Every section needs a clear `/* === SECTION NAME === */` comment block - **Always generate speaker notes** — see Speaker Notes below +- Portrait phones are handled by the reflow block in components.css, which collapses multi-column components to a single column so the deck adapts in place. The optional `.rotate-hint` overlay is only for decks you intentionally author landscape only. Add a `
` with generic prompt text when you want to ask the viewer to turn the device, and leave it out otherwise. It is CSS-only and clears itself on rotation to landscape. ### Speaker Notes (Mandatory) diff --git a/assets/components.css b/assets/components.css index d9ab5b90..b5c2f312 100644 --- a/assets/components.css +++ b/assets/components.css @@ -665,3 +665,43 @@ h2 { font-size: clamp(28px,3.5vw,48px); font-weight: 800; line-height: 1.15; let color: var(--text-muted); max-width: 640px; margin-top: clamp(6px, 1vh, 12px); } + +/* ====== PORTRAIT REFLOW ====== */ +/* Landscape-composed decks degrade to one column on narrow phones. + Reflowing the columns keeps the .slide { overflow: hidden } no-scroll + invariant intact, where forcing scroll would break it. */ +@media (max-width: 700px) { + .flip-grid, + .use-case-grid { + grid-template-columns: 1fr; + } + .arch-flow, + .stats-row, + .vs-container, + .auth-compare, + .fullstack-bar { + flex-direction: column; + } + /* The arrow sits horizontal by default. Rotate it a quarter turn so it + points down between the now-stacked architecture boxes. */ + .arch-arrow { + transform: rotate(90deg); + } +} + +/* ====== ROTATE HINT (opt-in) ====== */ +/* CSS-only affordance for decks that are intentionally landscape only. + Hidden by default. The portrait, narrow-width query below reveals it, + so rotating the device back to landscape clears it with no JavaScript. */ +.rotate-hint { + display: none; + position: fixed; inset: 0; z-index: 9999; + flex-direction: column; align-items: center; justify-content: center; + gap: 16px; padding: 32px; text-align: center; + background: var(--bg, #000); color: var(--text, #fff); + font-size: clamp(16px, 4vw, 22px); font-weight: 600; +} +.rotate-hint-icon { font-size: clamp(40px, 12vw, 64px); } +@media (orientation: portrait) and (max-width: 700px) { + .rotate-hint { display: flex; } +} diff --git a/assets/viewport-base.css b/assets/viewport-base.css index 67290b5e..43fc9343 100644 --- a/assets/viewport-base.css +++ b/assets/viewport-base.css @@ -45,9 +45,11 @@ html { --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); + /* Body text. The clamp minimums are floored at a legible size, because an + honest overflow the author then splits is better than text that shrinks + past readability. Preferred and max values are unchanged. */ + --body-size: clamp(1rem, 1.5vw, 1.125rem); + --small-size: clamp(0.8125rem, 1vw, 0.875rem); /* Spacing scales with viewport */ --slide-padding: clamp(1rem, 4vw, 4rem); diff --git a/references/presentation-layer.md b/references/presentation-layer.md index b74a593f..dae11e76 100644 --- a/references/presentation-layer.md +++ b/references/presentation-layer.md @@ -85,6 +85,8 @@ Each slide must fit exactly within 100vh. No scrolling, ever. Content exceeds limits? Split into multiple slides. Never cram, never scroll. +**Density tiering and the legible floor:** the clamp minimums on body and small text in `viewport-base.css` are floored at a readable size, so text holds a legible floor instead of shrinking out of sight on a small or projected viewport. When a slide would breach that floor it overflows, which is the signal to split it rather than pack it tighter. This is the same projection-readability constraint documented for diagram text in [libraries.md](libraries.md) (the 18px Mermaid `fontSize` floor). Pick a density tier per slide so every component clears the floor at the smallest viewport the deck will run on. + ## Navigation Requirements The presentation must support: