Files
sankey/src/styles.css
2026-02-14 15:49:09 +08:00

1063 lines
16 KiB
CSS

:root {
--primary-7: #8552a1;
--primary-6: #9b6bc2;
--fill-1: #f7f8fa;
--fill-3: #e5e6eb;
--fill-4: #c9cdd4;
--text-1: #ffffff;
--text-3: #86909c;
--text-4: #4e5969;
--danger-3: #fbaca3;
--font-pingfang: 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
}
* {
box-sizing: border-box;
}
html,
body,
#app {
margin: 0;
min-height: 100%;
}
body {
background: #f3f4f6;
color: #1d2129;
font-family: var(--font-pingfang);
}
.page {
position: relative;
width: 100%;
height: calc(var(--app-vh, 1vh) * 100);
padding: 16px 16px 10px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.top-bar {
position: relative;
display: flex;
justify-content: space-between;
gap: 16px;
align-items: center;
margin-bottom: 12px;
padding: 0 8px;
}
.brand {
display: flex;
align-items: center;
gap: 8px;
}
.logo {
width: 64px;
height: 64px;
border-radius: 16px;
}
.title-logo {
width: 174px;
height: auto;
}
.toolbar {
display: flex;
align-items: center;
gap: 12px;
flex: 1;
justify-content: flex-end;
}
.tool-item {
display: flex;
align-items: center;
gap: 4px;
}
.theme-trigger {
position: relative;
}
.tool-label {
color: #1d2129;
font-size: 14px;
white-space: nowrap;
}
.icon-btn {
border: 0;
background: transparent;
cursor: pointer;
padding: 0;
width: 36px;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.icon-btn img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
.upload-area {
min-width: 280px;
max-width: 420px;
flex: 1;
min-height: 38px;
border-radius: 6px;
display: flex;
align-items: center;
padding: 4px 10px;
background: var(--fill-1);
border: 1px solid var(--fill-3);
cursor: pointer;
position: relative;
}
.hidden-input {
display: none;
}
.upload-text {
color: var(--text-4);
font-size: 12px;
}
.export-box {
display: flex;
gap: 6px;
align-items: center;
background: #fff;
border: 1px solid var(--fill-3);
border-radius: 8px;
padding: 2px 8px;
}
.export-main {
width: 18px;
height: 34px;
}
.export-item {
width: 40px;
height: 40px;
}
.theme-popover {
position: fixed;
width: 292px;
border: 1px solid var(--primary-7);
border-radius: 24px 24px 0 0;
background: #fff;
z-index: 10;
padding: 8px 8px 10px;
}
.theme-popover::before {
content: '';
position: absolute;
top: -8px;
left: var(--theme-arrow-left, 50%);
width: 14px;
height: 14px;
background: #fff;
border-top: 1px solid var(--primary-7);
border-left: 1px solid var(--primary-7);
transform: translateX(-50%) rotate(45deg);
}
.theme-header {
text-align: center;
color: var(--primary-6);
font-size: 15px;
margin-bottom: 6px;
}
.theme-wheel-wrap {
--theme-row-height: 42px;
position: relative;
height: calc(var(--theme-row-height) * 5);
overflow: hidden;
}
.theme-wheel {
height: 100%;
overflow-y: auto;
padding-block: calc(var(--theme-row-height) * 2);
margin: 0;
scrollbar-width: thin;
scrollbar-color: #d6d8dc #fff;
}
.theme-wheel::-webkit-scrollbar {
width: 6px;
}
.theme-wheel::-webkit-scrollbar-track {
background: #fff;
}
.theme-wheel::-webkit-scrollbar-thumb {
background: #d6d8dc;
border-radius: 999px;
}
.theme-mask {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 3;
background: linear-gradient(
180deg,
#ffffff 0%,
rgba(255, 255, 255, 0.74) 20%,
rgba(255, 255, 255, 0) 35%,
rgba(255, 255, 255, 0) 65%,
rgba(255, 255, 255, 0.74) 80%,
#ffffff 100%
);
}
.theme-row {
width: 100%;
border: 0;
background: #fff;
display: flex;
align-items: center;
gap: 8px;
height: 42px;
padding: 5px 6px;
cursor: pointer;
transition: opacity 0.2s ease;
}
.theme-row.selected {
opacity: 1;
}
.theme-row img {
width: 18px;
height: 18px;
}
.palette {
flex: 1;
display: grid;
height: 20px;
border-radius: 2px;
overflow: hidden;
position: relative;
}
/* 选中分割线挂在色条本身,滚动时与选中项一起移动,长度与色条完全一致。 */
.theme-row.selected .palette::before,
.theme-row.selected .palette::after {
content: '';
position: absolute;
left: 0;
right: 0;
border-top: 1px solid var(--fill-3);
}
.theme-row.selected .palette::before {
top: 0;
}
.theme-row.selected .palette::after {
bottom: 0;
}
.palette-cell {
display: block;
}
/* Weixin (微信小程序) 弹窗 */
.weixin-trigger {
position: relative;
}
.weixin-popover {
position: fixed;
top: 70px;
right: 16px;
width: 180px;
border: 1px solid var(--primary-7);
border-radius: 12px;
background: #fff;
z-index: 100;
padding: 12px;
text-align: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.weixin-popover::before {
content: '';
position: absolute;
top: -8px;
right: 16px;
width: 14px;
height: 14px;
background: #fff;
border-top: 1px solid var(--primary-7);
border-left: 1px solid var(--primary-7);
transform: rotate(45deg);
}
.weixin-header {
color: var(--primary-6);
font-size: 14px;
margin-bottom: 12px;
}
.weixin-qrcode {
width: 140px;
height: 140px;
border-radius: 8px;
}
.weixin-btn {
width: auto;
height: auto;
}
.weixin-btn img {
height: 42px;
width: auto;
max-height: none;
}
.content {
display: grid;
grid-template-columns: 360px 1fr;
gap: 8px;
flex: 1;
min-height: 0;
}
.left-pane {
display: flex;
flex-direction: column;
gap: 10px;
min-height: 0;
}
.panel {
border: 1px solid #f7dede;
border-radius: 16px;
background: #fff;
}
.block-panel {
padding: 8px 8px 10px;
}
.select-panel {
flex: 1;
min-height: 0;
overflow: auto;
}
.panel-title-svg {
display: block;
max-width: 100%;
height: auto;
}
.panel-title-select {
width: 189px;
}
.panel-title-preview {
width: 238px;
}
.panel-title-info {
width: 186px;
}
.field-block {
margin-top: 14px;
position: relative;
}
.field-title-wrap {
width: 100%;
border: 0;
background: transparent;
padding: 0;
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 8px;
cursor: pointer;
text-align: left;
}
.field-title-wrap h3 {
margin: 0;
font-size: 18px;
font-weight: 500;
}
.expand-icon {
width: 20px;
height: 20px;
}
.column-list {
position: relative;
--connector-x: 10px;
--icon-left: 20px;
--row-height: 32px;
--connector-top-offset: -6px;
}
/* 展开后显示分类到列表项的树状连线,严格限制到首尾项中线。 */
.column-list::before {
content: '';
position: absolute;
left: var(--connector-x);
top: var(--connector-top-offset);
bottom: calc(var(--row-height) / 2);
border-left: 1px solid var(--fill-4);
}
.column-row {
position: relative;
display: flex;
align-items: center;
gap: 8px;
height: 32px;
padding-bottom: 6px;
padding-left: var(--icon-left);
}
.column-row::before {
content: '';
position: absolute;
left: var(--connector-x);
top: calc(50% - 0.5px);
width: calc(var(--icon-left) - var(--connector-x));
border-top: 1px solid var(--fill-4);
}
.column-row::after {
content: '';
position: absolute;
left: var(--icon-left);
right: 0;
bottom: 0;
border-top: 1px solid var(--fill-4);
}
.column-icon {
width: 18px;
height: 18px;
}
.column-label {
flex: 1;
color: var(--text-3);
font-size: 12px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.select-btn {
border: 0;
background: transparent;
cursor: pointer;
padding: 0;
width: 16px;
height: 16px;
}
.select-btn img {
width: 16px;
height: 16px;
}
.preview-panel {
padding: 8px;
display: flex;
flex-direction: column;
min-height: 0;
}
.preview-head {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: center;
min-height: 60px;
margin-bottom: 8px;
}
.preview-controls {
display: flex;
align-items: center;
gap: 24px;
}
.desktop-only {
display: inline-flex;
}
.mobile-only {
display: none;
}
.preview-controls .slider-label {
display: inline-flex;
align-items: center;
gap: 6px;
width: 148px;
}
.slider-track-wrap {
position: relative;
width: 122px;
height: 24px;
}
.slider-icon {
width: 20px;
height: 20px;
flex-shrink: 0;
}
.slider-input {
width: 100%;
height: 24px;
margin: 0;
background: transparent;
-webkit-appearance: none;
appearance: none;
}
.slider-input::-webkit-slider-runnable-track {
height: 4px;
border-radius: 999px;
background: linear-gradient(
to right,
var(--primary-6) 0,
var(--primary-6) var(--slider-percent, 0%),
var(--fill-3) var(--slider-percent, 0%),
var(--fill-3) 100%
);
}
.slider-input::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
border: 1px solid var(--fill-3);
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
margin-top: -7px;
}
.slider-input::-moz-range-track {
height: 4px;
border-radius: 999px;
background: var(--fill-3);
}
.slider-input::-moz-range-thumb {
width: 18px;
height: 18px;
border-radius: 50%;
border: 1px solid var(--fill-3);
background: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
.slider-input::-moz-range-progress {
height: 4px;
border-radius: 999px;
background: var(--primary-6);
}
.slider-value {
position: absolute;
top: -13px;
transform: translateX(-50%);
font-size: 10px;
line-height: 1;
color: var(--primary-6);
white-space: nowrap;
pointer-events: none;
}
.direction-control {
display: inline-flex;
align-items: center;
gap: 4px;
border: 0;
background: transparent;
padding: 0;
cursor: pointer;
flex-shrink: 0;
}
.direction-label {
font-size: 14px;
font-weight: 600;
color: #000;
line-height: 1;
}
.direction-switch {
display: inline-flex;
align-items: center;
gap: 1px;
min-width: 0;
width: auto;
height: 14px;
padding: 1px;
border-radius: 58.333px;
background: var(--fill-3);
justify-content: space-between;
}
.direction-switch-text {
font-size: 8px;
line-height: 1;
padding: 0 1px;
white-space: nowrap;
color: var(--text-4);
}
.direction-switch-thumb {
width: 11.667px;
height: 11.667px;
border-radius: 50%;
background: #fff;
border: 0;
box-shadow: none;
}
.direction-switch.on {
background: var(--primary-6);
}
.direction-switch.on .direction-switch-text {
color: #fff;
}
.direction-switch:not(.on) {
flex-direction: row-reverse;
}
.label-position-control {
display: inline-flex;
align-items: center;
gap: 6px;
}
.label-position-label {
font-size: 14px;
font-weight: 600;
color: #000;
line-height: 1;
white-space: nowrap;
}
.label-position-select {
min-width: 0;
}
.target-align-control {
display: inline-flex;
align-items: center;
gap: 6px;
}
.target-align-label {
font-size: 14px;
font-weight: 600;
color: #000;
line-height: 1;
white-space: nowrap;
}
.target-align-select {
min-width: 0;
}
.compact-control {
display: inline-flex;
align-items: center;
gap: 4px;
}
.compact-label {
font-size: 12px;
font-weight: 600;
color: #000;
line-height: 1;
white-space: nowrap;
}
.compact-select {
min-width: 0;
}
.label-position-select,
.target-align-select,
.compact-select {
width: auto;
inline-size: max-content;
height: 14px;
border: 0.5px solid #c9aee0;
border-radius: 4px;
background: #fff;
color: #1d2129;
font-size: 12px;
line-height: 1;
padding: 0 14px 0 4px;
appearance: none;
-webkit-appearance: none;
background-image: url('../assets/icons/list.svg');
background-repeat: no-repeat;
background-position: right 2px center;
background-size: 10px 8px;
flex-shrink: 0;
}
.example-line {
margin: 4px 0 8px;
color: var(--text-4);
font-size: 12px;
}
.chart-area {
background: var(--fill-1);
border-radius: 8px;
flex: 1;
min-height: 0;
}
.info-panel {
padding: 8px;
min-height: 120px;
max-height: 220px;
display: flex;
flex-direction: column;
gap: 8px;
overflow: hidden;
}
.info-log-list {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
gap: 4px;
overflow: auto;
}
.info-log-item {
font-size: 12px;
line-height: 1.45;
color: var(--text-4);
}
.info-log-item.level-warn {
color: #8d5b00;
}
.info-log-item.level-error {
color: #cb272d;
}
.info-log-empty {
margin: 0;
font-size: 12px;
color: var(--text-3);
}
.footer {
margin-top: 6px;
flex-shrink: 0;
color: var(--text-3);
font-size: 16px;
}
@media (max-width: 1024px) {
.top-bar {
flex-direction: column;
align-items: stretch;
}
.toolbar {
justify-content: flex-start;
flex-wrap: nowrap;
overflow-x: auto;
overflow-y: hidden;
gap: 8px;
scrollbar-width: none;
}
.toolbar::-webkit-scrollbar {
display: none;
}
.tool-item,
.export-box,
.upload-area {
flex-shrink: 0;
}
.weixin-popover {
top: 120px;
right: 50%;
transform: translateX(50%);
}
.weixin-popover::before {
display: none;
}
.content {
display: flex;
flex-direction: column;
overflow: hidden;
}
.preview-panel {
order: 1;
flex: 1;
min-height: 0;
}
.left-pane {
order: 2;
min-height: 0;
max-height: 42%;
overflow: auto;
}
.block-panel {
min-height: auto;
}
.chart-area {
min-height: 0;
}
.preview-head {
min-height: auto;
align-items: center;
flex-direction: row;
gap: 8px;
}
.preview-controls {
flex-wrap: nowrap;
gap: 8px;
overflow-x: auto;
overflow-y: hidden;
justify-content: flex-start;
scrollbar-width: none;
}
.preview-controls::-webkit-scrollbar {
display: none;
}
.preview-controls .slider-label {
width: 120px;
}
.slider-track-wrap {
width: 96px;
}
.label-position-control {
margin-left: 0;
flex-shrink: 0;
}
.target-align-control {
margin-left: 0;
flex-shrink: 0;
}
.info-panel {
max-height: 180px;
}
.footer {
font-size: 14px;
}
}
@media (max-width: 640px) {
.page {
padding: 8px;
}
.logo {
width: 48px;
height: 48px;
border-radius: 12px;
}
.title-logo {
width: 160px;
}
.tool-label {
font-size: 12px;
}
.upload-area {
display: flex;
min-width: 92px;
max-width: none;
flex: 1 1 auto;
min-height: 28px;
padding: 2px 5px;
}
.upload-text {
font-size: 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.top-bar {
padding: 0;
gap: 6px;
}
.toolbar {
width: 100%;
flex-wrap: nowrap;
overflow: hidden;
justify-content: flex-start;
gap: 4px;
}
.tool-item .tool-label {
display: none;
}
.tool-item,
.export-box {
flex-shrink: 0;
}
.tool-item .icon-btn {
width: 28px;
height: 28px;
}
.export-box {
padding: 1px 4px;
gap: 4px;
}
.export-main {
display: block;
width: 12px;
height: 24px;
}
.export-item {
width: 28px;
height: 28px;
}
.content {
gap: 6px;
}
.left-pane {
max-height: 46%;
}
.field-title-wrap h3 {
font-size: 16px;
}
.panel-title-preview {
width: 190px;
}
.preview-head {
gap: 4px;
}
.preview-controls {
width: 100%;
flex-wrap: nowrap;
gap: 4px;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: none;
justify-content: flex-start;
}
.preview-controls::-webkit-scrollbar {
display: none;
}
.desktop-only {
display: none;
}
.mobile-only {
display: inline-flex;
}
.preview-controls .slider-label {
width: 74px;
}
.slider-track-wrap {
width: 61px;
}
.label-position-control,
.target-align-control {
gap: 4px;
flex-shrink: 0;
}
.label-position-label,
.target-align-label {
font-size: 12px;
}
.label-position-select {
min-width: 0;
font-size: 12px;
padding: 0 14px 0 4px;
}
.target-align-select {
min-width: 0;
font-size: 12px;
padding: 0 14px 0 4px;
}
.direction-control {
flex-shrink: 0;
}
}