/* =============================================================================
   styles.css - fitlikemin.com

   THE IMPORTANT BIT
   -----------------
   Every height in this file comes from --vh, and --vh is written by app.js from
   window.innerHeight. Nothing here uses `100vh`.

   That is deliberate. The old version sized slides with `100vh` in CSS but
   calculated scroll offsets with window.innerHeight in JS. On Android those two
   numbers differ by the height of the browser address bar, and the error
   compounded once per slide. --vh gives CSS and JS one shared number, so they
   cannot drift apart.

   The `100vh` in the :root fallback below is only there for the split second
   before JS runs (and if JS fails entirely).
   ========================================================================== */

:root {
    --vh: 100vh;                    /* overwritten in px by app.js */
    --ink: #ffffff;
    --paper: #000000;
    --ink-muted: #666666;
    --ink-faint: #444444;
    --font-body: Arial, Helvetica, sans-serif;
    --font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

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

html,
body {
    height: 100%;
    background-color: var(--paper);
    color: var(--ink);
    font-family: var(--font-body);
    overflow: hidden;
    /* Stops Android/iOS bouncing the whole document behind our fixed layer. */
    overscroll-behavior: none;
    /* Keeps text size stable when an Android phone is turned sideways. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* -----------------------------------------------------------------------------
   Viewport - the window everything is seen through
   -------------------------------------------------------------------------- */

.viewport {
    position: fixed;
    inset: 0;
    height: var(--vh);
    overflow: hidden;
    /*
        touch-action: none tells the browser "I am handling all touch gestures
        here myself". This replaces the old global
        document.addEventListener('touchmove', e => e.preventDefault()) hack.
        Doing it declaratively lets our touch listeners stay passive, which is
        noticeably smoother on Android.
    */
    touch-action: none;
}

.track {
    position: absolute;
    inset: 0;
    /* transform is set from JS on every frame; no CSS transition, because the
       settle animation is driven by requestAnimationFrame instead. Relying on
       transitionend for state changes is a common source of stuck-state bugs
       on mobile. */
    will-change: transform;
}

/* -----------------------------------------------------------------------------
   Slides - exactly three, parked above / on / below the viewport
   -------------------------------------------------------------------------- */

.slide {
    position: absolute;
    left: 0;
    width: 100%;
    height: var(--vh);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 20px;
    /* Safe-area padding so words clear the notch and home indicator. */
    padding-top: env(safe-area-inset-top, 0px);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    opacity: 0;                     /* app.js cross-fades these */
}

.slide--prev { transform: translateY(calc(-1 * var(--vh))); }
.slide--curr { transform: translateY(0); }
.slide--next { transform: translateY(var(--vh)); }

/* -----------------------------------------------------------------------------
   The word itself
   -------------------------------------------------------------------------- */

.main-text {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    font-size: min(8vw, 3rem);
}

.word-container {
    position: relative;
    padding-bottom: 4rem;
}

.translation {
    position: absolute;
    left: 50%;
    bottom: 2rem;
    transform: translateX(-50%);
    font-size: min(3vw, 0.9rem);
    color: var(--ink-muted);
    font-style: italic;
    white-space: nowrap;
}

.pronunciation {
    position: absolute;
    left: 50%;
    bottom: 0.5rem;
    transform: translateX(-50%);
    font-size: min(2.5vw, 0.8rem);
    color: var(--ink-faint);
    font-family: var(--font-mono);
    white-space: nowrap;
}

/* Landscape: lay the word out on one line and tighten the vertical spacing. */
@media (orientation: landscape) {
    .main-text {
        font-size: min(6vh, 3rem);
        flex-direction: row;
    }

    .word-container { padding-bottom: 3rem; }

    .translation {
        font-size: min(2.5vh, 0.9rem);
        bottom: 1.5rem;
    }

    .pronunciation {
        font-size: min(2vh, 0.8rem);
        bottom: 0;
    }
}

/* -----------------------------------------------------------------------------
   Accessibility
   -------------------------------------------------------------------------- */

/* Keyboard users get a visible focus ring on the viewport. */
.viewport:focus-visible {
    outline: 2px solid var(--ink);
    outline-offset: -4px;
}

.noscript {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    text-align: center;
    font-size: 1.1rem;
}
