@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;
}
}