/* ============================================================================
   Shared site styles: accessibility primitives + the mobile shell.

   Loaded by every page (hub, guides, tutorial viewer) alongside theme.js and
   nav.js. Bump the ?v= query in each page's <link> whenever this file changes,
   same convention as hub.js / theme.js.

   This file is deliberately plain CSS, not Tailwind: it loads synchronously,
   so the rules here are in effect BEFORE the Tailwind Play CDN has compiled
   anything. That matters for the drawer — see "Pre-paint drawer guard" below.
   ============================================================================ */

/* Stop iOS from inflating text when the device rotates to landscape. */
html {
    -webkit-text-size-adjust: 100%;
}

/* ---------------------------------------------------------------------------
   Skip link — visually hidden until focused.
   --------------------------------------------------------------------------- */
.skip-link {
    position: absolute;
    top: -100px;
    left: 1rem;
    background: #4f46e5;
    color: #fff;
    padding: 0.5rem 1rem;
    border-radius: 0.375rem;
    z-index: 100;
    font-weight: 600;
    transition: top 150ms;
}

.skip-link:focus {
    top: 1rem;
    outline: none;
}

/* ---------------------------------------------------------------------------
   Focus-visible ring for keyboard users, site-wide.
   --------------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
input:focus-visible,
summary:focus-visible {
    outline: none;
    box-shadow: 0 0 0 2px #fff, 0 0 0 4px #6366f1;
    border-radius: 0.5rem;
}

html.dark a:focus-visible,
html.dark button:focus-visible,
html.dark input:focus-visible,
html.dark summary:focus-visible {
    box-shadow: 0 0 0 2px #111827, 0 0 0 4px #818cf8;
}

/* ---------------------------------------------------------------------------
   Mobile drawer.

   nav.js toggles a single `is-open` class on the panel and the backdrop.
   Below lg this file owns the panel's position; at lg and above the markup's
   Tailwind utilities take over and the panel is a static column again.
   --------------------------------------------------------------------------- */

/* Below lg the drawer is owned entirely by this file, not by Tailwind utility
   classes. Two reasons: the Tailwind CDN compiles asynchronously, so utilities
   are not in effect on first paint and the panel would flash across the
   article; and `visibility` has to be part of the transition so a closed
   drawer is genuinely out of the tab order rather than merely off-screen.
   The markup carries only the desktop layout (lg:static, lg:w-80, ...). */
@media (max-width: 1023.98px) {
    aside[data-drawer] {
        position: fixed;
        top: 0;
        bottom: 0;
        left: 0;
        transform: translateX(-100%);
        visibility: hidden;
        overflow-y: auto;
        transition: transform 300ms ease, visibility 0s linear 300ms;
    }

    aside[data-drawer].is-open {
        transform: translateX(0);
        visibility: visible;
        transition: transform 300ms ease, visibility 0s;
    }
}

#drawer-backdrop {
    opacity: 0;
    pointer-events: none;
    transition: opacity 300ms ease;
}

#drawer-backdrop.is-open {
    opacity: 1;
    pointer-events: auto;
}

/* Lock the page behind an open drawer so the article does not scroll under it. */
body.drawer-open {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    aside[data-drawer],
    #drawer-backdrop {
        transition: none !important;
    }
}

/* ---------------------------------------------------------------------------
   Touch targets. WCAG 2.2 AA (2.5.8) asks 24px; Apple and Google both ask 44.
   Applied below lg only, so desktop density is unchanged.
   --------------------------------------------------------------------------- */
@media (max-width: 1023.98px) {
    aside[data-drawer] nav a,
    aside[data-drawer] .lesson-link,
    aside[data-drawer] .page-link {
        min-height: 44px;
        display: flex;
        align-items: center;
    }
}

/* ---------------------------------------------------------------------------
   Form controls: anything under 16px makes iOS Safari zoom the viewport on
   focus, and it does not zoom back out on blur.
   --------------------------------------------------------------------------- */
@media (max-width: 640px) {
    input,
    select,
    textarea {
        font-size: 16px;
    }
}

/* Secondary prose (hub card blurbs, the refresher guides' intro paragraphs) is
   authored at text-sm / 14px, which is fine on a desktop but small for grey body
   copy on a phone. Nudge it up below sm; desktop typography is unchanged. */
@media (max-width: 640px) {
    main p.text-sm {
        font-size: 0.9375rem;
        line-height: 1.6;
    }
}

/* ---------------------------------------------------------------------------
   Wide content inside rendered Markdown: tables, diagrams, images.
   --------------------------------------------------------------------------- */

/* tutorial.html wraps every rendered <table> in this at render time. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    margin: 1.5rem 0;
}

.table-scroll > table {
    margin: 0 !important;
    min-width: 34rem;
}

@media (max-width: 640px) {
    #content th,
    #content td {
        padding: 0.45rem 0.6rem;
    }
}

/* Prism's stylesheet only makes `pre[class*="language-"]` scrollable. A fenced
   block with no language tag — ASCII diagrams, plain program output, the
   financial statements in the valuation deep dive — produces a bare
   `<pre><code>`, matches nothing, and pushes the whole page sideways on a
   phone. Give every code block its own scroller. */
#content pre,
main pre {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

/* Monospace at 14px runs wide on a 360px screen; a notch smaller fits more of
   an ASCII table before the reader has to scroll it. */
@media (max-width: 640px) {
    #content pre {
        font-size: 0.8125rem;
    }
}

/* Mermaid: scroll a wide diagram rather than shrinking it to illegibility.
   `margin: 0 auto` on a block child centres it when it fits and collapses to
   zero when it overflows, so the diagram starts flush left and scrolls. */
.mermaid {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.mermaid > svg {
    display: block;
    margin: 0 auto;
}

/* Mermaid 10 bakes `max-width` onto the SVG (useMaxWidth), which on a phone
   scales a complex diagram down until the labels are unreadable. Below lg,
   let it render at natural size inside the scroller instead. */
@media (max-width: 1023.98px) {
    .mermaid > svg {
        max-width: none !important;
    }
}

/* Reserve space for tutorial slide images so they do not shift the page as
   they lazy-load. A lazy image has no intrinsic size until it arrives, so
   `width` has to be explicit — with `width: auto` the box computes to zero and
   the aspect-ratio reserves nothing. Every image in tutorials/ today is a
   full-bleed 1376x768 slide, so 100% is the right width for all of them; the
   cost is that a small inline image would be upscaled.

   tutorial.html clears the placeholder ratio once each image loads (see
   adaptForSmallScreens), after which the file's own ratio governs and nothing
   can be distorted. */
#content img {
    width: 100%;
    height: auto;
    aspect-ratio: 1376 / 768;
}

/* ---------------------------------------------------------------------------
   In-page anchors must clear the sticky mobile top bar (h-14 = 3.5rem),
   otherwise a jump-nav link parks its heading underneath it. Only below lg,
   where that bar exists.
   --------------------------------------------------------------------------- */
@media (max-width: 1023.98px) {
    :target,
    section[id],
    main [id] {
        scroll-margin-top: 4.5rem;
    }

    html {
        scroll-behavior: smooth;
    }
}

/* ---------------------------------------------------------------------------
   Hub: fade the right edge of the sticky category pills so it reads as
   scrollable when the row is wider than the screen.
   --------------------------------------------------------------------------- */
.scroll-fade {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent 100%);
}

@media (min-width: 1024px) {
    .scroll-fade {
        -webkit-mask-image: none;
        mask-image: none;
    }
}
