<section class="tiles">
<div class="container">
<div class="tiles__grid -featured">
<!--
Thirds grid: 3 columns at desktop
- (no modifier) = 1×1 small square
- -featured = 2×2 large square
- -wide = 2×1 horizontal
- -tall = 1×2 vertical
-->
<div class="tiles__set -thirds">
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1557683316-973673baf926?w=400&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -featured -dark -has-content">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1478760329108-5c3ed9d495a0?w=800&h=800&fit=crop" alt="">
</div>
<div class="tiles__overlay"></div>
<div class="tiles__content">
<h3 class="tiles__heading">Featured tile</h3>
<p class="tiles__description">This tile uses -featured to span 2×2</p>
<div class="tiles__actions">
<a href="#" class="button -outline">Learn More</a>
</div>
</div>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1579546929518-9e396f3cc809?w=400&h=400&fit=crop" alt="">
</div>
</div>
</div>
<!--
Halves grid: 4 columns at desktop
Add any number of tiles, any combination of modifiers
-->
<div class="tiles__set -halves">
<div class="tiles__tile -featured">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1557682250-33bd709cbe85?w=800&h=800&fit=crop" alt="">
</div>
<button class="tiles__more">
<!--!Font Awesome Free v7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M480 80c8.8 0 16 7.2 16 16l0 256c0 8.8-7.2 16-16 16l-320 0c-8.8 0-16-7.2-16-16l0-256c0-8.8 7.2-16 16-16l320 0zM160 32c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L160 32zm80 112a32 32 0 1 0 -64 0 32 32 0 1 0 64 0zm140.7 3.8c-4.3-7.3-12.2-11.8-20.7-11.8s-16.4 4.5-20.7 11.8l-46.5 79-17.2-24.6c-4.5-6.4-11.8-10.2-19.7-10.2s-15.2 3.8-19.7 10.2l-56 80c-5.1 7.3-5.8 16.9-1.6 24.8S191.1 320 200 320l240 0c8.6 0 16.6-4.6 20.8-12.1s4.2-16.7-.1-24.1l-80-136zM48 152c0-13.3-10.7-24-24-24S0 138.7 0 152L0 448c0 35.3 28.7 64 64 64l360 0c13.3 0 24-10.7 24-24s-10.7-24-24-24L64 464c-8.8 0-16-7.2-16-16l0-296z"/></svg>
View 10 More Images
</button>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1614850523296-d8c1af93d400?w=400&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -wide">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1557682224-5b8590cd9ec5?w=600&h=300&fit=crop" alt="">
</div>
</div>
</div>
<!--
3-column grid with mixed layout:
Row 1: Wide (2 cols) + Tall (1 col, spans 2 rows)
Row 2: Small + Small + Tall continues
-->
<div class="tiles__set -thirds">
<div class="tiles__tile -wide -dark -has-content">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&h=400&fit=crop" alt="">
</div>
<div class="tiles__overlay"></div>
<div class="tiles__content">
<h3 class="tiles__heading">Wide tile</h3>
<p class="tiles__description">Spans 2 columns horizontally</p>
</div>
</div>
<div class="tiles__tile -tall -dark">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1682687220742-aba13b6e50ba?w=400&h=800&fit=crop" alt="">
</div>
<div class="tiles__overlay"></div>
<div class="tiles__content">
<h3 class="tiles__heading">Tall tile</h3>
<p class="tiles__description">Spans 2 rows</p>
</div>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=400&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=400&h=400&fit=crop" alt="">
</div>
</div>
</div>
<!--
4-column grid: Small + Wide + Small (1+2+1 = 4 cols)
Visually continues from the section above (no extra gap)
-->
<div class="tiles__set -halves">
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1501854140801-50d01698950b?w=400&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -wide">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1433086966358-54859d0ed716?w=800&h=400&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1439066615861-d1af74d74000?w=400&h=400&fit=crop" alt="">
</div>
</div>
</div>
<!--
3-column grid with staggered -short and -fill modifiers
-fill spans 2 grid rows, -short spans 1 row:
Grid rows: Col 1 Col 2 Col 3
Row 1: [fill-top] [short] [fill-top]
Row 2: [fill-bot] [fill-top] [fill-bot]
Row 3: [short] [fill-bot] [short]
-->
<div class="tiles__set -thirds -staggered">
<!-- Tile order: fill, short, fill, fill, short, short -->
<div class="tiles__tile -fill">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1557683316-973673baf926?w=400&h=600&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -short">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1478760329108-5c3ed9d495a0?w=800&h=450&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -fill">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1579546929518-9e396f3cc809?w=400&h=600&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -fill">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1557682250-33bd709cbe85?w=800&h=450&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -short">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=400&h=600&fit=crop" alt="">
</div>
</div>
<div class="tiles__tile -short">
<div class="tiles__media">
<img src="https://images.unsplash.com/photo-1614850523296-d8c1af93d400?w=800&h=450&fit=crop" alt="">
</div>
</div>
</div>
</div>
</div>
</section>
@use "@imarc/pronto/resources/styles/imported" as *;
.tiles {
$b: &;
padding: 2rem 0;
&__grid {
--columns: 1;
--gap: var(--root-gap, 1rem);
display: grid;
gap: var(--gap);
grid-template-columns: repeat(var(--columns), 1fr);
grid-auto-flow: dense;
@include at(md) {
--columns: 2;
}
@include at(lg) {
--columns: 4;
}
}
&__tile {
background-color: var(--tile-bg, var(--color-gray-100, #f5f5f5));
display: grid;
overflow: hidden;
position: relative;
// Position for content tiles
&.-has-content {
align-items: end;
}
}
&__media {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
img,
video {
height: 100%;
object-fit: cover;
width: 100%;
}
}
&__content {
display: flex;
flex-direction: column;
gap: 1.5rem;
max-width: 32rem;
padding: 2rem;
position: relative;
z-index: 1;
}
&__heading {
color: inherit;
font-family: var(--root-font-family-heading);
font-size: clamp(2rem, 5vw, 3.5rem);
font-weight: 700;
line-height: 1.1;
margin: 0;
}
&__description {
line-height: 1.5;
margin: 0;
}
&__actions {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-block-start: 0.5rem;
}
// Dark theme for tiles with dark backgrounds
&__tile.-dark {
color: #fff;
#{$b}__heading,
#{$b}__description {
color: inherit;
}
.button.-outline {
border-color: currentColor;
color: inherit;
&:hover {
background-color: #fff;
border-color: #fff;
color: #000;
}
}
}
// Light theme for tiles with light backgrounds
&__tile.-light {
color: var(--root-color, #333);
}
// Featured layout container
&__grid.-featured {
display: flex;
flex-direction: column;
gap: var(--gap);
}
// ==========================================================================
// Tile Sets - Flexible grid layouts
//
// Set modifiers define the column structure:
// -thirds : 3-column grid at desktop (for 1/3 + 2/3 style layouts)
// -halves : 4-column grid at desktop (for 50/50 style layouts)
//
// Tile modifiers control spanning (work in any set):
// -featured : Spans 2 columns × 2 rows (large square)
// -wide : Spans 2 columns × 1 row (horizontal banner)
// -tall : Spans 1 column × 2 rows (vertical banner)
// (default) : 1 column × 1 row (small square)
//
// Tiles flow in DOM order with dense packing to fill gaps.
// Add as many tiles as needed - the grid adapts automatically.
// ==========================================================================
&__set {
container-type: inline-size;
display: grid;
gap: var(--gap);
grid-auto-flow: dense;
// Thirds: 3-column grid
&.-thirds {
--_tile-size: 100cqi; // Mobile: full width
grid-template-columns: 1fr;
@include at(md) {
--_tile-size: calc((100cqi - var(--gap)) / 2);
grid-template-columns: repeat(2, 1fr);
}
@include at(lg) {
--_tile-size: calc((100cqi - var(--gap) * 2) / 3);
grid-template-columns: repeat(3, 1fr);
}
// Staggered layout: uses -short (1 row) and -fill (2 rows) tiles
// No explicit row heights - tiles define their own heights via aspect-ratio/min-height
&.-staggered {
// Short height = tile-width × 9/16
--_short-height: calc(var(--_tile-size) * 0.5625);
#{$b}__tile.-fill {
// Fill = 2 shorts + 1 gap
min-height: calc(var(--_short-height) * 2 + var(--gap));
aspect-ratio: auto;
}
}
}
// Halves: 4-column grid (good for 50/50 layouts with sub-divisions)
&.-halves {
--_tile-size: 100cqi; // Mobile: full width
grid-template-columns: 1fr;
@include at(md) {
--_tile-size: calc((100cqi - var(--gap)) / 2);
grid-template-columns: repeat(2, 1fr);
}
@include at(lg) {
--_tile-size: calc((100cqi - var(--gap) * 3) / 4);
grid-template-columns: repeat(4, 1fr);
}
}
// =======================================================================
// Tile modifiers - control spanning behavior
// Small/Featured tiles use aspect-ratio: 1 for square
// Wide/Tall tiles stretch to fill their grid area
// =======================================================================
// Default: 1×1 square tile
#{$b}__tile {
aspect-ratio: 1;
}
// Featured: Large 2×2 tile (still square)
#{$b}__tile.-featured {
grid-column: span 2;
grid-row: span 2;
aspect-ratio: 1;
@include at(md, max-width) {
grid-column: span 1;
grid-row: span 1;
}
}
// Wide: Horizontal 2×1 tile
#{$b}__tile.-wide {
grid-column: span 2;
aspect-ratio: auto;
align-self: stretch;
// Minimum height ensures correct sizing when alone in a row
min-height: var(--_tile-size, 200px);
@include at(md, max-width) {
grid-column: span 1;
aspect-ratio: 1;
min-height: unset;
}
}
// Tall: Vertical 1×2 tile
// Same width as a square tile, spans 2 rows
#{$b}__tile.-tall {
grid-row: span 2;
aspect-ratio: auto;
align-self: stretch;
// Minimum height ensures correct sizing when determining grid flow
min-height: calc(var(--_tile-size, 200px) * 2 + var(--gap));
@include at(md, max-width) {
grid-row: span 1;
aspect-ratio: 1;
min-height: unset;
}
}
// Short: Compressed height tile (16:9 landscape)
// Height = 9/16 of normal tile (56.25%)
#{$b}__tile.-short {
aspect-ratio: 16 / 9;
@include at(md, max-width) {
aspect-ratio: 1;
}
}
// Fill: Spans 2 grid rows, pairs with -short tiles
#{$b}__tile.-fill {
grid-row: span 2;
aspect-ratio: auto;
align-self: stretch;
@include at(md, max-width) {
grid-row: span 1;
aspect-ratio: 1;
}
}
}
// "View more" button - positioned within tile content
&__more {
align-items: center;
align-self: flex-end;
background: #fff;
border-radius: 4px;
border: none;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
color: #0066ff;
cursor: pointer;
display: inline-flex;
font-size: 0.875rem;
font-weight: 500;
gap: 0.5rem;
margin: auto 2rem 2rem auto; // Push to bottom-right with tile padding
padding: 0.5rem 1rem;
position: relative;
transition: box-shadow var(--root-duration-fast, 150ms) var(--root-ease-out);
white-space: nowrap;
z-index: 2;
&:hover {
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
svg,
.icon {
fill: currentColor;
height: 1em;
width: 1em;
}
}
// Gradient overlay for better text readability
&__overlay {
background: linear-gradient(
to top,
rgba(0, 0, 0, 0.7) 0%,
rgba(0, 0, 0, 0.3) 50%,
rgba(0, 0, 0, 0) 100%
);
inset: 0;
position: absolute;
z-index: 0;
}
}