- 코드 정리

- 경고 클래스 수정
- 카드 비율 수정 3:4 > 4:5
This commit is contained in:
2026-02-10 11:30:45 +09:00
parent ddc491dec1
commit 526d310ac9
6 changed files with 263 additions and 116 deletions

View File

@@ -48,6 +48,9 @@
screens: { screens: {
'xs': '480px', 'xs': '480px',
}, },
aspectRatio: {
'card': '4 / 5',
},
}, },
}, },
} }
@@ -137,7 +140,7 @@
<span class="text-slate-400 dark:text-slate-500 text-xs font-bold uppercase tracking-widest">Total Results</span> <span class="text-slate-400 dark:text-slate-500 text-xs font-bold uppercase tracking-widest">Total Results</span>
<span id="total-count" class="px-2 py-0.5 rounded bg-primary/10 text-primary text-sm font-bold">0</span> <span id="total-count" class="px-2 py-0.5 rounded bg-primary/10 text-primary text-sm font-bold">0</span>
</div> </div>
<div id="selection-summary" class="hidden flex items-center gap-3 bg-primary/10 px-3 py-1.5 rounded-full border border-primary/20"> <div id="selection-summary" class="hidden items-center gap-3 bg-primary/10 px-3 py-1.5 rounded-full border border-primary/20">
<span class="text-[11px] font-bold text-primary"> <span class="text-[11px] font-bold text-primary">
<span id="selected-count">0</span> <span id="selected-count">0</span>
items items
@@ -147,21 +150,21 @@
<div class="flex items-center gap-1 ml-2"> <div class="flex items-center gap-1 ml-2">
<button onclick="window.exportToExcel()" class="flex items-center gap-1 bg-primary text-white text-[10px] px-2 py-1 rounded-md hover:bg-primary-dark transition-colors"> <button onclick="window.exportToExcel()" class="flex items-center gap-1 bg-primary text-white text-[10px] px-2 py-1 rounded-md hover:bg-primary-dark transition-colors">
<span class="material-symbols-outlined !text-[14px]">download</span> <span class="material-symbols-outlined text-sm">download</span>
Export Export
</button> </button>
<button onclick="window.resetSelection()" class="flex items-center gap-1 bg-white dark:bg-slate-800 text-slate-500 text-[10px] px-2 py-1 rounded-md border border-slate-200 dark:border-slate-700 hover:bg-slate-50 transition-colors"> <button onclick="window.resetSelection()" class="flex items-center gap-1 bg-white dark:bg-slate-800 text-slate-500 text-[10px] px-2 py-1 rounded-md border border-slate-200 dark:border-slate-700 hover:bg-slate-50 transition-colors">
<span class="material-symbols-outlined !text-[14px]">restart_alt</span> <span class="material-symbols-outlined text-sm">restart_alt</span>
Reset Reset
</button> </button>
</div> </div>
</div> </div>
<div class="flex bg-slate-100 dark:bg-slate-800 p-1 rounded-lg"> <div class="flex bg-slate-100 dark:bg-slate-800 p-1 rounded-lg">
<button id="view-grid" class="p-1.5 rounded-md bg-white dark:bg-slate-700 shadow-sm text-primary transition-all"> <button id="view-grid" class="p-1.5 rounded-md bg-white dark:bg-slate-700 shadow-sm text-primary transition-all">
<span class="material-symbols-outlined !text-[20px]">grid_view</span> <span class="material-symbols-outlined text-xl">grid_view</span>
</button> </button>
<button id="view-table" class="p-1.5 rounded-md text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-all"> <button id="view-table" class="p-1.5 rounded-md text-slate-400 hover:text-slate-600 dark:hover:text-slate-200 transition-all">
<span class="material-symbols-outlined !text-[20px]">format_list_bulleted</span> <span class="material-symbols-outlined text-xl">format_list_bulleted</span>
</button> </button>
</div> </div>
</div> </div>

View File

@@ -66,9 +66,9 @@ export const TAG_STYLES = {
export const TAG_DEFAULT_STYLE = 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400'; export const TAG_DEFAULT_STYLE = 'bg-indigo-100 text-indigo-700 dark:bg-indigo-900/30 dark:text-indigo-400';
export const SEARCH_CONFIG = { export const SEARCH_CONFIG = {
USE_TITLE: true, // 상품명 검색 USE_TITLE: true, // 상품명 검색
USE_CUSTOM_TAG: true, // 커스텀 태그 검색 USE_CUSTOM_TAG: true, // 커스텀 태그 검색
USE_TAGS: true, // 태그 배열 검색 USE_TAGS: true, // 태그 배열 검색
USE_DESCRIPTION: true, // 요약 설명 검색 USE_DESCRIPTION: true, // 요약 설명 검색
USE_FULL_DESCRIPTION: false, // 상세 설명 배열 검색 USE_FULL_DESCRIPTION: false, // 상세 설명 배열 검색
}; };

View File

@@ -1,11 +1,6 @@
/** 진입점: 이벤트 바인딩·초기 렌더·URL 모달 처리 */ /** 진입점: 이벤트 바인딩·초기 렌더·URL 모달 처리 */
import { state, productsData, saveSelection } from './state.js'; import { state, productsData, saveSelection } from './state.js';
import { import { applyFilters, renderStatusChips, renderCategoryChips, bindCategoryFilter } from './filters.js';
applyFilters,
renderStatusChips,
renderCategoryChips,
bindCategoryFilter,
} from './filters.js';
import { ITEMS_PER_PAGE, STATUS_META } from './config.js'; import { ITEMS_PER_PAGE, STATUS_META } from './config.js';
import { renderProducts, changePage } from './productList.js'; import { renderProducts, changePage } from './productList.js';
import { openModal, closeModal } from './modal.js'; import { openModal, closeModal } from './modal.js';
@@ -44,7 +39,7 @@ function updateViewButtons() {
window.toggleSelectItem = (id) => { window.toggleSelectItem = (id) => {
if (state.selectedIds.has(id)) state.selectedIds.delete(id); if (state.selectedIds.has(id)) state.selectedIds.delete(id);
else state.selectedIds.add(id); else state.selectedIds.add(id);
updateSummary(); updateSummary();
}; };
@@ -52,22 +47,26 @@ export function updateSummary() {
const summary = document.getElementById('selection-summary'); const summary = document.getElementById('selection-summary');
const countEl = document.getElementById('selected-count'); const countEl = document.getElementById('selected-count');
const priceEl = document.getElementById('selected-total-price'); const priceEl = document.getElementById('selected-total-price');
if (!summary) return;
// 테이블 모드이면서 선택된 항목이 있을 때만 노출 // 테이블 모드이면서 선택된 항목이 있을 때만 노출
if (state.viewMode === 'table' && state.selectedIds.size > 0) { if (state.viewMode === 'table' && state.selectedIds.size > 0) {
// [수정] flex를 추가할 때 hidden은 확실히 제거
summary.classList.remove('hidden'); summary.classList.remove('hidden');
summary.classList.add('flex'); summary.classList.add('flex');
const total = Array.from(state.selectedIds).reduce((sum, id) => { const total = Array.from(state.selectedIds).reduce((sum, id) => {
const p = productsData.find(item => item.id === id); const p = productsData.find((item) => item.id === id);
return sum + (p ? p.price : 0); return sum + (p ? p.price : 0);
}, 0); }, 0);
countEl.textContent = state.selectedIds.size; countEl.textContent = state.selectedIds.size;
priceEl.textContent = `${total.toLocaleString()}`; priceEl.textContent = `${total.toLocaleString()}`;
} else { } else {
summary.classList.add('hidden'); // [수정] hidden을 추가할 때 flex는 확실히 제거
summary.classList.remove('flex'); summary.classList.remove('flex');
summary.classList.add('hidden');
} }
} }
@@ -124,7 +123,7 @@ if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localS
updateIcons(); updateIcons();
// 3. 버튼 클릭 이벤트 // 3. 버튼 클릭 이벤트
themeToggleBtn.addEventListener('click', function() { themeToggleBtn.addEventListener('click', function () {
// 테마 토글 // 테마 토글
if (document.documentElement.classList.contains('dark')) { if (document.documentElement.classList.contains('dark')) {
document.documentElement.classList.remove('dark'); document.documentElement.classList.remove('dark');
@@ -155,15 +154,15 @@ console.log(`%c[NUMBER]: ${newId}`, 'color: #137fec; font-weight: bold; border:
window.toggleSelectAll = (isChecked) => { window.toggleSelectAll = (isChecked) => {
const startIndex = (state.currentPage - 1) * ITEMS_PER_PAGE; const startIndex = (state.currentPage - 1) * ITEMS_PER_PAGE;
const currentPageProducts = state.visibleProducts.slice(startIndex, startIndex + ITEMS_PER_PAGE); const currentPageProducts = state.visibleProducts.slice(startIndex, startIndex + ITEMS_PER_PAGE);
currentPageProducts.forEach(p => { currentPageProducts.forEach((p) => {
const isSelectable = STATUS_META[p.status]?.selectable !== false; const isSelectable = STATUS_META[p.status]?.selectable !== false;
if (isSelectable) { if (isSelectable) {
if (isChecked) state.selectedIds.add(p.id); if (isChecked) state.selectedIds.add(p.id);
else state.selectedIds.delete(p.id); else state.selectedIds.delete(p.id);
} }
}); });
saveSelection(); // 변경사항 저장 saveSelection(); // 변경사항 저장
updateSummary(); updateSummary();
renderProducts(state.currentPage); renderProducts(state.currentPage);
@@ -171,7 +170,7 @@ window.toggleSelectAll = (isChecked) => {
/** 선택 리셋 */ /** 선택 리셋 */
window.resetSelection = () => { window.resetSelection = () => {
if (!confirm("선택된 내역을 모두 초기화할까요?")) return; if (!confirm('선택된 내역을 모두 초기화할까요?')) return;
state.selectedIds.clear(); state.selectedIds.clear();
saveSelection(); // 스토리지 동기화 saveSelection(); // 스토리지 동기화
updateSummary(); updateSummary();
@@ -180,12 +179,12 @@ window.resetSelection = () => {
/** 선택 토글 시 스토리지 저장 추가 */ /** 선택 토글 시 스토리지 저장 추가 */
window.toggleSelectItem = (id) => { window.toggleSelectItem = (id) => {
const product = productsData.find(p => p.id === id); const product = productsData.find((p) => p.id === id);
if (!product || STATUS_META[product.status]?.selectable === false) return; if (!product || STATUS_META[product.status]?.selectable === false) return;
if (state.selectedIds.has(id)) state.selectedIds.delete(id); if (state.selectedIds.has(id)) state.selectedIds.delete(id);
else state.selectedIds.add(id); else state.selectedIds.add(id);
saveSelection(); // 변경사항 저장 saveSelection(); // 변경사항 저장
updateSummary(); updateSummary();
}; };
@@ -193,62 +192,52 @@ window.toggleSelectItem = (id) => {
/** 선택된 항목들을 CSV 파일로 내보내기 */ /** 선택된 항목들을 CSV 파일로 내보내기 */
window.exportToExcel = () => { window.exportToExcel = () => {
if (state.selectedIds.size === 0) { if (state.selectedIds.size === 0) {
alert("내보낼 상품을 선택해 주세요."); alert('내보낼 상품을 선택해 주세요.');
return; return;
} }
// 1. 선택된 데이터 추출 및 계산 // 1. 선택된 데이터 추출 및 계산
let totalCount = 0; let totalCount = 0;
let totalPrice = 0; let totalPrice = 0;
const rows = Array.from(state.selectedIds).map(id => { const rows = Array.from(state.selectedIds)
const p = productsData.find(item => item.id === id); .map((id) => {
if (p) { const p = productsData.find((item) => item.id === id);
totalCount += 1; if (p) {
totalPrice += p.price; totalCount += 1;
return [ totalPrice += p.price;
p.id, return [p.id, `"${p.title.replace(/"/g, '""')}"`, p.category, p.price, p.status, `"${p.description.replace(/"/g, '""')}"`];
`"${p.title.replace(/"/g, '""')}"`, }
p.category, return null;
p.price, })
p.status, .filter((row) => row !== null);
`"${p.description.replace(/"/g, '""')}"`
];
}
return null;
}).filter(row => row !== null);
// 2. 헤더 및 푸터(합계) 설정 // 2. 헤더 및 푸터(합계) 설정
const headers = ["상품 ID", "상품명", "카테고리", "가격", "상태", "상세설명"]; const headers = ['상품 ID', '상품명', '카테고리', '가격', '상태', '상세설명'];
// 영수증 느낌을 위한 하단 합계 줄 // 영수증 느낌을 위한 하단 합계 줄
const footerEmpty = ["", "", "", "", "", ""]; // 빈 줄 const footerEmpty = ['', '', '', '', '', '']; // 빈 줄
const footerTotal = [ const footerTotal = ['TOTAL', `"총 ${totalCount}건의 항목"`, '', totalPrice, '', `"발행일: ${new Date().toLocaleString()}"`];
"TOTAL",
`"총 ${totalCount}건의 항목"`,
"",
totalPrice,
"",
`"발행일: ${new Date().toLocaleString()}"`
];
// 3. CSV 포맷 생성 (한글 깨짐 방지 BOM 추가) // 3. CSV 포맷 생성 (한글 깨짐 방지 BOM 추가)
const csvContent = "\uFEFF" + [ const csvContent =
headers.join(","), '\uFEFF' +
...rows.map(row => row.join(",")), [
footerEmpty.join(","), // 간격 조절용 빈 줄 headers.join(','),
footerTotal.join(",") // 합계 라인 ...rows.map((row) => row.join(',')),
].join("\n"); footerEmpty.join(','), // 간격 조절용 빈 줄
footerTotal.join(','), // 합계 라인
].join('\n');
// 4. 다운로드 실행 // 4. 다운로드 실행
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob); const url = URL.createObjectURL(blob);
const link = document.createElement("a"); const link = document.createElement('a');
const timestamp = new Date().toISOString().split('T')[0]; const timestamp = new Date().toISOString().split('T')[0];
link.setAttribute("href", url); link.setAttribute('href', url);
link.setAttribute("download", `inventory_receipt_${timestamp}.csv`); link.setAttribute('download', `inventory_receipt_${timestamp}.csv`);
document.body.appendChild(link); document.body.appendChild(link);
link.click(); link.click();
document.body.removeChild(link); document.body.removeChild(link);
}; };

View File

@@ -29,13 +29,25 @@ export function renderProducts(page = 1) {
// 2. 뷰 모드에 따른 컨테이너 노출 설정 // 2. 뷰 모드에 따른 컨테이너 노출 설정
if (state.viewMode === 'grid') { if (state.viewMode === 'grid') {
// 그리드 활성화
grid.classList.remove('hidden'); grid.classList.remove('hidden');
grid.classList.add('grid'); grid.classList.add('grid');
// 테이블 및 요약바 비활성화
tableWrapper.classList.add('hidden'); tableWrapper.classList.add('hidden');
summaryBar.classList.add('hidden'); if (summaryBar) {
summaryBar.classList.remove('flex'); // flex 제거
summaryBar.classList.add('hidden');
}
} else { } else {
// 그리드 비활성화
grid.classList.remove('grid');
grid.classList.add('hidden'); grid.classList.add('hidden');
// 테이블 활성화
tableWrapper.classList.remove('hidden'); tableWrapper.classList.remove('hidden');
// 요약바 노출 여부는 데이터 상태에 따라 updateSummary에서 결정
updateSummary(); updateSummary();
} }
@@ -47,11 +59,13 @@ export function renderProducts(page = 1) {
grid.innerHTML = ''; grid.innerHTML = '';
pagedProducts.forEach((product) => { pagedProducts.forEach((product) => {
const isSold = STATUS_META[product.status]?.soldOut === true; const isSold = STATUS_META[product.status]?.soldOut === true;
grid.insertAdjacentHTML('beforeend', ` grid.insertAdjacentHTML(
'beforeend',
`
<div class="group flex flex-col gap-4 cursor-pointer" onclick="openModal('${product.id}')"> <div class="group flex flex-col gap-4 cursor-pointer" onclick="openModal('${product.id}')">
<div class="relative w-full aspect-[4/5] bg-slate-50 dark:bg-slate-800 rounded-xl overflow-hidden shadow-sm group-hover:shadow-md transition-shadow"> <div class="relative w-full aspect-card bg-slate-50 dark:bg-slate-800 rounded-xl overflow-hidden shadow-sm group-hover:shadow-md transition-shadow">
<div class="w-full h-full bg-center bg-no-repeat bg-cover transform ${isSold ? 'grayscale opacity-80' : 'group-hover:scale-105'} transition-transform duration-500" <div class="w-full h-full bg-center bg-no-repeat bg-cover transform ${isSold ? 'grayscale opacity-80' : 'group-hover:scale-105'} transition-transform duration-500"
style="background-image: url('${product.images[0]}')"></div> style="background-image: url('${product.images[0]}')"></div>
<div class="absolute top-3 left-3"> <div class="absolute top-3 left-3">
<span class="px-2 py-1 text-[10px] uppercase tracking-wider font-bold rounded ${STATUS_COLOR[product.status]} backdrop-blur-md border"> <span class="px-2 py-1 text-[10px] uppercase tracking-wider font-bold rounded ${STATUS_COLOR[product.status]} backdrop-blur-md border">
${product.status} ${product.status}
@@ -63,19 +77,21 @@ export function renderProducts(page = 1) {
<p class="text-slate-500 dark:text-slate-400 text-sm font-normal line-clamp-1">${product.description}</p> <p class="text-slate-500 dark:text-slate-400 text-sm font-normal line-clamp-1">${product.description}</p>
</div> </div>
</div> </div>
`); `,
);
}); });
} else { } else {
// 테이블 렌더링 (이전과 동일, 가격 포함) // 테이블 렌더링 (이전과 동일, 가격 포함)
tableBody.innerHTML = pagedProducts.map(product => { tableBody.innerHTML = pagedProducts
const isSelectable = STATUS_META[product.status]?.selectable !== false; .map((product) => {
return ` const isSelectable = STATUS_META[product.status]?.selectable !== false;
return `
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors cursor-pointer" onclick="if(event.target.type !== 'checkbox') openModal('${product.id}')"> <tr class="hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors cursor-pointer" onclick="if(event.target.type !== 'checkbox') openModal('${product.id}')">
<td class="py-4 px-4 text-center" onclick="event.stopPropagation()"> <td class="py-4 px-4 text-center" onclick="event.stopPropagation()">
<input type="checkbox" class="product-check rounded border-slate-300 w-4 h-4 ${isSelectable ? 'cursor-pointer' : 'opacity-20 cursor-not-allowed'}" <input type="checkbox" class="product-check rounded border-slate-300 w-4 h-4 ${isSelectable ? 'cursor-pointer' : 'opacity-20 cursor-not-allowed'}"
${state.selectedIds.has(product.id) ? 'checked' : ''} ${state.selectedIds.has(product.id) ? 'checked' : ''}
${isSelectable ? '' : 'disabled'} ${isSelectable ? '' : 'disabled'}
onchange="window.toggleSelectItem('${product.id}')"> onchange="window.toggleSelectItem('${product.id}')">
</td> </td>
<td class="py-4 px-4 font-semibold text-slate-900 dark:text-white">${product.title}</td> <td class="py-4 px-4 font-semibold text-slate-900 dark:text-white">${product.title}</td>
<td class="py-4 px-4 text-slate-500 text-xs">${product.category}</td> <td class="py-4 px-4 text-slate-500 text-xs">${product.category}</td>
@@ -84,7 +100,8 @@ export function renderProducts(page = 1) {
<span class="px-2 py-0.5 rounded text-[10px] font-bold border ${STATUS_COLOR[product.status]}">${product.status}</span> <span class="px-2 py-0.5 rounded text-[10px] font-bold border ${STATUS_COLOR[product.status]}">${product.status}</span>
</td> </td>
</tr>`; </tr>`;
}).join(''); })
.join('');
} }
// [중요] 전체 선택 체크박스 상태 동기화 // [중요] 전체 선택 체크박스 상태 동기화
@@ -105,23 +122,19 @@ export function renderPagination() {
const totalPages = Math.ceil(state.visibleProducts.length / ITEMS_PER_PAGE); const totalPages = Math.ceil(state.visibleProducts.length / ITEMS_PER_PAGE);
const { currentPage } = state; const { currentPage } = state;
let html = `<button onclick="changePage(${currentPage - 1})" class="size-10 flex items-center justify-center ${currentPage === 1 ? 'invisible' : ''}"><svg viewBox="0 0 24 24" fill="none" let html = `<button onclick="changePage(${currentPage - 1})" class="size-10 flex items-center justify-center ${currentPage === 1 ? 'invisible' : ''}">
stroke="#64748B" stroke-width="3" <svg viewBox="0 0 24 24" fill="none" stroke="#64748B" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="w-5 h-5">
stroke-linecap="round" stroke-linejoin="round" <path d="M15 18l-6-6 6-6" />
class="w-5 h-5"> </svg>
<path d="M15 18l-6-6 6-6" /> </button>`;
</svg>
</button>`;
for (let i = 1; i <= totalPages; i++) { for (let i = 1; i <= totalPages; i++) {
html += `<button onclick="changePage(${i})" class="size-10 font-bold rounded-lg ${i === currentPage ? 'bg-primary text-white' : 'text-slate-500'}">${i}</button>`; html += `<button onclick="changePage(${i})" class="size-10 font-bold rounded-lg ${i === currentPage ? 'bg-primary text-white' : 'text-slate-500'}">${i}</button>`;
} }
html += `<button onclick="changePage(${currentPage + 1})" class="size-10 flex items-center justify-center ${currentPage === totalPages ? 'invisible' : ''}"><svg viewBox="0 0 24 24" fill="none" html += `<button onclick="changePage(${currentPage + 1})" class="size-10 flex items-center justify-center ${currentPage === totalPages ? 'invisible' : ''}">
stroke="#64748B" stroke-width="3" <svg viewBox="0 0 24 24" fill="none" stroke="#64748B" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="w-5 h-5">
stroke-linecap="round" stroke-linejoin="round" <path d="M9 18l6-6-6-6" />
class="w-5 h-5"> </svg>
<path d="M9 18l6-6-6-6" /> </button>`;
</svg>
</button>`;
container.innerHTML = html; container.innerHTML = html;
} }

View File

@@ -24,4 +24,4 @@ export const state = {
// 선택 내역이 변경될 때마다 세션 스토리지에 저장하는 헬퍼 함수 // 선택 내역이 변경될 때마다 세션 스토리지에 저장하는 헬퍼 함수
export function saveSelection() { export function saveSelection() {
sessionStorage.setItem('selectedProductIds', JSON.stringify(Array.from(state.selectedIds))); sessionStorage.setItem('selectedProductIds', JSON.stringify(Array.from(state.selectedIds)));
} }

View File

@@ -93,6 +93,8 @@
--text-3xl--line-height: calc(2.25 / 1.875); --text-3xl--line-height: calc(2.25 / 1.875);
--text-4xl: 2.25rem; --text-4xl: 2.25rem;
--text-4xl--line-height: calc(2.5 / 2.25); --text-4xl--line-height: calc(2.5 / 2.25);
--text-6xl: 3.75rem;
--text-6xl--line-height: 1;
--font-weight-normal: 400; --font-weight-normal: 400;
--font-weight-medium: 500; --font-weight-medium: 500;
--font-weight-semibold: 600; --font-weight-semibold: 600;
@@ -321,9 +323,6 @@
.z-50 { .z-50 {
z-index: 50; z-index: 50;
} }
.z-\[60\] {
z-index: 60;
}
.container { .container {
width: 100%; width: 100%;
@media (width >= 40rem) { @media (width >= 40rem) {
@@ -345,8 +344,11 @@
.mx-auto { .mx-auto {
margin-inline: auto; margin-inline: auto;
} }
.mt-4 { .mt-2 {
margin-top: calc(var(--spacing) * 4); margin-top: calc(var(--spacing) * 2);
}
.-mb-4 {
margin-bottom: calc(var(--spacing) * -4);
} }
.mb-2 { .mb-2 {
margin-bottom: calc(var(--spacing) * 2); margin-bottom: calc(var(--spacing) * 2);
@@ -354,6 +356,9 @@
.mb-3 { .mb-3 {
margin-bottom: calc(var(--spacing) * 3); margin-bottom: calc(var(--spacing) * 3);
} }
.mb-4 {
margin-bottom: calc(var(--spacing) * 4);
}
.mb-6 { .mb-6 {
margin-bottom: calc(var(--spacing) * 6); margin-bottom: calc(var(--spacing) * 6);
} }
@@ -363,6 +368,15 @@
.ml-0 { .ml-0 {
margin-left: calc(var(--spacing) * 0); margin-left: calc(var(--spacing) * 0);
} }
.ml-2 {
margin-left: calc(var(--spacing) * 2);
}
.line-clamp-1 {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.block { .block {
display: block; display: block;
} }
@@ -378,6 +392,9 @@
.inline-flex { .inline-flex {
display: inline-flex; display: inline-flex;
} }
.table {
display: table;
}
.aspect-\[4\/5\] { .aspect-\[4\/5\] {
aspect-ratio: 4/5; aspect-ratio: 4/5;
} }
@@ -400,6 +417,9 @@
.h-2 { .h-2 {
height: calc(var(--spacing) * 2); height: calc(var(--spacing) * 2);
} }
.h-3 {
height: calc(var(--spacing) * 3);
}
.h-4 { .h-4 {
height: calc(var(--spacing) * 4); height: calc(var(--spacing) * 4);
} }
@@ -448,12 +468,18 @@
.w-10 { .w-10 {
width: calc(var(--spacing) * 10); width: calc(var(--spacing) * 10);
} }
.w-12 {
width: calc(var(--spacing) * 12);
}
.w-auto { .w-auto {
width: auto; width: auto;
} }
.w-full { .w-full {
width: 100%; width: 100%;
} }
.w-px {
width: 1px;
}
.max-w-3xl { .max-w-3xl {
max-width: var(--container-3xl); max-width: var(--container-3xl);
} }
@@ -481,6 +507,9 @@
.grow { .grow {
flex-grow: 1; flex-grow: 1;
} }
.border-collapse {
border-collapse: collapse;
}
.-translate-x-1\/2 { .-translate-x-1\/2 {
--tw-translate-x: calc(calc(1/2 * 100%) * -1); --tw-translate-x: calc(calc(1/2 * 100%) * -1);
translate: var(--tw-translate-x) var(--tw-translate-y); translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -492,6 +521,9 @@
.transform { .transform {
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,); transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
} }
.cursor-not-allowed {
cursor: not-allowed;
}
.cursor-pointer { .cursor-pointer {
cursor: pointer; cursor: pointer;
} }
@@ -553,6 +585,20 @@
margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse))); margin-block-end: calc(calc(var(--spacing) * 0) * calc(1 - var(--tw-space-y-reverse)));
} }
} }
.divide-y {
:where(& > :not(:last-child)) {
--tw-divide-y-reverse: 0;
border-bottom-style: var(--tw-border-style);
border-top-style: var(--tw-border-style);
border-top-width: calc(1px * var(--tw-divide-y-reverse));
border-bottom-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
}
}
.divide-slate-100 {
:where(& > :not(:last-child)) {
border-color: var(--color-slate-100);
}
}
.overflow-hidden { .overflow-hidden {
overflow: hidden; overflow: hidden;
} }
@@ -622,6 +668,9 @@
.border-slate-200 { .border-slate-200 {
border-color: var(--color-slate-200); border-color: var(--color-slate-200);
} }
.border-slate-300 {
border-color: var(--color-slate-300);
}
.border-slate-300\/30 { .border-slate-300\/30 {
border-color: color-mix(in srgb, oklch(86.9% 0.022 252.894) 30%, transparent); border-color: color-mix(in srgb, oklch(86.9% 0.022 252.894) 30%, transparent);
@supports (color: color-mix(in lab, red, red)) { @supports (color: color-mix(in lab, red, red)) {
@@ -640,6 +689,9 @@
.\!bg-green-600 { .\!bg-green-600 {
background-color: var(--color-green-600) !important; background-color: var(--color-green-600) !important;
} }
.bg-\[\#fae100\] {
background-color: #fae100;
}
.bg-amber-100 { .bg-amber-100 {
background-color: var(--color-amber-100); background-color: var(--color-amber-100);
} }
@@ -718,12 +770,6 @@
.bg-slate-900 { .bg-slate-900 {
background-color: var(--color-slate-900); background-color: var(--color-slate-900);
} }
.bg-slate-900\/10 {
background-color: color-mix(in srgb, oklch(20.8% 0.042 265.755) 10%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-slate-900) 10%, transparent);
}
}
.bg-teal-100 { .bg-teal-100 {
background-color: var(--color-teal-100); background-color: var(--color-teal-100);
} }
@@ -760,6 +806,9 @@
.p-1 { .p-1 {
padding: calc(var(--spacing) * 1); padding: calc(var(--spacing) * 1);
} }
.p-1\.5 {
padding: calc(var(--spacing) * 1.5);
}
.p-3 { .p-3 {
padding: calc(var(--spacing) * 3); padding: calc(var(--spacing) * 3);
} }
@@ -802,6 +851,9 @@
.py-12 { .py-12 {
padding-block: calc(var(--spacing) * 12); padding-block: calc(var(--spacing) * 12);
} }
.py-20 {
padding-block: calc(var(--spacing) * 20);
}
.pt-4 { .pt-4 {
padding-top: calc(var(--spacing) * 4); padding-top: calc(var(--spacing) * 4);
} }
@@ -820,9 +872,16 @@
.text-center { .text-center {
text-align: center; text-align: center;
} }
.text-left {
text-align: left;
}
.text-right { .text-right {
text-align: right; text-align: right;
} }
.text-6xl {
font-size: var(--text-6xl);
line-height: var(--tw-leading, var(--text-6xl--line-height));
}
.text-base { .text-base {
font-size: var(--text-base); font-size: var(--text-base);
line-height: var(--tw-leading, var(--text-base--line-height)); line-height: var(--tw-leading, var(--text-base--line-height));
@@ -843,6 +902,12 @@
font-size: var(--text-xs); font-size: var(--text-xs);
line-height: var(--tw-leading, var(--text-xs--line-height)); line-height: var(--tw-leading, var(--text-xs--line-height));
} }
.\!text-\[14px\] {
font-size: 14px !important;
}
.\!text-\[20px\] {
font-size: 20px !important;
}
.text-\[10px\] { .text-\[10px\] {
font-size: 10px; font-size: 10px;
} }
@@ -892,9 +957,6 @@
--tw-tracking: var(--tracking-widest); --tw-tracking: var(--tracking-widest);
letter-spacing: var(--tracking-widest); letter-spacing: var(--tracking-widest);
} }
.text-nowrap {
text-wrap: nowrap;
}
.wrap-break-word { .wrap-break-word {
overflow-wrap: break-word; overflow-wrap: break-word;
} }
@@ -908,6 +970,9 @@
.whitespace-nowrap { .whitespace-nowrap {
white-space: nowrap; white-space: nowrap;
} }
.text-\[\#3c1e1e\] {
color: #3c1e1e;
}
.text-\[\#111418\] { .text-\[\#111418\] {
color: #111418; color: #111418;
} }
@@ -959,6 +1024,9 @@
.text-sky-700 { .text-sky-700 {
color: var(--color-sky-700); color: var(--color-sky-700);
} }
.text-slate-300 {
color: var(--color-slate-300);
}
.text-slate-400 { .text-slate-400 {
color: var(--color-slate-400); color: var(--color-slate-400);
} }
@@ -968,6 +1036,9 @@
.text-slate-600 { .text-slate-600 {
color: var(--color-slate-600); color: var(--color-slate-600);
} }
.text-slate-800 {
color: var(--color-slate-800);
}
.text-slate-900 { .text-slate-900 {
color: var(--color-slate-900); color: var(--color-slate-900);
} }
@@ -983,6 +1054,9 @@
.line-through { .line-through {
text-decoration-line: line-through; text-decoration-line: line-through;
} }
.opacity-20 {
opacity: 20%;
}
.opacity-30 { .opacity-30 {
opacity: 30%; opacity: 30%;
} }
@@ -1086,6 +1160,20 @@
color: var(--color-slate-400); color: var(--color-slate-400);
} }
} }
.hover\:bg-\[\#f7d600\] {
&:hover {
@media (hover: hover) {
background-color: #f7d600;
}
}
}
.hover\:bg-slate-50 {
&:hover {
@media (hover: hover) {
background-color: var(--color-slate-50);
}
}
}
.hover\:bg-slate-100 { .hover\:bg-slate-100 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@@ -1100,6 +1188,13 @@
} }
} }
} }
.hover\:text-slate-600 {
&:hover {
@media (hover: hover) {
color: var(--color-slate-600);
}
}
}
.hover\:opacity-50 { .hover\:opacity-50 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@@ -1161,11 +1256,6 @@
grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-columns: repeat(2, minmax(0, 1fr));
} }
} }
.sm\:flex-row {
@media (width >= 40rem) {
flex-direction: row;
}
}
.sm\:items-center { .sm\:items-center {
@media (width >= 40rem) { @media (width >= 40rem) {
align-items: center; align-items: center;
@@ -1386,6 +1476,13 @@
grid-template-columns: repeat(5, minmax(0, 1fr)); grid-template-columns: repeat(5, minmax(0, 1fr));
} }
} }
.dark\:divide-slate-800 {
@media (prefers-color-scheme: dark) {
:where(& > :not(:last-child)) {
border-color: var(--color-slate-800);
}
}
}
.dark\:border-gray-800 { .dark\:border-gray-800 {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
border-color: var(--color-gray-800); border-color: var(--color-gray-800);
@@ -1509,6 +1606,14 @@
background-color: var(--color-slate-800); background-color: var(--color-slate-800);
} }
} }
.dark\:bg-slate-800\/50 {
@media (prefers-color-scheme: dark) {
background-color: color-mix(in srgb, oklch(27.9% 0.041 260.031) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-slate-800) 50%, transparent);
}
}
}
.dark\:bg-slate-900 { .dark\:bg-slate-900 {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
background-color: var(--color-slate-900); background-color: var(--color-slate-900);
@@ -1605,6 +1710,11 @@
color: var(--color-slate-100); color: var(--color-slate-100);
} }
} }
.dark\:text-slate-200 {
@media (prefers-color-scheme: dark) {
color: var(--color-slate-200);
}
}
.dark\:text-slate-300 { .dark\:text-slate-300 {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
color: var(--color-slate-300); color: var(--color-slate-300);
@@ -1620,6 +1730,11 @@
color: var(--color-slate-500); color: var(--color-slate-500);
} }
} }
.dark\:text-slate-700 {
@media (prefers-color-scheme: dark) {
color: var(--color-slate-700);
}
}
.dark\:text-slate-900 { .dark\:text-slate-900 {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
color: var(--color-slate-900); color: var(--color-slate-900);
@@ -1653,6 +1768,27 @@
} }
} }
} }
.dark\:hover\:bg-slate-800\/50 {
@media (prefers-color-scheme: dark) {
&:hover {
@media (hover: hover) {
background-color: color-mix(in srgb, oklch(27.9% 0.041 260.031) 50%, transparent);
@supports (color: color-mix(in lab, red, red)) {
background-color: color-mix(in oklab, var(--color-slate-800) 50%, transparent);
}
}
}
}
}
.dark\:hover\:text-slate-200 {
@media (prefers-color-scheme: dark) {
&:hover {
@media (hover: hover) {
color: var(--color-slate-200);
}
}
}
}
} }
@property --tw-translate-x { @property --tw-translate-x {
syntax: "*"; syntax: "*";
@@ -1694,6 +1830,11 @@
inherits: false; inherits: false;
initial-value: 0; initial-value: 0;
} }
@property --tw-divide-y-reverse {
syntax: "*";
inherits: false;
initial-value: 0;
}
@property --tw-border-style { @property --tw-border-style {
syntax: "*"; syntax: "*";
inherits: false; inherits: false;
@@ -1901,6 +2042,7 @@
--tw-skew-x: initial; --tw-skew-x: initial;
--tw-skew-y: initial; --tw-skew-y: initial;
--tw-space-y-reverse: 0; --tw-space-y-reverse: 0;
--tw-divide-y-reverse: 0;
--tw-border-style: solid; --tw-border-style: solid;
--tw-leading: initial; --tw-leading: initial;
--tw-font-weight: initial; --tw-font-weight: initial;