/* Stylesheet for the VitePress-style landing page rendered by
 * DocumenterLandingPage.jl.
 *
 * Theming is theme-adaptive: the landing components consume only the CSS
 * custom properties below, and the `html.theme--<name>` blocks mirror
 * Documenter's own SCSS palette for each of its six shipped themes
 * (documenter-light, documenter-dark, and the four catppuccin flavors), so
 * the landing page follows the visitor's theme with no custom palette of its
 * own. Values are transcribed from Documenter's theme SCSS:
 *
 *   - `--landing-surface`:   `$background`       (tiles, alt buttons)
 *   - `--landing-surface-2`: one step further     (icon badges)
 *   - `--landing-border`:    a step between       (tile borders)
 *   - `--landing-accent`:    `$link`              (name, brand button)
 *   - `--landing-accent-contrast`: text on the brand button
 *   - `--landing-glow`:      the logo's blurred glow disc, accent hue (~45% alpha)
 *
 * Text and headings are deliberately left to inherit from the theme; nothing
 * here overrides Documenter's own chrome.
 */

:root {
    --landing-surface: #f5f5f5;
    --landing-surface-2: #dbdee0;
    --landing-border: #e0e0e0;
    --landing-accent: #2e63b8;
    --landing-accent-contrast: #fff;
    --landing-glow: rgba(46, 99, 184, 0.45);
}

html.theme--documenter-dark {
    --landing-surface: #282f2f;
    --landing-surface-2: #343c3d;
    --landing-border: #343c3d;
    --landing-accent: #1abc9c;
    --landing-accent-contrast: #00332a;
    --landing-glow: rgba(26, 188, 156, 0.45);
}

html.theme--catppuccin-latte {
    --landing-surface: #e6e9ef;
    --landing-surface-2: #bcc0cc;
    --landing-border: #ccd0da;
    --landing-accent: #1e66f5;
    --landing-accent-contrast: #fff;
    --landing-glow: rgba(30, 102, 245, 0.42);
}

html.theme--catppuccin-frappe {
    --landing-surface: #292c3c;
    --landing-surface-2: #51576d;
    --landing-border: #414559;
    --landing-accent: #8caaee;
    --landing-accent-contrast: #303446;
    --landing-glow: rgba(140, 170, 238, 0.42);
}

html.theme--catppuccin-macchiato {
    --landing-surface: #1e2030;
    --landing-surface-2: #494d64;
    --landing-border: #363a4f;
    --landing-accent: #8aadf4;
    --landing-accent-contrast: #24273a;
    --landing-glow: rgba(138, 173, 244, 0.42);
}

html.theme--catppuccin-mocha {
    --landing-surface: #181825;
    --landing-surface-2: #45475a;
    --landing-border: #313244;
    --landing-accent: #89b4fa;
    --landing-accent-contrast: #1e1e2e;
    --landing-glow: rgba(137, 180, 250, 0.42);
}

/* The landing page spans the same content width as a VitePress home layout
 * (Documenter caps the content column at 52rem; the VitePress home container
 * is 72rem). The theme files scope their rules under html.theme--<name>, so
 * these selectors carry the same specificity to win regardless of order. */
body:has(#landing) #documenter .docs-main,
body:has(#landing) #documenter .docs-main > article {
    max-width: 72rem;
}

/* Everything below sizes the hero against the landing column itself, not the
 * viewport. This matters because the two are not proportional: Documenter's
 * own chrome flips its sidebar on at 1056px, which steps the content column
 * down by 320px in a single pixel of resize (below it the column is the full
 * viewport minus padding; above it the sidebar claims 20rem plus a 1rem
 * gutter), and caps it at the 72rem above. Viewport-keyed sizes (vw units,
 * @media) are blind to all three facts: they kept growing while the column
 * was capped and jumped while the type did not, which is what made the hero
 * reflow abruptly and the name wrap mid-range. A container query makes the
 * column the single reference frame: every fluid size below is expressed in
 * cqi (1% of the column's inline size) and every breakpoint is a
 * @container condition, so the hero scales proportionally with the space it
 * actually has — the sidebar flip becomes one coherent zoom instead of a
 * re-wrap. Container queries are supported by every browser that already
 * renders this sheet (it already depends on :has() above), so this adds no
 * new compatibility requirement. */
#landing {
    container-type: inline-size;
}

/* ---- Hero: two columns, text left, logo right, vertically centered ---- */
#landing .landing-hero {
    display: flex;
    align-items: center;
    gap: 4rem;
    padding: 2rem 0 2.5rem;
    /* Deliberately no overflow clipping: the glow below spills past its box
     * over the surrounding page (its blur is ink overflow, like a
     * box-shadow, and can never widen the page), and clipping here would
     * slice that halo flat. The one thing that must not spill — the
     * no-wrap name — is clipped inside the text column below. */
}
#landing .landing-hero__text {
    flex: 0 1 58%;
    min-width: 0;
    /* The hero's only overflow guard: an extreme no-wrap package name is
     * clipped at its column's edge instead of pushing the page wider
     * (content overflow scrolls; ink overflow does not). */
    overflow-x: clip;
}
#landing .landing-name {
    margin: 0 0 0.75rem;
    /* Scaled by the column (4cqi), capped at the VitePress desktop size.
     * `nowrap` makes the single-line name a hard invariant instead of the
     * old tuned vw ramp, which only kept a specific name on one line by
     * coincidence. The math: the text column is ~58% of the landing column,
     * and at 4cqi a bold name of ~24 characters spans ~46% of it — so the
     * name stays on one line at *every* two-column width, growing and
     * shrinking exactly with the column. Longer names shrink toward the
     * 1.5rem floor rather than wrap; the floor fits ~26 characters even at
     * the narrowest stacked width. */
    font-size: clamp(1.5rem, 4cqi, 3.25rem);
    font-weight: 700;
    line-height: 1.15;
    color: var(--landing-accent);
    white-space: nowrap;
}
#landing .landing-title {
    margin: 0 0 1.25rem;
    /* The ramps below interpolate between the same anchors the old vw clamps
     * were tuned to — 2rem at the stacking width, 3.25rem at the 72rem column
     * cap — but keyed to the column, so the step is continuous through every
     * viewport flip and stops growing when the column stops. */
    font-size: clamp(2rem, calc(3.906cqi + 7px), 3.25rem);
    font-weight: 700;
    line-height: 1.15;
}
#landing .landing-tagline {
    margin: 0 0 1.75rem;
    font-size: clamp(1.05rem, calc(0.625cqi + 12.8px), 1.25rem);
    line-height: 1.6;
}
#landing .landing-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}
#landing .landing-btn {
    display: inline-block;
    padding: 0.5rem 1.25rem;
    border-radius: 999px;
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: none;
    border: 1px solid var(--landing-border);
}
#landing .landing-btn--brand {
    background-color: var(--landing-accent);
    border-color: transparent;
    color: var(--landing-accent-contrast);
}
#landing .landing-btn--alt {
    background-color: var(--landing-surface);
    color: inherit;
}
#landing .landing-btn:hover {
    text-decoration: none;
}
#landing .landing-btn--alt:hover {
    background-color: var(--landing-surface-2);
}
#landing .landing-hero__image {
    flex: 0 1 42%;
    display: flex;
    justify-content: center;
}
/* The logo rides in a fixed square box (VitePress's .image-container) whose
 * size steps with the column; only the box itself has to fit the column
 * (each step below is derived from the 42% image column's width), so a step
 * never crowds the text. The logo fills ~2/3 of the box (75% on wide
 * columns); `contain` keeps a small logo upscaling to fill its share and
 * letterboxes a wide one instead of overflowing. */
#landing .landing-hero__image-container {
    width: 240px;
    height: 240px;
    flex: none;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}
#landing .landing-hero__image-container img {
    width: 65%;
    height: 65%;
    object-fit: contain;
    position: relative;
    z-index: 1;
}
/* Glow behind the logo, in the theme's accent hue: a solid accent disc as
 * wide as the box itself, its soft falloff provided entirely by the 40px
 * blur (a pre-faded radial gradient on top of a blur reads dim and small).
 * The halo is meant to spill past the box over whatever surrounds the hero
 * — column gutters, padding, the page background — the way VitePress's own
 * home hero glow does: nothing between here and the viewport clips
 * overflow, and because the blur is ink overflow (not content overflow) it
 * can never introduce a scrollbar, so the aura reads as one seamless layer
 * over the page instead of a box-enclosed effect. On the stacked phone
 * layout the disc steps back to 65% of the box so the halo stays on-screen
 * (VitePress's mobile glow is contained the same way). */
#landing .landing-hero__image-container::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    background: var(--landing-glow);
    filter: blur(40px);
    z-index: 0;
}

/* ---- Features: 3x2 grid of tiles with emoji badges ---- */
#landing .landing-features {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.5rem;
    padding: 0.5rem 0 2rem;
}
#landing .landing-feature {
    background-color: var(--landing-surface);
    border: 1px solid var(--landing-border);
    border-radius: 12px;
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    text-decoration: none;
    color: inherit;
}
#landing .landing-feature:hover {
    border-color: var(--landing-accent);
}
#landing .landing-feature__icon {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    background-color: var(--landing-surface-2);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
}
/* A wrapped image icon sits in the badge box with breathing room: cap it at
 * 80% of the box so even a 1:1 icon does not crowd the edges, and an
 * oversized width/height cannot overflow it. An unwrapped image icon renders
 * directly as a tile child; cap it at the tile width so a large asset never
 * overruns the column. */
#landing .landing-feature__icon img {
    max-width: 80%;
    max-height: 80%;
}
#landing .landing-feature__icon-img {
    max-width: 100%;
}
#landing .landing-feature__title {
    margin: 0;
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
}
#landing .landing-feature__details {
    margin: 0;
    font-size: 0.875rem;
    line-height: 1.55;
}

/* ---- Responsive: keyed to the landing column, not the viewport ---- */

/* Wide columns step the box up, mirroring VitePress's own steps (240 → 320
 * at 52rem, 320 → 392 at 64rem, where the logo's share of the box grows to
 * 75%). Each threshold is where the 42% image column first fits the larger
 * box with room for the text column beside it (0.42 × 832 − 27 ≈ 322px ≥
 * 320; 0.42 × 1024 − 27 ≈ 404px ≥ 392), so a step never crowds the name.
 * Only the logo share changes here — the glow disc stays the full width of
 * the box at every step, so the spilled halo stays proportional to it. */
@container (min-width: 52rem) {
    #landing .landing-hero__image-container {
        width: 320px;
        height: 320px;
    }
}
@container (min-width: 64rem) {
    #landing .landing-hero__image-container {
        width: 392px;
        height: 392px;
    }
    #landing .landing-hero__image-container img {
        width: 75%;
    }
}

/* Below 40rem the column cannot fit two comfortable columns, so the hero
 * stacks (logo above, text below). Only the direction, spacing, and the
 * text column's width change here — the type ramps and the logo box are
 * already column-keyed and continuous across this boundary, so nothing
 * pops when it flips. The name keeps its nowrap single line: stacked, it
 * has the full column width, which is strictly wider than the 58% it had
 * beside the logo. */
@container (max-width: 40rem) {
    #landing .landing-hero {
        flex-direction: column-reverse;
        align-items: center;
        text-align: left;
        gap: 2rem;
    }
    #landing .landing-hero__text {
        flex: 1 1 auto;
        width: 100%;
    }
    /* The image column needs a definite width too: with align-items: center
     * it would shrink-wrap its content, and the box's min(320px, 100%)
     * would resolve against an indefinite width and collapse. */
    #landing .landing-hero__image {
        width: 100%;
    }
    /* Contained glow on phones: the disc steps back to 65% of the box so
     * the halo hugs the logo instead of running off the narrow screen. */
    #landing .landing-hero__image-container::before {
        width: 65%;
    }
    /* Stacked, the box no longer shares the row with the text column, so it
     * takes VitePress's mobile size (320px, capped by the column) — the
     * halo is just as prominent on a phone as on a desktop. */
    #landing .landing-hero__image-container {
        width: min(320px, 100%);
        height: auto;
        aspect-ratio: 1 / 1;
    }
    #landing .landing-name {
        margin-bottom: 0.5rem;
    }
    #landing .landing-title {
        margin-bottom: 0.75rem;
    }
    #landing .landing-tagline {
        margin-bottom: 1.25rem;
    }
}

/* The tile grid is the one piece left on a viewport media query: the tiles
 * are a fixed 3-column grid (they do not scale with the column like the
 * hero does), and a viewport tablet width is a fine proxy for when three
 * tiles no longer fit side by side. */
@media (max-width: 768px) {
    #landing .landing-features {
        grid-template-columns: 1fr;
    }
}
