From 7da9bff42dba232f86262ebd1ff1c19cfba055bf Mon Sep 17 00:00:00 2001 From: Dan M Date: Wed, 14 Jan 2026 16:21:09 -0500 Subject: [PATCH 1/7] Add markup and styles for tiles module --- resources/styles/organisms/index.scss | 1 + resources/styles/organisms/tiles/index.scss | 306 ++++++++++++++++++++ resources/styles/organisms/tiles/tiles.html | 188 ++++++++++++ 3 files changed, 495 insertions(+) create mode 100644 resources/styles/organisms/tiles/index.scss create mode 100644 resources/styles/organisms/tiles/tiles.html diff --git a/resources/styles/organisms/index.scss b/resources/styles/organisms/index.scss index 90d60f0..6cfa498 100644 --- a/resources/styles/organisms/index.scss +++ b/resources/styles/organisms/index.scss @@ -10,4 +10,5 @@ @forward "slider"; @forward "stats"; @forward "table"; +@forward "tiles"; @forward "featuredTestimonials"; diff --git a/resources/styles/organisms/tiles/index.scss b/resources/styles/organisms/tiles/index.scss new file mode 100644 index 0000000..8cd161c --- /dev/null +++ b/resources/styles/organisms/tiles/index.scss @@ -0,0 +1,306 @@ +@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; + } +} diff --git a/resources/styles/organisms/tiles/tiles.html b/resources/styles/organisms/tiles/tiles.html new file mode 100644 index 0000000..77b9a84 --- /dev/null +++ b/resources/styles/organisms/tiles/tiles.html @@ -0,0 +1,188 @@ +
+
+ +
+
From 8b56a9f97476a87a17d68ba51a976abda98b1d1e Mon Sep 17 00:00:00 2001 From: Dan M Date: Wed, 14 Jan 2026 16:29:39 -0500 Subject: [PATCH 2/7] Split into files --- .../styles/organisms/tiles/tiles--halves.html | 64 +++++++++++++ .../styles/organisms/tiles/tiles--thirds.html | 90 +++++++++++++++++++ 2 files changed, 154 insertions(+) create mode 100644 resources/styles/organisms/tiles/tiles--halves.html create mode 100644 resources/styles/organisms/tiles/tiles--thirds.html diff --git a/resources/styles/organisms/tiles/tiles--halves.html b/resources/styles/organisms/tiles/tiles--halves.html new file mode 100644 index 0000000..4f0f515 --- /dev/null +++ b/resources/styles/organisms/tiles/tiles--halves.html @@ -0,0 +1,64 @@ +
+
+ +
+
\ No newline at end of file diff --git a/resources/styles/organisms/tiles/tiles--thirds.html b/resources/styles/organisms/tiles/tiles--thirds.html new file mode 100644 index 0000000..f444442 --- /dev/null +++ b/resources/styles/organisms/tiles/tiles--thirds.html @@ -0,0 +1,90 @@ +
+
+ +
+
\ No newline at end of file From 4f5d313f63731ab4a9c741f741031b29f3d1a064 Mon Sep 17 00:00:00 2001 From: Dan M Date: Thu, 22 Jan 2026 16:55:35 -0500 Subject: [PATCH 3/7] Move svg images icon to sprite.svg and add assistive tech attributes --- public/main-icons-sprite.svg | 2 ++ resources/styles/organisms/tiles/tiles--halves.html | 5 +++-- resources/styles/organisms/tiles/tiles.html | 5 +++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/public/main-icons-sprite.svg b/public/main-icons-sprite.svg index bc5fa1f..718fe75 100644 --- a/public/main-icons-sprite.svg +++ b/public/main-icons-sprite.svg @@ -98,4 +98,6 @@ + + diff --git a/resources/styles/organisms/tiles/tiles--halves.html b/resources/styles/organisms/tiles/tiles--halves.html index 4f0f515..56c5a66 100644 --- a/resources/styles/organisms/tiles/tiles--halves.html +++ b/resources/styles/organisms/tiles/tiles--halves.html @@ -11,8 +11,9 @@ diff --git a/resources/styles/organisms/tiles/tiles.html b/resources/styles/organisms/tiles/tiles.html index 77b9a84..efa8d2e 100644 --- a/resources/styles/organisms/tiles/tiles.html +++ b/resources/styles/organisms/tiles/tiles.html @@ -46,8 +46,9 @@

Featured tile

From d441fc8fa120acdb666d133ea878803443b839b5 Mon Sep 17 00:00:00 2001 From: Dan M Date: Thu, 22 Jan 2026 17:14:27 -0500 Subject: [PATCH 4/7] Make usage of already exposes variables --- resources/styles/organisms/tiles/index.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/styles/organisms/tiles/index.scss b/resources/styles/organisms/tiles/index.scss index 8cd161c..ab2d3b6 100644 --- a/resources/styles/organisms/tiles/index.scss +++ b/resources/styles/organisms/tiles/index.scss @@ -263,10 +263,10 @@ align-items: center; align-self: flex-end; background: #fff; - border-radius: 4px; + border-radius: var(--root-border-radius); border: none; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); - color: #0066ff; + color: var(--link-color, var(--color-blue)); cursor: pointer; display: inline-flex; font-size: 0.875rem; @@ -275,7 +275,7 @@ 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); + transition: box-shadow var(--root-ease-out-fast); white-space: nowrap; z-index: 2; From 2b47f3acb85c7c65489aaf74995b134480925671 Mon Sep 17 00:00:00 2001 From: Dan M Date: Thu, 22 Jan 2026 17:15:13 -0500 Subject: [PATCH 5/7] Update breakpoints --- resources/styles/organisms/tiles/index.scss | 75 ++++++++------------- 1 file changed, 27 insertions(+), 48 deletions(-) diff --git a/resources/styles/organisms/tiles/index.scss b/resources/styles/organisms/tiles/index.scss index ab2d3b6..5da3158 100644 --- a/resources/styles/organisms/tiles/index.scss +++ b/resources/styles/organisms/tiles/index.scss @@ -182,9 +182,9 @@ } // ======================================================================= - // Tile modifiers - control spanning behavior - // Small/Featured tiles use aspect-ratio: 1 for square - // Wide/Tall tiles stretch to fill their grid area + // 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 @@ -192,68 +192,47 @@ aspect-ratio: 1; } - // Featured: Large 2×2 tile (still square) + // Featured: Large 2×2 tile at md+ (square on mobile) #{$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; + @include at(md) { + grid-column: span 2; + grid-row: span 2; } } - // Wide: Horizontal 2×1 tile + // Wide: Horizontal 2×1 tile at md+ (square on mobile) #{$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; + @include at(md) { + grid-column: span 2; + aspect-ratio: auto; + align-self: stretch; + min-height: var(--_tile-size, 200px); } } - // Tall: Vertical 1×2 tile - // Same width as a square tile, spans 2 rows + // Tall: Vertical 1×2 tile at md+ (square on mobile) #{$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; + @include at(md) { + grid-row: span 2; + aspect-ratio: auto; + align-self: stretch; + min-height: calc(var(--_tile-size, 200px) * 2 + var(--gap)); } } - // Short: Compressed height tile (16:9 landscape) - // Height = 9/16 of normal tile (56.25%) + // Short: 16:9 landscape tile at md+ (square on mobile) #{$b}__tile.-short { - aspect-ratio: 16 / 9; - - @include at(md, max-width) { - aspect-ratio: 1; + @include at(md) { + aspect-ratio: 16 / 9; } } - // Fill: Spans 2 grid rows, pairs with -short tiles + // Fill: Spans 2 grid rows at md+, pairs with -short tiles (square on mobile) #{$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; + @include at(md) { + grid-row: span 2; + aspect-ratio: auto; + align-self: stretch; } } } From 77586da0deba8c08b2e6f54c3553bc58ff99a37e Mon Sep 17 00:00:00 2001 From: Dan M Date: Thu, 22 Jan 2026 17:20:23 -0500 Subject: [PATCH 6/7] Remove class from outer heading --- resources/styles/organisms/tiles/tiles--thirds.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/styles/organisms/tiles/tiles--thirds.html b/resources/styles/organisms/tiles/tiles--thirds.html index f444442..528ed98 100644 --- a/resources/styles/organisms/tiles/tiles--thirds.html +++ b/resources/styles/organisms/tiles/tiles--thirds.html @@ -46,7 +46,7 @@

Featured tile

Row 3: [short] [fill-bot] [short] --> -

Staggered

+

Staggered

From ea80508417b0410cc82db9f7c138d4c4c2723b05 Mon Sep 17 00:00:00 2001 From: Dan M Date: Tue, 10 Feb 2026 11:38:20 -0500 Subject: [PATCH 7/7] Updates tiles module breakpoints for better fit --- resources/styles/organisms/tiles/index.scss | 32 ++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/resources/styles/organisms/tiles/index.scss b/resources/styles/organisms/tiles/index.scss index 5da3158..6e1d6c3 100644 --- a/resources/styles/organisms/tiles/index.scss +++ b/resources/styles/organisms/tiles/index.scss @@ -141,12 +141,12 @@ --_tile-size: 100cqi; // Mobile: full width grid-template-columns: 1fr; - @include at(md) { + @include at(sm) { --_tile-size: calc((100cqi - var(--gap)) / 2); - grid-template-columns: repeat(2, 1fr); + grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); } - @include at(lg) { + @include at(md) { --_tile-size: calc((100cqi - var(--gap) * 2) / 3); grid-template-columns: repeat(3, 1fr); } @@ -170,12 +170,13 @@ --_tile-size: 100cqi; // Mobile: full width grid-template-columns: 1fr; - @include at(md) { + @include at(sm) { --_tile-size: calc((100cqi - var(--gap)) / 2); - grid-template-columns: repeat(2, 1fr); + // Allow columns to shrink more before dropping + grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr)); } - @include at(lg) { + @include at(md) { --_tile-size: calc((100cqi - var(--gap) * 3) / 4); grid-template-columns: repeat(4, 1fr); } @@ -194,6 +195,12 @@ // 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; @@ -202,17 +209,22 @@ // Wide: Horizontal 2×1 tile at md+ (square on mobile) #{$b}__tile.-wide { - @include at(md) { - grid-column: span 2; + @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(md) { + @include at(sm) { grid-row: span 2; aspect-ratio: auto; align-self: stretch; @@ -222,7 +234,7 @@ // Short: 16:9 landscape tile at md+ (square on mobile) #{$b}__tile.-short { - @include at(md) { + @include at(sm) { aspect-ratio: 16 / 9; } }