/* ============================================================================
   Home page layouts.

   Structure only - every colour, face and radius still comes from the theme
   contract, which is what keeps five layouts and five themes from being
   twenty-five things to maintain.

   Two rules hold this together:

   Slots are containers. A module sizes itself against the space it was given
   rather than the viewport, because a rail is narrow on a 27" monitor too. Any
   module that adapts must use container queries, not media queries.

   The narrow-screen order is declared, not inherited. Each layout restates its
   stacking with `order`, so what a phone shows first is a decision in the
   layout rather than an accident of source order. Rail Left is the case that
   proves it: the rail is drawn first and stacked second.
   ========================================================================== */

.wx-home {
    display: grid;
    gap: var(--wx-mod-gap);
}

.wx-slot {
    display: grid;
    gap: var(--wx-mod-gap);
    align-content: start;
    min-width: 0;

    /* What lets a module know how much room it actually has. */
    container-type: inline-size;
}

/* A slot with no module in it gives its space back rather than leaving a hole.
   Not :empty - the markup leaves whitespace inside the element, so :empty never
   matches. :has(*) asks the question that was meant: are there any elements. */
.wx-slot:not(:has(*)) {
    display: none;
}

/* ---- heights ----------------------------------------------------------- */

/* Every module sits in a box of one of two heights on a wide screen - short, or
   tall, which is exactly two shorts and the gap between them - so columns line up
   whatever is in them: two shorts side by side, two talls, or a tall beside two
   stacked shorts (Frank, 2026-10-01). The height does not change with the width; a
   module rearranges itself to fit (container queries on .wx-slot). A phone stacks
   everything at its natural height, so none of this applies below 900px. */
.wx-home {
    --wx-mod-gap: calc(var(--wx-pad) * 1.6);
    --wx-short: 260px;
    --wx-tall: calc(var(--wx-short) * 2 + var(--wx-mod-gap));
}

/* A module with nothing to show - the streak for a visitor - takes no room. */
.wx-mod:not(:has(*)) {
    display: none;
}

@media (min-width: 900px) {
    .wx-mod {
        display: flex;
        flex-direction: column;
        min-width: 0;
        overflow: hidden;
    }

    .wx-mod > * {
        flex: 1 1 auto;
        min-height: 0;
    }

    .wx-mod[data-height="short"] { height: var(--wx-short); }
    .wx-mod[data-height="tall"]  { height: var(--wx-tall); }

    /* ---- fitting the box --------------------------------------------------
       Every module fills its box, at full, half or third width. A band keeps its
       heading and gives the rest to its body; a list in a band shows the whole cards
       that fit and no part of the next one (wxFit.js hides the rest - its heading's
       "See All" has them). The narrow arrangements key off the slot's width, which is
       what each module is given. */

    .wx-mod > .wx-band {
        display: flex;
        flex-direction: column;
    }

    .wx-mod > .wx-band > :not(.wx-band-head) {
        flex: 1 1 auto;
        min-height: 0;
        overflow: hidden;
        align-content: start;
    }

    /* A list keeps every card its natural height. In a box of fixed height the grid
       would otherwise shrink its rows to fit and squash every card - the text cut
       off inside each - instead of letting the ones that don't fit fall past the
       bottom, where wxFit.js finds them. */
    .wx-mod :is(.wx-posts, .wx-cards, .wx-tiles, .wx-winners, .product-grid) {
        grid-auto-rows: max-content;
        align-content: start;
    }

    .wx-mod :is(.wx-posts, .wx-cards, .wx-tiles, .wx-winners, .product-grid) > * {
        flex-shrink: 0;
    }

    /* Compact cards in a tall box: narrower columns, and the picture and the title
       without the paragraph under it - so the count a partner set fits. Six posts or
       six games at half width is three across and two down; at the store page's or
       the feed's own size two big cards were all a half-width box could hold. */
    .wx-mod[data-height="tall"] .wx-posts,
    .wx-mod[data-height="tall"] .wx-tiles,
    .wx-mod[data-height="tall"] .product-grid {
        grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
    }

    .wx-mod[data-height="tall"] :is(.wx-post-text, .wx-tile-in p, .product-info .desc) {
        display: none;
    }

    /* One card size for posts and games: the same picture, and the same room under it
       - two lines of title and the line under those - so two tall modules side by side
       have rows that match (Frank, 2026-10-01). */
    .wx-mod[data-height="tall"] :is(.wx-post-in, .wx-tile-in) {
        box-sizing: border-box;
        height: 82px;
        align-content: start;
        overflow: hidden;
    }

    .wx-mod[data-height="tall"] :is(.wx-post-in h3, .wx-tile-in h3) {
        font-size: 0.86rem;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* The hero fills the box; its photograph crops to it. */
    .wx-mod > .wx-hero { min-height: 0; height: 100%; }

    /* The streak and the balances sit in the middle of a box that is taller than
       they need. */
    .wx-mod > .vs { height: 100%; align-content: center; }
    .wx-mod > .wx-band > .wx-points { height: 100%; align-content: center; }

    /* A pinned post fills its box: picture and words side by side. */
    .wx-mod > .wx-pin { height: 100%; }
    .wx-mod > .wx-pin .wx-pin-shot { min-height: 0; }

    /* Text that runs past its box fades out rather than stopping mid-line. */
    .wx-mod > .wx-textblock { height: 100%; overflow: hidden; }
    .wx-mod > .wx-textblock.is-clipped {
        -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 48px), transparent);
        mask-image: linear-gradient(to bottom, #000 calc(100% - 48px), transparent);
    }

    /* A third: one product to a row, and a square picture would make that one card
       taller than the box. A landscape crop keeps at least one in it. */
    @container (max-width: 520px) {
        .wx-mod .product-grid .product-image img,
        .wx-mod .product-grid .product-noimage {
            aspect-ratio: 4 / 3;
            object-fit: cover;
        }
    }

    /* Half or a third: the balances alone - the ways to earn need the room. */
    @container (max-width: 760px) {
        .wx-mod[data-height="short"] .wx-points { grid-template-columns: minmax(0, 1fr); }
        .wx-mod[data-height="short"] .wx-earn { display: none; }
    }

    /* A short pinned post in a narrow column has no room for its picture. */
    @container (max-width: 520px) {
        .wx-mod[data-height="short"] .wx-pin { grid-template-columns: minmax(0, 1fr); }
        .wx-mod[data-height="short"] .wx-pin-shot { display: none; }
    }

    /* A tall pinned post in a narrow column: picture above, words below. */
    @container (max-width: 520px) {
        .wx-mod[data-height="tall"] .wx-pin {
            grid-template-columns: minmax(0, 1fr);
            grid-template-rows: minmax(0, 1fr) auto;
        }
    }
}

/* ---- stack ------------------------------------------------------------- */

.wx-home[data-layout="stack"] {
    grid-template-columns: minmax(0, 1fr);
}

/* ---- rail right -------------------------------------------------------- */

@media (min-width: 900px) {
    /* Six columns rather than three, so a row can be split two ways as well as
       evenly: the rail keeps its 2:1 against the main column, while the fold below
       goes two across instead of three. Three narrow columns of bands broke the
       vertical rhythm - each one too short to say anything, and the eye having to
       track across three of them before it could move down. */
    .wx-home[data-layout="rail-right"] {
        grid-template-columns: repeat(6, minmax(0, 1fr));
        grid-template-areas:
            "hero  hero  hero  hero  hero  hero"
            "main  main  main  main  rail  rail"
            "fold1 fold1 fold1 fold2 fold2 fold2"
            "fold3 fold3 fold3 fold3 fold3 fold3";
    }

    .wx-home[data-layout="rail-left"] {
        grid-template-columns: repeat(6, minmax(0, 1fr));
        grid-template-areas:
            "hero  hero  hero  hero  hero  hero"
            "rail  rail  main  main  main  main"
            "fold1 fold1 fold1 fold2 fold2 fold2"
            "fold3 fold3 fold3 fold3 fold3 fold3";
    }

    /* One column has to say so too. The slots below are placed by area name, and a
       layout that names no areas gets them made up for it - an implicit column per
       name, after the real one. Stack drew an empty 1,220px column and pushed its
       hero and body off the right edge into two more (2026-10-01). */
    .wx-home[data-layout="stack"] {
        grid-template-areas:
            "hero"
            "full";
    }

    .wx-home[data-layout="app"] {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "full";
    }

    .wx-home[data-layout="halves"] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-areas:
            "hero hero"
            "left right"
            "full full";
    }

    .wx-home[data-layout="showcase"] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-areas:
            "hero    hero"
            "feature feature"
            "fold1   fold2"
            "fold3   fold3"
            "full    full";
    }

    .wx-home .wx-slot[data-slot="hero"]    { grid-area: hero; }
    .wx-home .wx-slot[data-slot="main"]    { grid-area: main; }
    .wx-home .wx-slot[data-slot="rail"]    { grid-area: rail; }
    .wx-home .wx-slot[data-slot="left"]    { grid-area: left; }
    .wx-home .wx-slot[data-slot="right"]   { grid-area: right; }
    .wx-home .wx-slot[data-slot="feature"] { grid-area: feature; }
    .wx-home .wx-slot[data-slot="fold1"]   { grid-area: fold1; }
    .wx-home .wx-slot[data-slot="fold2"]   { grid-area: fold2; }
    .wx-home .wx-slot[data-slot="fold3"]   { grid-area: fold3; }
    .wx-home .wx-slot[data-slot="full"]    { grid-area: full; }
}

/* ---- narrow ------------------------------------------------------------ */

/* One column, and each layout says what comes first. Grid areas are dropped
   here so `order` decides, which is the whole point: Rail Left draws its rail
   on the left but stacks it after the main column, because nobody scrolls past
   a sidebar to reach the shop. */
@media (max-width: 899px) {
    .wx-home {
        display: flex;
        flex-direction: column;
    }

    .wx-slot[data-slot="hero"]    { order: 0; }
    .wx-slot[data-slot="main"]    { order: 1; }
    .wx-slot[data-slot="feature"] { order: 1; }
    .wx-slot[data-slot="left"]    { order: 1; }
    .wx-slot[data-slot="rail"]    { order: 2; }
    .wx-slot[data-slot="right"]   { order: 2; }
    .wx-slot[data-slot="fold1"]   { order: 3; }
    .wx-slot[data-slot="fold2"]   { order: 4; }
    .wx-slot[data-slot="fold3"]   { order: 5; }
    .wx-slot[data-slot="full"]    { order: 6; }
}

/* ---- modules in a narrow slot ------------------------------------------ */

/* A rail is about a third of the shell. Everything that lays out in columns
   has to collapse against the slot, not the window. */
@container (max-width: 460px) {
    .product-grid,
    .wx-cards,
    .wx-tiles,
    .wx-posts,
    .wx-winners {
        grid-template-columns: minmax(0, 1fr);
    }

    .wx-pin,
    .wx-points {
        grid-template-columns: minmax(0, 1fr);
    }

    .wx-pin-shot {
        min-height: 150px;
    }

    /* The hero carries less weight in a rail than across the page. */
    .wx-hero {
        min-height: 150px;
    }

    .wx-hero-name {
        font-size: clamp(1.2rem, 6cqi, 1.8rem);
    }
}

@container (min-width: 461px) and (max-width: 700px) {
    .product-grid,
    .wx-cards,
    .wx-tiles,
    .wx-posts {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ---- text module ------------------------------------------------------- */

.wx-textblock {
    display: grid;
    gap: 10px;
    justify-items: start;
    background: var(--wx-surface);
    border: 1px solid var(--wx-line);
    border-radius: var(--wx-radius);
    padding: var(--wx-pad);
}

.wx-textblock h2 {
    margin: 0;
    font-size: 1.25rem;
    line-height: 1.2;
    color: var(--wx-ink);
}

/* Line breaks the partner typed survive without any of it being markup. */
.wx-textblock p {
    margin: 0;
    color: var(--wx-muted);
    white-space: pre-wrap;
    max-width: 62ch;
}

/* A card wxFit.js found past the bottom of its module's box. */
.wx-fit-out { display: none !important; }
