/* SFH2026 brands list.
 *
 * The tile table is grid/layouts/sfh2026-brands.css — the homepage teaser the
 * design was drawn for — rebuilt here for the full page, because cms2 emits a
 * layout's CSS only when that layout is on the page and the two are never on the
 * same one. Same construction, and for the same reason: top+left border on the
 * CONTAINER, right+bottom on each CELL, which closes the box with no doubled
 * line and no :nth-child arithmetic, so it holds for any column count and for a
 * last row of any length.
 *
 * The .sfh-* chrome below is the documented duplication of
 * productslider/layouts/sfh2026.css (see the note atop gallery's copy). Keep
 * .sfh-heading-xl in step with the other copies — it is one style with several
 * definitions, and they drift silently.
 */
.sfh-container { max-width: var(--cms2-max-width, 1280px); margin: 0 auto; }
.sfh-eyebrow {
    margin: 0 0 12px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: #BE202E;
    line-height: 1.2;
}
.sfh-heading-xl {
    margin: 0;
    font-size: clamp(34px, 4.6vw, 42px);
    font-weight: 800;
    line-height: 120%;
    text-transform: uppercase;
    color: #000;
}
.sfh-section-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    margin-bottom: 38px;
}
.sfh-link-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex: none;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    text-decoration: none;
    color: #121212;
}
.sfh-link-btn .sfh-btn-arrow svg { width: 28px; height: 9px; display: block; color: #BE202E; }

.sfh-brandlist { padding: 64px 20px; background: #fff; }

/* Flex, not grid, and a SHORT LAST ROW IS CENTRED at the normal column width.
 *
 * A grid packs the leftover items into the first N columns and leaves a hole on
 * the right, which is what made a table of 14 brands end with two cells and an
 * open box. Flex with a fixed basis and `justify-content: center` puts the
 * remainder in the middle instead: a full row has no free space to distribute
 * and stays six equal columns, while a last row of two sits in columns 3 and 4.
 * No count, no :nth-child, no knowledge of how many brands there are.
 *
 * EVERY LINE IS A CELL BORDER, and that is forced by the centring. The border
 * used to be split between the container (top + left) and the cell (right +
 * bottom), which closes the box beautifully — as long as every row is full. The
 * moment a row is centred, a container-level side border is a stray line
 * hanging beside the empty space, and no arrangement of the split avoids it:
 * whichever edge the container owns is the edge the short row does not reach.
 *
 * So each cell carries all four, and `margin: -1px 0 0 -1px` laps each one over
 * its neighbour's so a shared edge stays a single 1px line rather than two.
 *
 * That overlap is why the basis is `100%/cols + 1px` rather than a plain
 * 100%/cols. Each cell's margin box is 1px narrower than its border box, so the
 * extra pixel is what the neighbour laps back; without it the row is a pixel
 * short, the centring splits the leftover in half, and the whole table sits
 * half a pixel inside its own line (measured: 81..1359 instead of 80..1360).
 * NB the 100% resolves against the CONTENT box, which the container's 1px
 * padding has already narrowed — that padding is there to cancel the first
 * cell's negative margin so the table starts exactly on the site's content line.
 *
 * `box-sizing: border-box` (site.css, on *) is load-bearing throughout: the
 * basis is a percentage of the row, so the borders have to be counted inside it.
 */
.sfh-brandlist-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    padding: 1px 0 0 1px;
}
/* A two-row grid, not a centred column, so every NAME lands on the same line
 * across a row.
 *
 * As a flex column the cell centred whatever it contained, so its height was the
 * artwork's: a tall badge pushed its caption down and a flat wordmark pulled it
 * up, and the captions in one row sat at three different heights. Reserving a
 * fixed row for the logo fixes the caption's position regardless of what the
 * factory uploaded — which is the only thing here we do not control.
 *
 * The name is pinned to row 2 explicitly, so a brand with no logo leaves row 1
 * empty rather than sliding up into it: text-only tiles then line up with the
 * rest instead of floating in the middle of their box.
 */
.sfh-brandlist-cell {
    flex: 0 0 calc(100% / var(--cols, 6) + 1px);
    min-width: 0;
    margin: -1px 0 0 -1px;
    display: grid;
    grid-template-rows: var(--brand-logo-h, 56px) auto;
    align-content: start;
    justify-items: center;
    gap: 16px;
    text-align: center;
    min-height: 104px;
    padding: 35px 14px;
    background: #fff;
    border: 1px solid #e6e6e6;
    font-size: 12px;
    font-weight: 700;
    line-height: 1.3;
    color: black;
    text-decoration: none;
    transition: color .15s, background-color .15s;
}
/* Only the cells that lead somewhere react — a plain name is not a control. */
a.sfh-brandlist-cell:hover { color: #fff; background: #121212; }

/* Hovering one tile fades the rest, so the cursor picks a brand out of the wall
 * instead of the wall staying uniformly loud.
 *
 * The fade is on the cell's CONTENTS, not the cell, and that is the whole trick:
 * `opacity` on the cell would take its borders with it, and those borders ARE
 * the table — at #e6e6e6 they would all but disappear the moment the pointer
 * entered, so the grid would dissolve rather than focus. Fading only the logo
 * and the name leaves every line, and the hovered tile's ink fill, untouched.
 *
 * Every cell dims, linked or not: this is about where the eye should go, not
 * about what is clickable, and leaving the unlinked names at full strength
 * would make them the loudest thing on the page whenever anything else is
 * hovered.
 *
 * The trigger is `:has(cell:hover)` on the grid, NOT `grid:hover`. The container
 * is always full width, but a short last row is centred — so the empty flanks
 * beside it, and the container's own 1px padding, are inside the container and
 * inside no cell. On `grid:hover` the pointer landing there dimmed the whole
 * wall with nothing to restore, which is what this looked like from the outside:
 * a hover state with nothing hovered.
 *
 * A browser without :has() simply never dims. That is the right way for this to
 * degrade — the wall reads exactly as it did before the effect existed. */
.sfh-brandlist-cell > * { transition: opacity .18s; }
.sfh-brandlist-grid:has(.sfh-brandlist-cell:hover) .sfh-brandlist-cell > * { opacity: .28; }
.sfh-brandlist-grid:has(.sfh-brandlist-cell:hover) .sfh-brandlist-cell:hover > * { opacity: 1; }

/* Centred header, per the Figma frame.
 *
 * Scoped to .sfh-brandlist because .sfh-section-header is the shared SFH chrome
 * that productslider also ships, and both stylesheets can load on one page —
 * unscoped, this would re-centre the slider headings depending on which file
 * happened to load last. Exactly the trap the gallery layout hit. */
.sfh-brandlist .sfh-section-header.is-center { justify-content: center; }
.sfh-brandlist .sfh-section-header.is-center .sfh-section-title { text-align: center; }

/* A logo is artwork of whatever size and aspect the factory uploaded, so the BOX
   is what stays regular, never the image. It fills neither dimension: the width
   cap keeps a long wordmark (Arakawa, Morgan) from running the full width of its
   cell, which read as ragged next to a compact badge, and object-fit keeps every
   one of them undistorted inside whatever box it ends up with. Both limits are
   variables so a site can tune the wall without restating the rule. */
.sfh-brandlist-cell img {
    max-width: var(--brand-logo-w, 62%);
    max-height: 100%;
    object-fit: contain;
    align-self: center;
}
/* `align-content: start`, and row 2 sized by its own text.
 *
 * What has to hold is that row 2 BEGINS at the same y in every cell of a row,
 * and the fixed logo track already guarantees that — as long as the rows are
 * packed from the top. Centring them was the mistake: it re-centred each cell's
 * whole block, so a caption that wrapped lifted its own first line above its
 * neighbours', and the fix for THAT was to reserve two caption lines
 * everywhere — which left a band of dead space under every one-line caption,
 * 17px measured, and that is what the empty space under CHANNEL ISLANDS was.
 *
 * Packing from the top needs no reservation at all: a wrapping caption grows
 * downward and its neighbours keep their line. Nothing is centred away and
 * nothing is held empty. In the ordinary case, where no caption wraps, the
 * content fills the cell exactly and start and centre are the same thing. */
.sfh-brandlist-name { grid-row: 2; align-self: start; }

/* A tile with no logo drops the reserved row and centres its name instead.
 *
 * Holding the row open put the name on the caption line of its neighbours,
 * which is the tidier answer in a row of logos — but a lone name under an empty
 * box reads as stuck to the bottom of it, not as aligned with anything. Since
 * there is no artwork above it, there is nothing for it to line up WITH, so the
 * centre is the only position that looks deliberate. */
.sfh-brandlist-cell:not(.has-logo) {
    grid-template-rows: auto;
    align-content: center;
}
.sfh-brandlist-cell:not(.has-logo) .sfh-brandlist-name { grid-row: 1; }
/* Logos are usually black-on-white artwork, which would vanish into the hover
   fill. Inverting is cruder than a second white asset per brand and better than
   an invisible tile. */
a.sfh-brandlist-cell:hover img { filter: invert(1) grayscale(1) contrast(1.4); }

/* With the logo above it the name is a caption, not the tile's subject — the
   artwork already says the brand, so the word is there for the ones whose
   wordmark is unreadable at 56px (and several are: a shamrock, a signature).
   Its own colour has to be undone on hover, or it stays grey on the ink fill. */
.sfh-brandlist-cell.has-logo .sfh-brandlist-name {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: black;
}
a.sfh-brandlist-cell:hover .sfh-brandlist-name { color: inherit; }

@media (max-width: 760px) {
    .sfh-brandlist { padding: 40px 20px; }
    .sfh-section-header { margin-bottom: 26px; }
    .sfh-brandlist-cell { flex-basis: calc(100% / var(--cols-m, 2) + 1px); }
    .sfh-brandlist-cell {
        min-height: 92px; font-size: 16px; padding: 12px 10px; gap: 8px;
        grid-template-rows: var(--brand-logo-h-m, 44px) auto;
    }
    .sfh-brandlist-cell img { max-width: var(--brand-logo-w-m, 72%); }
    .sfh-brandlist-cell.has-logo .sfh-brandlist-name { font-size: 11px; }
}
