Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions public/main-icons-sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions resources/styles/organisms/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@
@forward "slider";
@forward "stats";
@forward "table";
@forward "tiles";
@forward "featuredTestimonials";
297 changes: 297 additions & 0 deletions resources/styles/organisms/tiles/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,297 @@
@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(sm) {
--_tile-size: calc((100cqi - var(--gap)) / 2);
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

@include at(md) {
--_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(sm) {
--_tile-size: calc((100cqi - var(--gap)) / 2);
// Allow columns to shrink more before dropping
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
}

@include at(md) {
--_tile-size: calc((100cqi - var(--gap) * 3) / 4);
grid-template-columns: repeat(4, 1fr);
}
}

// =======================================================================
// Tile modifiers - control spanning behavior (mobile-first)
// Default: 1×1 square tile on all screens
// Modifiers add spanning at md breakpoint and above
// =======================================================================

// Default: 1×1 square tile
#{$b}__tile {
aspect-ratio: 1;
}

// Featured: Large 2×2 tile at md+ (square on mobile)
#{$b}__tile.-featured {
@include at(sm) {
// Span all available columns at sm to avoid implicit tracks.
grid-column: 1 / -1;
grid-row: span 2;
}

@include at(md) {
grid-column: span 2;
grid-row: span 2;
}
}

// Wide: Horizontal 2×1 tile at md+ (square on mobile)
#{$b}__tile.-wide {
@include at(sm) {
// Span all available columns at md to avoid implicit tracks.
grid-column: 1 / -1;
aspect-ratio: auto;
align-self: stretch;
min-height: var(--_tile-size, 200px);
}

@include at(md) {
grid-column: span 2;
}
}

// Tall: Vertical 1×2 tile at md+ (square on mobile)
#{$b}__tile.-tall {
@include at(sm) {
grid-row: span 2;
aspect-ratio: auto;
align-self: stretch;
min-height: calc(var(--_tile-size, 200px) * 2 + var(--gap));
}
}

// Short: 16:9 landscape tile at md+ (square on mobile)
#{$b}__tile.-short {
@include at(sm) {
aspect-ratio: 16 / 9;
}
}

// Fill: Spans 2 grid rows at md+, pairs with -short tiles (square on mobile)
#{$b}__tile.-fill {
@include at(md) {
grid-row: span 2;
aspect-ratio: auto;
align-self: stretch;
}
}
}

// "View more" button - positioned within tile content
&__more {
align-items: center;
align-self: flex-end;
background: #fff;
border-radius: var(--root-border-radius);
border: none;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
color: var(--link-color, var(--color-blue));
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-ease-out-fast);
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;
}
}
65 changes: 65 additions & 0 deletions resources/styles/organisms/tiles/tiles--halves.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<section class="tiles">
<div class="container">
<div class="tiles__grid -featured">
<!--
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">
<svg class="icon" aria-hidden="true" role="presentation">
<use href="/main-icons-sprite.svg#images" />
</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>

<!--
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>
</div>
</div>
</section>
Loading