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
10 changes: 10 additions & 0 deletions .mcp.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"mcpServers": {
"figma-desktop": {
"type": "http",
"url": "http://host.docker.internal:3845/mcp",
"description": "Figma Desktop MCP Server for design extraction and migration",
"enabled": true
}
}
}
1 change: 1 addition & 0 deletions bar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
foobar

Check failure on line 1 in bar.js

View workflow job for this annotation

GitHub Actions / build

Missing semicolon

Check failure on line 1 in bar.js

View workflow job for this annotation

GitHub Actions / build

'foobar' is not defined

Check failure on line 1 in bar.js

View workflow job for this annotation

GitHub Actions / build

Expected an assignment or function call and instead saw an expression
6 changes: 3 additions & 3 deletions blocks/cards-trends/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
"padding": "16px"
},
"usage": {
"pagesUsing": ["/latest-trends-young-fashion", "/fashion-insights"],
"reuseCount": 2,
"lastUsed": "2025-11-03T11:56:41.163Z"
"pagesUsing": ["/latest-trends-young-fashion", "/fashion-insights", "/us/en"],
"reuseCount": 3,
"lastUsed": "2025-11-06T23:15:00.000Z"
}
}
153 changes: 153 additions & 0 deletions blocks/carousel-wknd/carousel-wknd.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
.carousel-wknd .carousel-wknd-slides-container {
position: relative;
}

.carousel-wknd .carousel-wknd-slides,
.carousel-wknd .carousel-wknd-slide-indicators {
list-style: none;
margin: 0;
padding: 0;
}

.carousel-wknd .carousel-wknd-slides {
display: flex;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
overflow: scroll clip;
}

.carousel-wknd .carousel-wknd-slides::-webkit-scrollbar {
display: none;
}

.carousel-wknd .carousel-wknd-slide {
flex: 0 0 100%;
scroll-snap-align: start;
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
position: relative;
width: 100%;
min-height: min(50vw, calc(100dvh - var(--header-height)));
}

.carousel-wknd .carousel-wknd-slide:has(.carousel-wknd-slide-content[data-align='center']) {
align-items: center;
}

.carousel-wknd .carousel-wknd-slide:has(.carousel-wknd-slide-content[data-align='right']) {
align-items: flex-end;
}

.carousel-wknd .carousel-wknd-slide .carousel-wknd-slide-image picture {
position: absolute;
inset: 0;
}

.carousel-wknd .carousel-wknd-slide .carousel-wknd-slide-image picture > img {
height: 100%;
width: 100%;
object-fit: cover;
}

.carousel-wknd .carousel-wknd-slide .carousel-wknd-slide-content {
z-index: 1;
margin: 68px;
padding: 16px;
color: white;
background-color: rgba(19 19 19 / 75%);
position: relative;
width: var(--slide-content-width, auto);
}

.carousel-wknd .carousel-wknd-slide-indicators {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 6px 12px;
padding: 12px;
background-color: var(--light-color);
line-height: 0;
}

.carousel-wknd .carousel-wknd-slide-indicator button {
width: 24px;
height: 24px;
margin: 0;
padding: 0;
border-radius: 50%;
background-color: #dadada;
transition: background-color 0.2s;
}

.carousel-wknd .carousel-wknd-slide-indicator button:disabled,
.carousel-wknd .carousel-wknd-slide-indicator button:hover,
.carousel-wknd .carousel-wknd-slide-indicator button:focus-visible {
background-color: var(--text-color);
}

.carousel-wknd .carousel-wknd-navigation-buttons {
position: absolute;
top: 50%;
transform: translateY(-50%);
left: 12px;
right: 12px;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 1;
}

/* stylelint-disable-next-line no-descending-specificity */
.carousel-wknd .carousel-wknd-navigation-buttons button {
position: relative;
width: 44px;
height: 44px;
margin: 0;
border-radius: 50%;
padding: 0;
background-color: rgba(19 19 19 / 25%);
transition: background-color 0.2s;
}

.carousel-wknd .carousel-wknd-navigation-buttons button:hover,
.carousel-wknd .carousel-wknd-navigation-buttons button:focus-visible {
background-color: rgba(19 19 19 / 75%);
}

.carousel-wknd .carousel-wknd-navigation-buttons button::after {
display: block;
content: '';
border: 2px solid;
border-bottom: 0;
border-left: 0;
height: 12px;
width: 12px;
position: absolute;
top: 50%;
left: calc(50% + 2px);
transform: translate(-50%, -50%) rotate(-135deg);
}

.carousel-wknd .carousel-wknd-navigation-buttons button.slide-next::after {
transform: translate(-50%, -50%) rotate(45deg);
left: calc(50% - 2px);
}

@media (width >= 600px) {
.carousel-wknd .carousel-wknd-navigation-buttons {
left: 24px;
right: 24px;
}

.carousel-wknd .carousel-wknd-slide .carousel-wknd-slide-content {
--slide-content-width: calc((100% - 184px) / 2);

margin: 92px;
}

.carousel-wknd .carousel-wknd-slide .carousel-wknd-slide-content[data-align='justify'] {
--slide-content-width: auto;
}
}
146 changes: 146 additions & 0 deletions blocks/carousel-wknd/carousel-wknd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
function updateActiveSlide(slide) {
const block = slide.closest('.carousel-wknd');
const slideIndex = parseInt(slide.dataset.slideIndex, 10);
block.dataset.activeSlide = slideIndex;

const slides = block.querySelectorAll('.carousel-wknd-slide');

slides.forEach((aSlide, idx) => {
aSlide.setAttribute('aria-hidden', idx !== slideIndex);
aSlide.querySelectorAll('a').forEach((link) => {
if (idx !== slideIndex) {
link.setAttribute('tabindex', '-1');
} else {
link.removeAttribute('tabindex');
}
});
});

const indicators = block.querySelectorAll('.carousel-wknd-slide-indicator');
indicators.forEach((indicator, idx) => {
if (idx !== slideIndex) {
indicator.querySelector('button').removeAttribute('disabled');
} else {
indicator.querySelector('button').setAttribute('disabled', 'true');
}
});
}

export function showSlide(block, slideIndex = 0) {
const slides = block.querySelectorAll('.carousel-wknd-slide');
let realSlideIndex = slideIndex < 0 ? slides.length - 1 : slideIndex;
if (slideIndex >= slides.length) realSlideIndex = 0;
const activeSlide = slides[realSlideIndex];

activeSlide.querySelectorAll('a').forEach((link) => link.removeAttribute('tabindex'));
block.querySelector('.carousel-wknd-slides').scrollTo({
top: 0,
left: activeSlide.offsetLeft,
behavior: 'smooth',
});
}

function bindEvents(block) {
const slideIndicators = block.querySelector('.carousel-wknd-slide-indicators');
if (!slideIndicators) return;

slideIndicators.querySelectorAll('button').forEach((button) => {
button.addEventListener('click', (e) => {
const slideIndicator = e.currentTarget.parentElement;
showSlide(block, parseInt(slideIndicator.dataset.targetSlide, 10));
});
});

block.querySelector('.slide-prev').addEventListener('click', () => {
showSlide(block, parseInt(block.dataset.activeSlide, 10) - 1);
});
block.querySelector('.slide-next').addEventListener('click', () => {
showSlide(block, parseInt(block.dataset.activeSlide, 10) + 1);
});

const slideObserver = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) updateActiveSlide(entry.target);
});
}, { threshold: 0.5 });
block.querySelectorAll('.carousel-wknd-slide').forEach((slide) => {
slideObserver.observe(slide);
});
}

function createSlide(row, slideIndex, carouselId) {
const slide = document.createElement('li');
slide.dataset.slideIndex = slideIndex;
slide.setAttribute('id', `carousel-wknd-${carouselId}-slide-${slideIndex}`);
slide.classList.add('carousel-wknd-slide');

row.querySelectorAll(':scope > div').forEach((column, colIdx) => {
column.classList.add(`carousel-wknd-slide-${colIdx === 0 ? 'image' : 'content'}`);
slide.append(column);
});

const labeledBy = slide.querySelector('h1, h2, h3, h4, h5, h6');
if (labeledBy) {
slide.setAttribute('aria-labelledby', labeledBy.getAttribute('id'));
}

return slide;
}

let carouselId = 0;
export default function decorate(block) {
carouselId += 1;
block.setAttribute('id', `carousel-wknd-${carouselId}`);
const rows = block.querySelectorAll(':scope > div');
const isSingleSlide = rows.length < 2;

block.setAttribute('role', 'region');
block.setAttribute('aria-roledescription', 'Carousel');

const container = document.createElement('div');
container.classList.add('carousel-wknd-slides-container');

const slidesWrapper = document.createElement('ul');
slidesWrapper.classList.add('carousel-wknd-slides');
block.prepend(slidesWrapper);

let slideIndicators;
if (!isSingleSlide) {
const slideIndicatorsNav = document.createElement('nav');
slideIndicatorsNav.setAttribute('aria-label', 'Carousel Slide Controls');
slideIndicators = document.createElement('ol');
slideIndicators.classList.add('carousel-wknd-slide-indicators');
slideIndicatorsNav.append(slideIndicators);
block.append(slideIndicatorsNav);

const slideNavButtons = document.createElement('div');
slideNavButtons.classList.add('carousel-wknd-navigation-buttons');
slideNavButtons.innerHTML = `
<button type="button" class="slide-prev" aria-label="Previous Slide"></button>
<button type="button" class="slide-next" aria-label="Next Slide"></button>
`;

container.append(slideNavButtons);
}

rows.forEach((row, idx) => {
const slide = createSlide(row, idx, carouselId);
slidesWrapper.append(slide);

if (slideIndicators) {
const indicator = document.createElement('li');
indicator.classList.add('carousel-wknd-slide-indicator');
indicator.dataset.targetSlide = idx;
indicator.innerHTML = `<button type="button" aria-label="Show Slide ${idx + 1} of ${rows.length}"></button>`;
slideIndicators.append(indicator);
}
row.remove();
});

container.append(slidesWrapper);
block.prepend(container);

if (!isSingleSlide) {
bindEvents(block);
}
}
50 changes: 50 additions & 0 deletions blocks/carousel-wknd/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"variantName": "carousel-wknd",
"baseBlock": "carousel",
"version": "1.0.0",
"created": "2025-11-06T23:16:00.000Z",
"sourceContext": {
"originUrl": "https://wknd.site/us/en.html",
"originPage": "WKND home page",
"blockPosition": "top"
},
"visualCharacteristics": {
"colorScheme": "light",
"density": "spacious",
"purpose": "hero-carousel",
"imagePattern": "large",
"textLength": "medium"
},
"contentPattern": {
"structure": "image + heading + description + CTA per slide",
"headingMaxLength": 50,
"descriptionMaxLength": 200,
"buttonCount": 1,
"imageCount": 3
},
"reuseGuidance": {
"suitableFor": [
"hero carousels with multiple featured content",
"rotating promotional banners",
"adventure or travel site hero sections"
],
"notSuitableFor": [
"single hero images",
"static content",
"image galleries without CTAs"
],
"similarVariants": []
},
"designTokens": {
"primaryColor": "#ffffff",
"backgroundColor": "#f5f5f5",
"fontFamily": "system-ui",
"headingSize": "2rem",
"padding": "68px"
},
"usage": {
"pagesUsing": ["/us/en"],
"reuseCount": 1,
"lastUsed": "2025-11-06T23:16:00.000Z"
}
}
6 changes: 3 additions & 3 deletions blocks/columns-banner/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
"padding": "40px 24px"
},
"usage": {
"pagesUsing": ["/latest-trends-young-fashion"],
"reuseCount": 1,
"lastUsed": "2025-11-03T11:37:46.427Z"
"pagesUsing": ["/latest-trends-young-fashion", "/us/en"],
"reuseCount": 2,
"lastUsed": "2025-11-06T23:15:00.000Z"
}
}
Loading
Loading