/** * EwoooC Dot Matrix v3.0 — Production * ───────────────────────────────────────────────────────────── * 受 Nothing Phone Dot Matrix 啟發的點陣視覺語言 * * 適用場景(已導入): * ① Brand mark .momo-logo-mark (在 ewoooc-shell.css) * ② Section divider .momo-dot-divider * ⑥ Active nav .momo-nav-link.is-active 左側 3 顆豎排 dot * ⑦ Progress bar .momo-dot-meter, .momo-dot-progress * * 不適用場景(不要套): * ❌ 表格背景 / 大面積 paper 底 / 卡片背景 / KPI strip 背景 * * 載入順序:tokens.css → shell.css → dotmatrix.css → page-level * * 工程備註: * 點陣圖樣統一走 background-image: radial-gradient(circle, ...) * color 全部吃 currentColor,由父層字色決定,不要寫死 # */ /* ════════════════════════════════════════════════════════ * ② Section Divider — 點陣分隔線 * ════════════════════════════════════════════════════════ * 用法:
* 變體:.is-tight (10px 間距) / .is-loose (14px) / .is-wide (18px) * .is-soft (低濃度) / .is-strong (高濃度) * .is-accent (吃群組色,取代 currentColor) * 情境:取代 1px solid 線,用於 section / hero / card 分隔 * 建議:每頁最多用 3-4 條,避免變裝飾 noise */ .momo-dot-divider { height: 7px; width: 100%; background-image: radial-gradient( circle, currentColor var(--momo-dot-radius), transparent calc(var(--momo-dot-radius) + 0.5px) ); background-size: var(--momo-dot-size-base) 7px; background-repeat: repeat-x; background-position: center; color: var(--momo-text-tertiary); opacity: var(--momo-dot-alpha-strong); } .momo-dot-divider.is-tight { background-size: var(--momo-dot-size-tight) 7px; } .momo-dot-divider.is-loose { background-size: var(--momo-dot-size-loose) 7px; } .momo-dot-divider.is-wide { background-size: var(--momo-dot-size-wide) 7px; } .momo-dot-divider.is-soft { opacity: var(--momo-dot-alpha-mid); } .momo-dot-divider.is-whisper { opacity: var(--momo-dot-alpha-soft); } .momo-dot-divider.is-accent { color: var(--momo-page-accent); opacity: 0.85; } .momo-dot-divider.is-ink { color: var(--momo-ink); } /* 垂直變體 — 用於 column 之間 */ .momo-dot-divider-v { width: 7px; height: 100%; min-height: 32px; background-image: radial-gradient( circle, currentColor var(--momo-dot-radius), transparent calc(var(--momo-dot-radius) + 0.5px) ); background-size: 7px var(--momo-dot-size-base); background-repeat: repeat-y; background-position: center; color: var(--momo-text-tertiary); opacity: var(--momo-dot-alpha-strong); } /* ════════════════════════════════════════════════════════ * ⑥ Active Nav Indicator — 左側 3 顆豎排 dot * ════════════════════════════════════════════════════════ * 取代原本的 3px 直線 active 指示 * 附著在 .momo-nav-link.is-active 上 * 暖色點亮時有「指示燈」感 * * 注意:此 selector 會 override ewoooc-shell.css 的 .is-active 樣式 */ .momo-nav-link.is-active, .momo-nav-sublink.is-active { position: relative; } .momo-nav-link.is-active::before { content: ""; position: absolute; left: 4px; top: 50%; transform: translateY(-50%); width: 3px; height: 16px; background-image: radial-gradient( circle, var(--momo-page-accent-dark) 1.2px, transparent 1.7px ); background-size: 3px 5px; background-repeat: repeat-y; background-position: center; opacity: 1; } /* sublink 的 active 是淡底 + 深字,dot 顏色要吃 accent-dark */ .momo-nav-sublink.is-active::before { content: ""; position: absolute; left: -10px; top: 50%; transform: translateY(-50%); width: 3px; height: 14px; background-image: radial-gradient( circle, var(--momo-page-accent-dark) 1.1px, transparent 1.6px ); background-size: 3px 5px; background-repeat: repeat-y; background-position: center; } /* ════════════════════════════════════════════════════════ * ⑦ Dot Meter / Progress — 點陣刻度 * ════════════════════════════════════════════════════════ * .momo-dot-meter 固定 20 顆 dot(5×4 或單列),用 --filled 控制亮起數量 * .momo-dot-progress 橫向長條 dot 刻度,根據百分比亮起 * .momo-dot-threshold 3 段閾值(70/85/95)— 對齊 P0/P1/P2 警示語言 * * 設計動機:取代連續長條,視覺上更像「監控儀表」 * 常用情境:預算用量、配額、健康度、進度、SLA */ /* 7-1: 點陣長條(單列) */ .momo-dot-progress { --momo-dot-progress-pct: 0; /* 0-100 */ --momo-dot-progress-track: var(--momo-text-tertiary); --momo-dot-progress-fill: var(--momo-page-accent); position: relative; display: block; height: 12px; background-image: radial-gradient( circle, var(--momo-dot-progress-track) 1.2px, transparent 1.7px ); background-size: 8px 12px; background-repeat: repeat-x; background-position: left center; opacity: 1; } .momo-dot-progress::before { content: ""; position: absolute; inset: 0; width: calc(var(--momo-dot-progress-pct) * 1%); background-image: radial-gradient( circle, var(--momo-dot-progress-fill) 1.4px, transparent 1.9px ); background-size: 8px 12px; background-repeat: repeat-x; background-position: left center; transition: width 0.4s cubic-bezier(0.4, 0, 0.2, 1); } /* 7-2: 三段閾值刻度(70/85/95) */ .momo-dot-threshold { position: relative; display: grid; grid-template-columns: 70fr 15fr 10fr 5fr; gap: 4px; height: 14px; } .momo-dot-threshold > span { display: block; height: 100%; background-image: radial-gradient( circle, currentColor 1.2px, transparent 1.7px ); background-size: 8px 14px; background-repeat: repeat-x; background-position: left center; border-radius: 1px; } .momo-dot-threshold > span:nth-child(1) { color: var(--momo-success); } .momo-dot-threshold > span:nth-child(2) { color: var(--momo-warning); } .momo-dot-threshold > span:nth-child(3) { color: var(--momo-page-accent); } .momo-dot-threshold > span:nth-child(4) { color: var(--momo-danger); } /* 失活段:濃度降到 whisper */ .momo-dot-threshold.is-stage-1 > span:nth-child(n+2) { opacity: var(--momo-dot-alpha-whisper); } .momo-dot-threshold.is-stage-2 > span:nth-child(n+3) { opacity: var(--momo-dot-alpha-whisper); } .momo-dot-threshold.is-stage-3 > span:nth-child(n+4) { opacity: var(--momo-dot-alpha-whisper); } /* stage-4 全亮 */ .momo-dot-threshold-labels { display: grid; grid-template-columns: 70fr 15fr 10fr 5fr; gap: 4px; margin-top: 4px; font-family: var(--momo-font-mono); font-size: var(--momo-text-label-tiny); color: var(--momo-text-tertiary); letter-spacing: 0.04em; } .momo-dot-threshold-labels > span { text-align: right; } /* 7-3: 5×4 矩陣(20 點,用於緊湊空間,例如 KPI 卡內) */ .momo-dot-meter { --momo-dot-meter-filled: 0; /* 0-20 */ display: grid; grid-template-columns: repeat(20, 1fr); gap: 2px; height: 8px; width: 100%; max-width: 180px; } .momo-dot-meter > span { display: block; height: 8px; border-radius: 50%; background: var(--momo-text-tertiary); opacity: var(--momo-dot-alpha-soft); } /* :nth-child 控制亮起前 N 顆 — 配合 inline style --momo-dot-meter-filled 不夠彈性, 實務做法:在 HTML 直接給前 N 顆 .is-on class,後 20-N 顆不加 */ .momo-dot-meter > span.is-on { background: var(--momo-page-accent); opacity: 1; } .momo-dot-meter.is-warn > span.is-on { background: var(--momo-warning); } .momo-dot-meter.is-danger > span.is-on { background: var(--momo-danger); } /* ════════════════════════════════════════════════════════ * 共用:載入點陣(為將來 ④ Loading 預留 hook) * ════════════════════════════════════════════════════════ */ @keyframes momo-dot-scan { 0%, 100% { opacity: var(--momo-dot-alpha-soft); } 50% { opacity: var(--momo-dot-alpha-strong); } } /* ════════════════════════════════════════════════════════ * ⑧ Brand Mark 強化(針對 .momo-logo-mark 已存在於 shell.css) * ════════════════════════════════════════════════════════ * ewoooc-shell.css 已有 .momo-logo-mark,這裡額外提供: * .momo-logo-mark.is-accent 底色改為群組 accent * .momo-logo-mark.is-large 32×32 用於 hero * .momo-logo-mark.is-tiny 18×18 用於 inline */ .momo-logo-mark.is-accent { background: var(--momo-page-accent); color: var(--momo-page-inverse); } .momo-logo-mark.is-large { width: 32px; height: 32px; gap: 2px; padding: 5px; } .momo-logo-mark.is-tiny { width: 18px; height: 18px; gap: 1px; padding: 2.5px; border-radius: 1px; } /* hero 點陣大標 — 取代裝飾性 mono 標籤 */ .momo-dot-eyebrow { display: inline-flex; align-items: center; gap: 8px; padding: 4px 10px 4px 6px; background: var(--momo-bg-paper); border: 1px solid var(--momo-border-light); border-radius: var(--momo-radius-pill); font-family: var(--momo-font-mono); font-size: var(--momo-text-label); font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--momo-text-secondary); } .momo-dot-eyebrow .momo-logo-mark { width: 14px; height: 14px; gap: 1px; padding: 1.5px; border-radius: 1px; }