/* introduction.html
   Same letter-hover system as letter-hover-responsive.html, restructured
   onto semantic h1/h2/h3/p elements instead of generic .line/#line-1-2-3
   divs. Font-sizes below never change per screen size. Fitting an element
   into a narrow viewport is handled by letting it wrap onto multiple rows
   via ordinary CSS text flow (white-space: normal + max-width below), not
   by shrinking anything -- every letter keeps its exact desktop size,
   weight, and spacing at every viewport width, continuously, with no JS
   sizing math and no breakpoints to tune. The JS groups each word's
   letters into an inline-block .word wrapper (so a word can't split
   mid-letter) and leaves real spaces as plain text between them, which is
   what gives the browser a place to wrap.

   Everything below used to be split between this file and an inline
   <style> block in introduction.html -- consolidated here so there's a
   single source of truth per selector (a duplicate rule split across two
   places risks the load-order/specificity trap that bit the old .line
   rule).

   SHARING THE PAGE. This is now the first screen of index.html, with the
   photos gallery below it (see site.css), which changes three things here:
   - What used to be body's rules are on .intro-screen, so the gallery's
     screen keeps its own font and layout.
   - Element rules (h1, h2, h3, p) are wrapped in :where(.intro-screen) so
     they can't reach the gallery's own <p>/<h2> elements. :where() adds
     no specificity, so every rule here still wins and loses exactly as
     it did before.
   - Sizes are px, not rem. The gallery's desktop scale (--desktop-scale
     in photos-style.css) works by shrinking the root font size, which
     would shrink every rem here too. Each px value is the exact rem it
     replaced at the browser's default 16px, so nothing moved. */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* same background as .page (not a visually distinct "desk") -- .page's
   8.5x11 sizing and 1in margins are structural only, invisible, just
   controlling where the text sits and wraps. The whole thing should read
   as one seamless background, not a page floating on a different surface. */
.intro-screen {
    display: flex;
    justify-content: center;
    align-items: flex-start; /* without this, flex's default (stretch) can pull .page taller than 11in on any viewport taller than that */
    /* 100dvh tracks the real visible height as iOS Safari's address bar
       shows and hides; 100vh is the bar-collapsed height. The vh line
       comes first as the fallback: a browser that doesn't know dvh drops
       the second declaration and keeps the first. Same as photos-style.css. */
    min-height: 100vh;
    min-height: 100dvh;
    background: #ffffff; /* matches taliacotton.com/#bio -- pure white, not the previous off-white */
    font-family: Georgia, 'Times New Roman', Times, serif;
    /* The browser's default 16px, set here rather than inherited: on
       desktop the root font size is scaled down for the gallery (see the
       SHARING THE PAGE note above), and anything left inheriting it --
       the <br> gaps between paragraphs size off it -- would shrink. */
    font-size: 16px;
    /* the 48px top/bottom gap, plus the safe-area insets that
       viewport-fit=cover (index.html) leaves to the page: notch
       and status bar on top, home indicator below, and the notch side in
       landscape. Every inset is 0 on desktop and on phones without a
       notch, so this collapses to plain 48px / 0 there. Added here,
       outside .page, so .page's min()/clamp() sizing stays untouched. */
    padding-top: calc(48px + env(safe-area-inset-top, 0px));
    padding-bottom: calc(48px + env(safe-area-inset-bottom, 0px));
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
}

/* an 8.5in-wide sheet with a document-style 1in top/side margin -- but
   NOT an 11in-tall one: that forced a full sheet's worth of empty space
   below short content. Dropped the aspect-ratio that produced that; the
   page now just ends naturally after its content, closer to normal
   desktop proportions, with a modest close instead of a full page's
   worth of trailing blank space. Top/sides unchanged from before.

   width and the top/side padding are still continuous functions of the
   viewport width rather than a fixed value that snaps at a breakpoint --
   there's no single pixel where either jumps, at any screen size:

   - width: min(8.5in, 100%) shrinks the page fluidly once the viewport
     drops under 8.5in (816px), instead of a hard max-width override.
   - padding-top/padding-inline use clamp() to interpolate smoothly
     between a 20px floor (comfortable on the smallest phones) and
     the full 1in ceiling -- reached almost exactly at 816px, the same
     width where the page itself stops shrinking, so nothing here is
     out of step with it. */
.page {
    width: min(8.5in, 100%);
    padding-top: clamp(20px, -44.8px + 17.2vw, 1in);
    padding-inline: clamp(20px, -44.8px + 17.2vw, 1in);
    padding-bottom: 48px; /* a normal close, not a full 11in sheet's worth of trailing space */
    display: flex;
    flex-direction: column;
    align-items: flex-start; /* left-justifies the whole block, not just text within it */
    /* side breathing room so letters/photo never sit flush against the
       screen edge on a phone, and a safety net against horizontal scroll */
    overflow-x: hidden;
}

:where(.intro-screen) h1,
:where(.intro-screen) h2,
:where(.intro-screen) h3,
:where(.intro-screen) p {
    white-space: normal; /* allow wrapping between words (not within one -- see .word) */
    max-width: 100%; /* forces a wrap once content would otherwise overflow the element's box */
    text-align: left; /* keeps wrapped rows left-justified, matching the unwrapped look */
    /* fixed line-height so a substituted emoji font's own metrics can't
       stretch any wrapped row's height and shift its letters' baseline --
       that vertical nudge is what read as a "shake" alongside the old
       horizontal one */
    line-height: 1;
    font-weight: normal; /* neutralize each tag's default browser bold/size before setting our own below */
}

/* every element initLetterHover has split into letters (class added in
   script.js). touch-action: none hands a finger drag that starts on the
   text to the touchmove tracking instead of scrolling the page, so
   sliding a finger over it sweeps letters the way a mouse does -- the
   page still scrolls from a drag that starts anywhere else. Set on the
   whole block, not each .letter, so the gaps between words and lines
   behave the same. Selection and the iOS long-press callout are off too,
   or holding a finger still would start selecting text mid-sweep. */
.letter-hover {
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.word {
    display: inline-block; /* a word's own letters never split across a wrap */
    white-space: nowrap;
    vertical-align: top; /* matches .letter's alignment, so it lines up with the space text between words */
}

.letter {
    display: inline-block;
    text-align: center;
    line-height: 1;
    vertical-align: top; /* alignment independent of each glyph's own metrics */
    overflow: visible; /* let a wider/scaled emoji spill past its pinned box without affecting layout */
    cursor: default;
    transform-origin: center center; /* scale grows evenly from the letter's middle */
    /* translate/rotate/scale as independent CSS properties (not one
       combined `transform`) so each can have its own transition below --
       specifically so scale can be excluded and snap instantly */
    translate: 0 0;
    rotate: 0deg;
    scale: 1;
    /* fast snap-back with just a touch of ease-out -- close to constant
       speed, not a dramatic curve, just enough to soften the stop.
       Only translate is listed here: scale and rotate are deliberately
       left out, so the letter reappears at its normal size and
       completely upright the instant the emoji is gone, instead of
       still shrinking down or un-tilting afterward -- only its
       position keeps gliding back. */
    transition: translate 0.45s cubic-bezier(0.3, 0.1, 0.3, 1);
}

/* while floating, JS sets transform/filter/opacity directly on every
   animation frame (60fps), so no CSS transition should fight those
   per-frame values -- that's what makes the drift read as one
   continuous motion instead of the browser chasing a new target
   every time a transition fires. The bouncy spring transition above
   only applies again once this class comes off, for the snap-back.
   will-change hints the browser to put this element on its own
   compositor layer for the duration of the float (cheaper transform
   updates every frame); scoped to .floating only, so it's not paying
   for a promoted layer on every idle letter on the page, and comes off
   automatically the instant the class does, right before the snap-back.

   Known trade-off, kept on purpose: iOS Safari sizes that layer to the
   letter's box, not to where the glyph paints, so h1/h2 emoji (which
   rise ~0.25em above their box in Plate Gothic) get their tops cropped
   a little on an iPhone. Dropping will-change -- and switching .page's
   overflow-x to clip -- fixed the crop but made every float stutter in
   desktop Chrome. Smooth everywhere beats uncropped on one browser. */
.letter.floating {
    transition: none;
    will-change: transform;
}

/* red squiggly underline, like Word's spellcheck/hyperlink flag --
   placeholder to mark a word as "this will be a link" */
.link-hint {
    text-decoration-line: underline;
    text-decoration-style: wavy;
    text-decoration-color: red;
    text-decoration-thickness: 1.5px;
    text-underline-offset: 0.5px; /* tight to the letters -- 3px was reaching down into the next wrapped line */
}

/* no squiggle under the emoji while it's out -- only the letter carries it.
   An image emoji never showed one (an <img> takes no text-decoration), but
   a character emoji (#portfolio's 🔥/🎬) is text, so it drew one too.
   .floating is on the letter from the swap until the snap back. */
.link-hint.floating {
    text-decoration-line: none;
}

/* wraps hyperlinked target phrases -- reset the browser's default blue
   link color/underline so it doesn't fight the letter-hover styling or
   the .link-hint squiggle, and restore a pointer cursor since .letter
   explicitly sets cursor: default (an inherited value never overrides
   an element's own explicit declaration) */
.letter-link {
    color: inherit;
    text-decoration: none;
}
.letter-link .letter {
    cursor: pointer;
}

/* sizes are identical at every screen size -- narrow screens wrap onto
   more rows instead of shrinking. */
/* letterhead lines in Plate Gothic (MyWebfontsKit/), falling back to the
   body's Georgia while it loads */
:where(.intro-screen) h1,
:where(.intro-screen) h2 {
    font-family: "PlateGothicThreeFourRegular", Georgia, serif;
}

/* h1 and h2 both 24px -- keep both, and h2's pull-up, to whole-pixel
   sizes. With line-height: 1, a fractional one (1.3rem = 20.8px) shifts
   everything below onto a sub-pixel row, which breaks up the per-letter
   .link-hint squiggles */
:where(.intro-screen) h1 {
    font-size: 24px;
    margin-bottom: 0; /* no gap before h2 */
}

:where(.intro-screen) h2 {
    font-size: 24px;
    margin-top: -6px; /* tucks it up under h1 -- the caps-only font leaves an empty descender band below h1 */
    margin-bottom: 0;
}

:where(.intro-screen) h3 {
    font-size: 48px;
    margin-bottom: 32px;
}

:where(.intro-screen) p {
    /* same stack as the photos section's sidebar (.photos-screen in photos-style.css):
       San Francisco on Apple devices, the system UI font elsewhere */
    font-family: -apple-system, "SF Pro", "SF Pro Display", "SF Pro Text", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
    font-size: 14px; /* the photos sidebar items' size (before its desktop scale); whole pixels, see h1/h2 */
    margin-bottom: 0;
}

/* no @media breakpoint needed anymore for .page's sizing -- width,
   aspect-ratio, and padding above are all continuous functions of
   viewport width (see the comment on .page), so there's nothing here
   left to override at a fixed cutoff. */
