mobile h2 + sky wheel landscape fit: per-letter flex spread (justify-content: space-between via base.html JS letter-splitter) replaces text-justify: inter-character — iOS Safari + Firefox silently fall back to inter-word for Latin text, leaving letters clustered at the slot start; flex layout works everywhere; viewport-fluid font clamp(1.3rem, 5vw, 2rem) portrait + clamp(1.2rem, 4.4vh, 2.75rem) landscape so glyphs scale w. viewport instead of a fixed-rem ceiling that overflowed the 45/55 slot at the rem-clamp floor; portrait <500px gets padding-inline 0.4em→0.6em on the word-spans so H-B don't run together at the cramped font-size; .sky-page post-save scroll-snap sections pinned to height: 100% (was: min-height: 100%) + .sky-svg max-height: 100% so the wheel fits exactly one aperture on landscape mobile (was: 480px max blew past ~350px aperture, leaving an intermediate scroll position)
Code architected by Disco DeDisco <discodedisco@outlook.com> Git commit message Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -210,10 +210,20 @@ body {
|
||||
var(--title-shadow-offset) var(--title-shadow-offset) 0 rgba(0, 0, 0, 0.8)
|
||||
;
|
||||
|
||||
// Each word-span hosts per-letter <span>s injected by the
|
||||
// h2-letter-split script in base.html — display: flex +
|
||||
// justify-content: space-between distributes those letters
|
||||
// across the slot's width (or height in landscape's
|
||||
// writing-mode: vertical-rl). text-justify: inter-character
|
||||
// would do the same in pure CSS, but iOS Safari + Firefox
|
||||
// silently fall back to inter-word for Latin scripts, which
|
||||
// can't split a single word — letters end up clustered at
|
||||
// the slot's start with empty space trailing. The flex
|
||||
// approach works everywhere.
|
||||
> span {
|
||||
text-align: justify;
|
||||
text-align-last: justify;
|
||||
text-justify: inter-character;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
// Padding-inline (logical) creates the natural visual gap
|
||||
@@ -365,8 +375,14 @@ body {
|
||||
height: 80vh; // explicit height so the flex 45/55 % basis resolves
|
||||
transform: translateY(-50%) rotate(180deg);
|
||||
writing-mode: vertical-rl; // inline axis becomes top-to-bottom; flex stacks on it
|
||||
font-size: 3rem; // rem-fluid → no min-height jumps
|
||||
letter-spacing: 0.4em;
|
||||
// Per-letter flex spread (justify-content: space-between on each word
|
||||
// span) fills the slot regardless of font-size, so we only need to
|
||||
// cap font-size by vh so each letter glyph stays smaller than slot /
|
||||
// letter-count. Worst case: HOWDY STRANGER (8ch second word) in 55%
|
||||
// of 80vh on a 375-tall iPhone SE landscape → 165px slot ÷ 8 ≈ 20px
|
||||
// max glyph height; clamp's 4.4vh + 1.2rem floor gives 16.5–16.8px
|
||||
// at that viewport, well under 20.
|
||||
font-size: clamp(1.2rem, 4.4vh, 2.75rem);
|
||||
margin: 0;
|
||||
z-index: 85;
|
||||
pointer-events: none;
|
||||
@@ -476,16 +492,20 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
// Per-letter flex spread fills each 45/55 slot regardless of font-size,
|
||||
// so we just need to cap the glyph size by viewport width to keep the
|
||||
// worst-case title (HOWDY STRANGER, 8ch second word) from clipping at
|
||||
// tiny mobile widths. clamp picks max(1.3rem, 5vw) capped at 2rem —
|
||||
// at 320w → 18.2px, 390w → 19.5px, 430w → 21.5px.
|
||||
// padding-inline boundary bumped from 0.4em → 0.6em (each side) so the
|
||||
// last letter of word 1 (H) and first letter of word 2 (B) don't run
|
||||
// together at the cramped portrait font-size.
|
||||
.row .col-lg-6 h2 {
|
||||
text-align: center;
|
||||
text-align-last: center;
|
||||
letter-spacing: 0.33em;
|
||||
margin: 0;
|
||||
font-size: 2rem;
|
||||
font-size: clamp(1.3rem, 5vw, 2rem);
|
||||
|
||||
&#id_dash_wallet {
|
||||
letter-spacing: 0.25em;
|
||||
}
|
||||
> span:first-child { padding-inline-end: 0.6em; }
|
||||
> span:last-child { padding-inline-start: 0.6em; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1089,18 +1089,32 @@ body.sky-saved {
|
||||
.sky-page .sky-form-col {
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
min-height: 100%;
|
||||
// height (not min-height) pins each section to EXACTLY one aperture so
|
||||
// the snap-stops land at integer multiples of the viewport. min-height
|
||||
// alone let .sky-svg's 480px max-height push the wheel section past one
|
||||
// viewport on landscape mobile (~350px aperture), which created an
|
||||
// intermediate scroll position between the wheel-end and the form-start.
|
||||
height: 100%;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
// Release the wheel-col aspect-ratio cap so the section fills the aperture;
|
||||
// .sky-svg inside still renders square (its own aspect-ratio:1/1) and stays
|
||||
// centered via the col's align-items:center.
|
||||
// centered via the col's align-items:center. max-height: 100% caps the SVG
|
||||
// to the aperture height — without it the .sky-svg's 480px max-* would let
|
||||
// the wheel render taller than the section, overflowing into the form-col
|
||||
// on cramped landscape phones.
|
||||
.sky-page .sky-wheel-col {
|
||||
aspect-ratio: auto;
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
max-height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.sky-svg {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
// form-col loses its grow/min-height fill so the snap basis (min-height:100%
|
||||
|
||||
@@ -74,6 +74,32 @@
|
||||
{% block scripts %}
|
||||
{% endblock scripts %}
|
||||
<script>
|
||||
// h2 letter splitter — wrap each character of every .row .col-lg-6 h2
|
||||
// word-span in its own <span> so .scss can use justify-content:
|
||||
// space-between to fill the 45/55 slot. text-justify: inter-character
|
||||
// would do this in pure CSS but iOS Safari + Firefox silently fall
|
||||
// back to inter-word for Latin text, leaving letters clustered at the
|
||||
// slot's start.
|
||||
(function () {
|
||||
var spans = document.querySelectorAll('.row .col-lg-6 h2 > span');
|
||||
for (var i = 0; i < spans.length; i++) {
|
||||
var span = spans[i];
|
||||
if (span.dataset.lettersSplit === '1') continue;
|
||||
var text = (span.textContent || '').trim();
|
||||
if (!text) continue;
|
||||
span.dataset.lettersSplit = '1';
|
||||
span.setAttribute('aria-label', text);
|
||||
span.textContent = '';
|
||||
for (var j = 0; j < text.length; j++) {
|
||||
var letter = document.createElement('span');
|
||||
letter.setAttribute('aria-hidden', 'true');
|
||||
letter.textContent = text[j];
|
||||
span.appendChild(letter);
|
||||
}
|
||||
}
|
||||
}());
|
||||
</script>
|
||||
<script>
|
||||
(function () {
|
||||
var portal = null;
|
||||
var _cb = null;
|
||||
|
||||
Reference in New Issue
Block a user