update skill ba
This commit is contained in:
137
.claude/skills/ba-design/templates/ds-components.css
Normal file
137
.claude/skills/ba-design/templates/ds-components.css
Normal file
@@ -0,0 +1,137 @@
|
||||
/* ds-components v1.1 — BEGIN
|
||||
CSS component của DS_<PROJECT>. Chỉ dùng biến --ds-* (tokens.css); cấm mã màu/px thô ngoài khối này.
|
||||
Từ vựng lớp = cột "Kiểu trình bày" của UICONV §11 (xem DS §3). Khối này được chép NGUYÊN VĂN vào
|
||||
components.html và mọi HIFI_*.html — kiểm khớp bằng scripts/design-check.mjs. */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
html{font-family:var(--ds-font-family-base);font-size:var(--ds-font-size-sm);line-height:var(--ds-font-line-height-normal);color:var(--ds-color-text-primary);background:var(--ds-color-bg-canvas);-webkit-font-smoothing:antialiased}
|
||||
body{margin:0}
|
||||
h1,h2,h3{margin:0;line-height:var(--ds-font-line-height-tight);font-weight:var(--ds-font-weight-semibold)}
|
||||
h1{font-size:var(--ds-font-size-xl)}h2{font-size:var(--ds-font-size-lg)}h3{font-size:var(--ds-font-size-md)}
|
||||
a,.ds-link{color:var(--ds-color-brand-primary);text-decoration:underline;text-underline-offset:2px;cursor:pointer}
|
||||
a:hover,.ds-link:hover{color:var(--ds-color-brand-primary-hover)}
|
||||
:focus-visible{outline:2px solid var(--ds-color-focus-ring);outline-offset:2px}
|
||||
.ds-muted{color:var(--ds-color-text-secondary)}
|
||||
.ds-small{font-size:var(--ds-font-size-xs)}
|
||||
.ds-icon{width:var(--ds-size-icon);height:var(--ds-size-icon);flex:none;stroke:currentColor;fill:none;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round}
|
||||
.ds-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
|
||||
|
||||
/* Layout */
|
||||
.ds-page{max-width:var(--ds-size-content-max);margin:0 auto;padding:var(--ds-space-6) var(--ds-space-4);display:grid;gap:var(--ds-space-4)}
|
||||
.ds-row{display:flex;gap:var(--ds-space-2);align-items:center;flex-wrap:wrap}
|
||||
.ds-row--between{justify-content:space-between}.ds-row--end{justify-content:flex-end}
|
||||
.ds-stack{display:grid;gap:var(--ds-space-3)}
|
||||
.ds-cols{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr);gap:var(--ds-space-4);align-items:start}
|
||||
.ds-header{position:sticky;top:0;z-index:5;background:var(--ds-color-bg-surface);border-bottom:1px solid var(--ds-color-border-default);padding:var(--ds-space-3) var(--ds-space-4);display:flex;align-items:center;gap:var(--ds-space-4);min-height:56px}
|
||||
.ds-breadcrumb{display:flex;gap:var(--ds-space-2);align-items:center;font-size:var(--ds-font-size-xs);color:var(--ds-color-text-secondary)}
|
||||
.ds-breadcrumb a{text-decoration:none}
|
||||
|
||||
/* Nút — UICONV §11: nút chính / nút phụ / nút nguy hiểm / liên kết */
|
||||
.ds-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--ds-space-2);height:var(--ds-size-control-desktop);padding:0 var(--ds-space-4);border-radius:var(--ds-radius-sm);border:1px solid transparent;font:inherit;font-weight:var(--ds-font-weight-semibold);cursor:pointer;white-space:nowrap;text-decoration:none;transition:background .12s}
|
||||
.ds-btn--primary{background:var(--ds-color-brand-primary);color:var(--ds-color-text-inverse)}
|
||||
.ds-btn--primary:hover{background:var(--ds-color-brand-primary-hover)}
|
||||
.ds-btn--secondary{background:var(--ds-color-bg-surface);color:var(--ds-color-text-primary);border-color:var(--ds-color-border-strong)}
|
||||
.ds-btn--secondary:hover{background:var(--ds-color-bg-subtle)}
|
||||
.ds-btn--danger{background:var(--ds-color-status-danger);color:var(--ds-color-text-inverse)}
|
||||
.ds-btn--ghost{background:transparent;color:var(--ds-color-brand-primary)}
|
||||
.ds-btn--icon{width:var(--ds-size-control-desktop);padding:0}
|
||||
.ds-btn[aria-disabled="true"],.ds-btn:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}
|
||||
.ds-btn.is-loading{pointer-events:none}
|
||||
.ds-spinner{width:16px;height:16px;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:ds-spin .8s linear infinite;flex:none}
|
||||
@keyframes ds-spin{to{transform:rotate(360deg)}}
|
||||
|
||||
/* Field — UICONV §4: nhãn trên field, * sau nhãn, lỗi dưới field thay hint */
|
||||
.ds-field{display:grid;gap:var(--ds-space-1)}
|
||||
.ds-field__label{font-size:var(--ds-font-size-xs);font-weight:var(--ds-font-weight-semibold);color:var(--ds-color-text-primary)}
|
||||
.ds-field__label .ds-req{color:var(--ds-color-status-danger);margin-left:2px}
|
||||
.ds-field__hint{font-size:var(--ds-font-size-xs);color:var(--ds-color-text-secondary)}
|
||||
.ds-field__error{font-size:var(--ds-font-size-xs);color:var(--ds-color-status-danger);display:flex;gap:var(--ds-space-1);align-items:center}
|
||||
.ds-input,.ds-select,.ds-textarea{width:100%;height:var(--ds-size-control-desktop);padding:0 var(--ds-space-3);border:1px solid var(--ds-color-border-strong);border-radius:var(--ds-radius-sm);background:var(--ds-color-bg-surface);color:var(--ds-color-text-primary);font:inherit}
|
||||
.ds-textarea{height:auto;min-height:88px;padding:var(--ds-space-2) var(--ds-space-3)}
|
||||
.ds-input::placeholder{color:var(--ds-color-text-secondary)}
|
||||
.ds-input:hover,.ds-select:hover{border-color:var(--ds-color-text-secondary)}
|
||||
.ds-input:focus,.ds-select:focus{border-color:var(--ds-color-brand-primary);outline:2px solid var(--ds-color-focus-ring);outline-offset:0}
|
||||
.ds-input.is-invalid,.ds-select.is-invalid{border-color:var(--ds-color-status-danger)}
|
||||
.ds-input[disabled],.ds-select[disabled]{background:var(--ds-color-bg-subtle);color:var(--ds-color-text-disabled);cursor:not-allowed}
|
||||
.ds-input[readonly]{border-color:transparent;background:transparent;padding-left:0}
|
||||
.ds-input-wrap{position:relative}
|
||||
.ds-input-wrap .ds-icon{position:absolute;left:var(--ds-space-3);top:50%;transform:translateY(-50%);color:var(--ds-color-text-secondary)}
|
||||
.ds-input-wrap .ds-input{padding-left:calc(var(--ds-space-3) + var(--ds-size-icon) + var(--ds-space-2))}
|
||||
.ds-select{appearance:none;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%235B6472' stroke-width='1.75'><path d='m4 6 4 4 4-4'/></svg>");background-repeat:no-repeat;background-position:right var(--ds-space-3) center;padding-right:calc(var(--ds-space-3) + 24px)}
|
||||
.ds-check{display:inline-flex;align-items:center;gap:var(--ds-space-2);cursor:pointer;min-height:var(--ds-size-control-desktop)}
|
||||
.ds-check input{width:18px;height:18px;margin:0;accent-color:var(--ds-color-brand-primary)}
|
||||
.ds-switch{position:relative;width:40px;height:22px;border-radius:var(--ds-radius-pill);background:var(--ds-color-border-strong);display:inline-block;flex:none}
|
||||
.ds-switch::after{content:"";position:absolute;top:2px;left:2px;width:18px;height:18px;border-radius:50%;background:var(--ds-color-bg-surface)}
|
||||
.ds-switch[aria-checked="true"]{background:var(--ds-color-brand-primary)}
|
||||
.ds-switch[aria-checked="true"]::after{left:20px}
|
||||
.ds-stepper{display:inline-flex;border:1px solid var(--ds-color-border-strong);border-radius:var(--ds-radius-sm);height:var(--ds-size-control-desktop);overflow:hidden}
|
||||
.ds-stepper button{width:var(--ds-size-control-desktop);border:0;background:var(--ds-color-bg-surface);font:inherit;cursor:pointer;color:var(--ds-color-text-primary)}
|
||||
.ds-stepper input{width:48px;text-align:center;border:0;border-left:1px solid var(--ds-color-border-default);border-right:1px solid var(--ds-color-border-default);font:inherit}
|
||||
|
||||
/* Bảng / Card — UICONV §3, §11 */
|
||||
.ds-table-wrap{overflow-x:auto;border:1px solid var(--ds-color-border-default);border-radius:var(--ds-radius-md);background:var(--ds-color-bg-surface)}
|
||||
.ds-table{width:100%;border-collapse:collapse;font-size:var(--ds-font-size-sm)}
|
||||
.ds-table th,.ds-table td{padding:var(--ds-space-3) var(--ds-space-4);text-align:left;border-bottom:1px solid var(--ds-color-border-default);vertical-align:middle}
|
||||
.ds-table th{background:var(--ds-color-bg-subtle);font-weight:var(--ds-font-weight-semibold);font-size:var(--ds-font-size-xs);color:var(--ds-color-text-secondary);white-space:nowrap}
|
||||
.ds-table th[aria-sort]{cursor:pointer}
|
||||
.ds-table tbody tr:hover{background:var(--ds-color-bg-canvas)}
|
||||
.ds-table tbody tr[aria-selected="true"]{background:var(--ds-color-brand-primary-subtle)}
|
||||
.ds-table tbody tr:last-child td{border-bottom:0}
|
||||
.ds-table td.ds-num{text-align:right;font-variant-numeric:tabular-nums}
|
||||
.ds-card{background:var(--ds-color-bg-surface);border:1px solid var(--ds-color-border-default);border-radius:var(--ds-radius-md);padding:var(--ds-space-4);display:grid;gap:var(--ds-space-2)}
|
||||
.ds-cards{display:grid;gap:var(--ds-space-3)}
|
||||
.ds-badge{display:inline-flex;align-items:center;height:22px;padding:0 var(--ds-space-2);border-radius:var(--ds-radius-pill);font-size:var(--ds-font-size-xs);font-weight:var(--ds-font-weight-semibold);background:var(--ds-color-bg-subtle);color:var(--ds-color-text-primary)}
|
||||
.ds-badge--info{background:var(--ds-color-brand-primary-subtle)}
|
||||
.ds-badge--success{background:var(--ds-color-status-success-subtle);color:var(--ds-color-status-success)}
|
||||
.ds-badge--warning{background:var(--ds-color-status-warning-subtle);color:var(--ds-color-status-warning)}
|
||||
.ds-badge--danger{background:var(--ds-color-status-danger-subtle);color:var(--ds-color-status-danger)}
|
||||
.ds-tabs{display:flex;gap:var(--ds-space-4);border-bottom:1px solid var(--ds-color-border-default)}
|
||||
.ds-tab{padding:var(--ds-space-2) 0;border-bottom:2px solid transparent;color:var(--ds-color-text-secondary);cursor:pointer;font-weight:var(--ds-font-weight-semibold)}
|
||||
.ds-tab[aria-selected="true"]{color:var(--ds-color-brand-primary);border-bottom-color:var(--ds-color-brand-primary)}
|
||||
.ds-pagination{display:flex;gap:var(--ds-space-2);align-items:center;font-size:var(--ds-font-size-xs);color:var(--ds-color-text-secondary)}
|
||||
.ds-price{font-variant-numeric:tabular-nums;font-weight:var(--ds-font-weight-semibold)}
|
||||
.ds-thumb{width:64px;height:64px;border-radius:var(--ds-radius-sm);background:var(--ds-color-bg-subtle);border:1px solid var(--ds-color-border-default);display:grid;place-items:center;color:var(--ds-color-text-secondary);flex:none}
|
||||
|
||||
/* Phản hồi hệ thống — UICONV §5, §6 */
|
||||
.ds-toast{position:fixed;top:var(--ds-space-4);right:var(--ds-space-4);z-index:20;min-width:280px;max-width:420px;padding:var(--ds-space-3) var(--ds-space-4);border-radius:var(--ds-radius-md);background:var(--ds-color-text-primary);color:var(--ds-color-text-inverse);box-shadow:var(--ds-shadow-md);display:flex;gap:var(--ds-space-3);align-items:flex-start}
|
||||
.ds-toast--error{background:var(--ds-color-status-danger)}
|
||||
.ds-banner{display:flex;gap:var(--ds-space-3);align-items:flex-start;padding:var(--ds-space-3) var(--ds-space-4);border-radius:var(--ds-radius-md);border:1px solid var(--ds-color-border-default);background:var(--ds-color-bg-subtle)}
|
||||
.ds-banner--error{background:var(--ds-color-status-danger-subtle);border-color:var(--ds-color-status-danger);color:var(--ds-color-status-danger)}
|
||||
.ds-banner--warning{background:var(--ds-color-status-warning-subtle);border-color:var(--ds-color-status-warning)}
|
||||
.ds-empty{display:grid;justify-items:center;text-align:center;gap:var(--ds-space-3);padding:var(--ds-space-12) var(--ds-space-4);color:var(--ds-color-text-secondary)}
|
||||
.ds-empty__illus{width:120px;height:88px;color:var(--ds-color-border-strong)}
|
||||
.ds-empty--filter{padding:var(--ds-space-8) var(--ds-space-4)}
|
||||
.ds-skeleton{height:14px;border-radius:var(--ds-radius-sm);background:linear-gradient(90deg,var(--ds-color-bg-subtle),var(--ds-color-bg-canvas),var(--ds-color-bg-subtle));background-size:200% 100%;animation:ds-shimmer 1.2s infinite}
|
||||
@keyframes ds-shimmer{to{background-position:-200% 0}}
|
||||
.ds-modal-backdrop{position:fixed;inset:0;background:#1B1F2480;display:grid;place-items:center;z-index:10;padding:var(--ds-space-4)}
|
||||
.ds-modal{width:100%;max-width:520px;background:var(--ds-color-bg-surface);border-radius:var(--ds-radius-md);box-shadow:var(--ds-shadow-md);display:grid}
|
||||
.ds-modal__head{display:flex;justify-content:space-between;align-items:center;padding:var(--ds-space-4) var(--ds-space-6);border-bottom:1px solid var(--ds-color-border-default)}
|
||||
.ds-modal__body{padding:var(--ds-space-6);display:grid;gap:var(--ds-space-4)}
|
||||
.ds-modal__foot{display:flex;justify-content:flex-end;gap:var(--ds-space-2);padding:var(--ds-space-4) var(--ds-space-6);border-top:1px solid var(--ds-color-border-default)}
|
||||
.ds-status-page{display:grid;justify-items:center;gap:var(--ds-space-3);padding:var(--ds-space-12);text-align:center}
|
||||
|
||||
/* Trạng thái ẩn/khoá/read-only — W7 */
|
||||
[data-vis="hidden"]{display:none!important}
|
||||
[data-vis="disabled"]{opacity:.45;pointer-events:none}
|
||||
[data-vis="readonly"] .ds-input{border-color:transparent;background:transparent}
|
||||
|
||||
/* Responsive — breakpoint theo UICONV §1; body[data-view] ép khung nhìn khi xem trong HIFI */
|
||||
@media (max-width:1023px){.ds-cols{grid-template-columns:1fr}}
|
||||
@media (max-width:767px){
|
||||
.ds-page{padding:var(--ds-space-4) var(--ds-space-3)}
|
||||
.ds-btn{height:var(--ds-size-control-touch)}
|
||||
.ds-input,.ds-select{height:var(--ds-size-control-touch)}
|
||||
.ds-table-wrap{display:none}.ds-cards{display:grid}
|
||||
.ds-hide-m{display:none!important}
|
||||
}
|
||||
@media (min-width:768px){.ds-cards{display:none}.ds-hide-d{display:none!important}}
|
||||
body[data-view="mobile"] .ds-cols{grid-template-columns:1fr}
|
||||
body[data-view="mobile"] .ds-table-wrap{display:none}body[data-view="mobile"] .ds-cards{display:grid}
|
||||
body[data-view="mobile"] .ds-hide-m{display:none!important}body[data-view="mobile"] .ds-hide-d{display:revert}
|
||||
body[data-view="mobile"] .ds-btn,body[data-view="mobile"] .ds-input,body[data-view="mobile"] .ds-select{height:var(--ds-size-control-touch)}
|
||||
body[data-view="mobile"] .ds-page{padding:var(--ds-space-4) var(--ds-space-3)}
|
||||
body[data-view="tablet"] .ds-cols{grid-template-columns:1fr}
|
||||
/* Tiện ích xếp chồng ở mobile: phần tử trong .ds-row chiếm trọn hàng (nhóm nút thao tác của một dòng danh sách/CartItem…) */
|
||||
.ds-m-full{}
|
||||
@media (max-width:767px){.ds-m-full{flex-basis:100%;min-width:0}}
|
||||
body[data-view="mobile"] .ds-m-full{flex-basis:100%;min-width:0}
|
||||
/* ds-components v1.1 — END */
|
||||
Reference in New Issue
Block a user