Make --radius-avatar the single source of truth for frontend user avatar shape. A new primitive in components-ext.css (img.avatar / avatar-mini / avatar-md / avatar-lg / .avatar-img img) forces a circle on every avatar image, which covers the bare avatar-mini in the ban and report modals, the classless img inside the VIP modal's .avatar-img, and the post-card meta avatar that previously depended on post-card.css being enqueued. The user center header frame, the public user home hero and the friends page avatar switch to the same token because route CSS loads after the public bundle and would otherwise override the primitive. The VIP icon no longer rides the avatar corner. The user card widget, the after-article author card and the sign-in modal stop opting into aksrt_get_avatar_box()'s corner badge, and the icon renders first in the badge/level row instead, since aksrt_get_user_name already orders name -> VIP -> auth -> medal -> level. The sign-in modal appends it after the display name and keeps the legacy precedence where a ban badge takes the VIP slot. The user card widget name row now shrinks its display name so the extra icon cannot overflow a narrow sidebar. Verified with the new frontend-avatar-shape-contract test plus post-visual, user-card-runtime, circular-button-icon-margin, user-features and page-display contracts, and php -l on every changed PHP file. The public bundle was rebuilt with tools/build-public-assets.mjs.
590 lines
12 KiB
CSS
590 lines
12 KiB
CSS
/**
|
||
* AKSRT Profile / User Center — v3.3 Editorial
|
||
*
|
||
* 从 page-profile.php 内嵌 <style> 提取,token 化。
|
||
* 通过 class-aksrt-scripts.php 在 is_page_template('templates/pages/page-profile.php') 时加载。
|
||
*
|
||
* 覆盖:
|
||
* - 公开个人主页头
|
||
* - 仪表盘标签 + 数据表
|
||
* - 个人资料编辑表单 + 联系方式行
|
||
* - 账号设置区(第三方绑定 / 安全操作)
|
||
* - 模态弹窗(修改密码 / 修改邮箱)
|
||
* - 密码强度条
|
||
*/
|
||
|
||
/* ==================== 用户资料卡片(共享) ==================== */
|
||
.uc-header {
|
||
margin-bottom: 20px;
|
||
border-radius: var(--radius-lg, 12px);
|
||
overflow: hidden;
|
||
background: var(--surface-1);
|
||
box-shadow: 0 2px 12px rgba(15, 23, 42, 0.06);
|
||
}
|
||
|
||
/* 对齐 legacy: calc(20% + 100px) */
|
||
.uc-header__cover {
|
||
position: relative;
|
||
padding-bottom: calc(20% + 100px);
|
||
overflow: hidden;
|
||
}
|
||
|
||
.uc-header__cover-img {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.uc-header__cover-mask {
|
||
position: absolute;
|
||
bottom: 0;
|
||
left: 0;
|
||
right: 0;
|
||
height: 80px;
|
||
background: linear-gradient(to top, rgba(0,0,0,0.35), transparent);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.aksrt-cover-menu {
|
||
position: absolute;
|
||
bottom: 12px;
|
||
right: 12px;
|
||
z-index: 2;
|
||
}
|
||
.aksrt-cover-menu__trigger {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 34px;
|
||
height: 34px;
|
||
padding: 0;
|
||
border: none;
|
||
border-radius: 50%;
|
||
background: rgba(0, 0, 0, 0.25);
|
||
color: #fff;
|
||
cursor: pointer;
|
||
backdrop-filter: blur(4px);
|
||
transition: background .2s;
|
||
}
|
||
.aksrt-cover-menu__trigger:hover,
|
||
.aksrt-cover-menu__trigger:focus-visible {
|
||
background: rgba(0, 0, 0, 0.45);
|
||
outline: 2px solid #fff;
|
||
outline-offset: 2px;
|
||
}
|
||
.aksrt-cover-menu__panel {
|
||
position: absolute;
|
||
right: 0;
|
||
bottom: calc(100% + 8px);
|
||
display: grid;
|
||
min-width: 140px;
|
||
padding: 6px;
|
||
border-radius: 10px;
|
||
background: rgba(20, 24, 31, .94);
|
||
box-shadow: 0 12px 32px rgba(0,0,0,.22);
|
||
backdrop-filter: blur(12px);
|
||
}
|
||
.aksrt-cover-menu__panel[hidden] {
|
||
display: none !important;
|
||
}
|
||
.aksrt-cover-menu__panel [role="menuitem"] {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
min-height: 36px;
|
||
padding: 0 10px;
|
||
border: 0;
|
||
border-radius: 6px;
|
||
color: #fff;
|
||
background: transparent;
|
||
font: inherit;
|
||
font-size: 13px;
|
||
text-align: left;
|
||
text-decoration: none;
|
||
cursor: pointer;
|
||
}
|
||
.aksrt-cover-menu__panel [role="menuitem"]:hover,
|
||
.aksrt-cover-menu__panel [role="menuitem"]:focus-visible { background: rgba(255,255,255,.13); outline: none; }
|
||
.profile-form__fields { display: grid; gap: 14px; }
|
||
.profile-form__fields label { display: grid; gap: 6px; font-size: 13px; color: var(--color-ink, #24292f); }
|
||
|
||
.uc-header__content {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 20px;
|
||
padding: 18px 28px 24px;
|
||
margin-top: -60px;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.uc-header__avatar {
|
||
position: relative;
|
||
flex-shrink: 0;
|
||
width: 140px;
|
||
height: 140px;
|
||
border-radius: var(--radius-avatar, 50%);
|
||
}
|
||
|
||
#aksrt-bg-file-input[hidden],
|
||
#aksrt-avatar-file-input[hidden] {
|
||
display: none !important;
|
||
}
|
||
|
||
/* 140px 正方形 → 正圆:统一前端用户头像形状(--radius-avatar) */
|
||
.uc-header__avatar img {
|
||
display: block;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: inherit;
|
||
border: 4px solid var(--surface-1);
|
||
box-shadow: 0 4px 12px rgba(0,0,0,0.12);
|
||
object-fit: cover;
|
||
transition: transform 0.2s ease;
|
||
}
|
||
|
||
.uc-header__avatar-upload {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 7px;
|
||
width: 100%;
|
||
padding: 0;
|
||
border: 0;
|
||
border-radius: inherit;
|
||
background: rgba(0, 0, 0, 0.52);
|
||
color: #fff;
|
||
font-size: 13px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
opacity: 0;
|
||
visibility: hidden;
|
||
transition: opacity 0.2s ease, visibility 0.2s ease;
|
||
}
|
||
|
||
.uc-header__avatar-upload i {
|
||
font-size: 22px;
|
||
}
|
||
|
||
.uc-header__avatar:hover .uc-header__avatar-upload,
|
||
.uc-header__avatar:focus-within .uc-header__avatar-upload {
|
||
opacity: 1;
|
||
visibility: visible;
|
||
}
|
||
|
||
.uc-header__avatar:hover img,
|
||
.uc-header__avatar:focus-within img {
|
||
transform: scale(1.03);
|
||
}
|
||
|
||
.uc-header__avatar-upload:focus-visible {
|
||
outline: 2px solid #fff;
|
||
outline-offset: -5px;
|
||
}
|
||
|
||
.uc-header__avatar-upload:disabled {
|
||
cursor: wait;
|
||
opacity: 1;
|
||
visibility: visible;
|
||
}
|
||
|
||
.uc-header__info {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding-top: 65px;
|
||
}
|
||
|
||
.uc-header__name {
|
||
margin: 0 0 6px;
|
||
font-size: 1.35rem;
|
||
font-weight: 700;
|
||
color: var(--color-ink);
|
||
line-height: 1.3;
|
||
}
|
||
|
||
.uc-header__desc {
|
||
margin: 0 0 10px;
|
||
font-size: 13px;
|
||
color: var(--color-ink-3);
|
||
line-height: 1.5;
|
||
max-width: 520px;
|
||
}
|
||
|
||
.aksrt-identity-chips {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
margin: 10px 0 0;
|
||
}
|
||
|
||
.aksrt-identity-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 6px;
|
||
min-height: 30px;
|
||
padding: 0 12px;
|
||
border-radius: 999px;
|
||
font-size: 12px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
letter-spacing: 0.01em;
|
||
}
|
||
|
||
.aksrt-identity-chip--success {
|
||
color: #0f766e;
|
||
background: rgba(15, 118, 110, 0.12);
|
||
}
|
||
|
||
.aksrt-identity-chip--info {
|
||
color: #1d4ed8;
|
||
background: rgba(37, 99, 235, 0.12);
|
||
}
|
||
|
||
.aksrt-identity-chip--warning {
|
||
color: #b45309;
|
||
background: rgba(245, 158, 11, 0.14);
|
||
}
|
||
|
||
.aksrt-identity-chip--brand {
|
||
color: #7c3aed;
|
||
background: rgba(124, 58, 237, 0.12);
|
||
}
|
||
|
||
.aksrt-identity-chip--neutral {
|
||
color: var(--color-ink-3);
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
|
||
.uc-header__meta {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
font-size: 13px;
|
||
color: var(--color-ink-3);
|
||
}
|
||
|
||
.uc-header__meta .aksrt-ip-geo-badge {
|
||
margin: 2px 0;
|
||
}
|
||
|
||
.uc-header__meta-item {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
}
|
||
|
||
.uc-header__meta-item i {
|
||
font-size: 12px;
|
||
opacity: 0.65;
|
||
}
|
||
|
||
/* 治理状态提示:与相邻元信息同排版;链接默认色会让箭头/图标偏离行内墨色 */
|
||
.uc-header__meta .aksrt-user-ban-notice {
|
||
color: var(--color-ink-3);
|
||
}
|
||
|
||
.uc-header__actions {
|
||
flex-shrink: 0;
|
||
padding-top: 68px;
|
||
}
|
||
|
||
|
||
/* 公开主页响应式 */
|
||
@media (max-width: 767px) {
|
||
.uc-header__content {
|
||
flex-direction: column;
|
||
align-items: center;
|
||
text-align: center;
|
||
padding: 12px 16px 20px;
|
||
}
|
||
|
||
.uc-header__info {
|
||
padding-top: 0;
|
||
}
|
||
|
||
.uc-header__desc {
|
||
max-width: 100%;
|
||
}
|
||
|
||
.uc-header__meta {
|
||
justify-content: center;
|
||
}
|
||
|
||
.aksrt-identity-chips {
|
||
justify-content: center;
|
||
}
|
||
|
||
.uc-header__actions {
|
||
padding-top: 0;
|
||
margin-top: 4px;
|
||
}
|
||
|
||
}
|
||
|
||
@media (max-width: 480px) {
|
||
.uc-header__cover {
|
||
padding-bottom: calc(20% + 60px);
|
||
}
|
||
|
||
.uc-header__content {
|
||
margin-top: -40px;
|
||
gap: 14px;
|
||
}
|
||
|
||
.uc-header__avatar {
|
||
width: 90px;
|
||
height: 90px;
|
||
}
|
||
|
||
.uc-header__avatar img {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.uc-header__avatar-upload {
|
||
gap: 5px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.uc-header__avatar-upload i {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.uc-header__name {
|
||
font-size: 1.15rem;
|
||
}
|
||
}
|
||
|
||
|
||
/* ==================== Dashboard Tabs 计数徽章 ==================== */
|
||
.dashboard-tabs__count {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 18px;
|
||
height: 18px;
|
||
padding: 0 6px;
|
||
margin-left: 4px;
|
||
font-size: 11px;
|
||
font-weight: 600;
|
||
line-height: 1;
|
||
color: var(--color-ink-3);
|
||
background: var(--surface-3);
|
||
border-radius: var(--radius-pill);
|
||
font-variant-numeric: tabular-nums;
|
||
transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
|
||
}
|
||
.dashboard-tabs button.is-active .dashboard-tabs__count {
|
||
color: var(--color-on-primary, #fff);
|
||
background: var(--color-primary);
|
||
}
|
||
|
||
/* 移动端 tab 横向滚动(取代换行) */
|
||
@media (max-width: 640px) {
|
||
.dashboard-tabs {
|
||
flex-wrap: nowrap;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
scrollbar-width: none;
|
||
-ms-overflow-style: none;
|
||
}
|
||
.aksrt-profile .uc-mobile-tabs {
|
||
flex-wrap: wrap;
|
||
overflow: hidden;
|
||
}
|
||
.dashboard-tabs::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
.dashboard-tabs button {
|
||
flex-shrink: 0;
|
||
white-space: nowrap;
|
||
}
|
||
}
|
||
|
||
|
||
/* ==================== 个人资料编辑表单 ==================== */
|
||
.profile-form .widget-card {
|
||
margin-bottom: 16px;
|
||
}
|
||
.profile-form__submit {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 0;
|
||
margin-top: 16px;
|
||
background: none;
|
||
border: none;
|
||
}
|
||
.profile-add-contact {
|
||
margin-top: 8px;
|
||
}
|
||
.profile-input {
|
||
display: block;
|
||
width: 100%;
|
||
padding: 10px 14px;
|
||
font-size: 14px;
|
||
line-height: 1.5;
|
||
color: var(--color-ink);
|
||
background: var(--surface-1);
|
||
border: 1px solid var(--color-line);
|
||
border-radius: 8px;
|
||
outline: none;
|
||
transition: border-color 0.2s, box-shadow 0.2s;
|
||
box-sizing: border-box;
|
||
}
|
||
.profile-input:focus {
|
||
border-color: var(--color-primary);
|
||
box-shadow: 0 0 0 3px var(--color-primary-soft);
|
||
}
|
||
.profile-textarea {
|
||
resize: vertical;
|
||
min-height: 90px;
|
||
font-family: inherit;
|
||
}
|
||
.profile-hint {
|
||
font-size: 12px;
|
||
color: var(--color-ink-4);
|
||
margin: 6px 0 0;
|
||
}
|
||
.profile-hint--top {
|
||
margin-top: 0;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
/* ==================== List Header(标题 + 状态筛选) ==================== */
|
||
.profile-list-header {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: 12px;
|
||
margin-bottom: 14px;
|
||
padding-bottom: 12px;
|
||
border-bottom: 2px solid var(--color-primary-50);
|
||
}
|
||
|
||
.creator-center-header {
|
||
align-items: flex-start;
|
||
}
|
||
.creator-center-heading {
|
||
min-width: 220px;
|
||
}
|
||
.creator-center-heading__summary {
|
||
margin: 4px 0 0;
|
||
color: var(--color-ink-4);
|
||
font-size: 12px;
|
||
}
|
||
.creator-center-actions {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: center;
|
||
justify-content: flex-end;
|
||
gap: 10px;
|
||
}
|
||
.creator-center-actions .profile-status-filter {
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.widget-title--inline {
|
||
margin: 0;
|
||
padding: 0;
|
||
border: none;
|
||
}
|
||
.widget-title--inline::before {
|
||
display: none;
|
||
}
|
||
|
||
.profile-status-filter {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 6px;
|
||
}
|
||
.profile-status-chip {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 5px;
|
||
padding: 4px 10px;
|
||
border-radius: var(--radius-pill);
|
||
border: 1px solid var(--color-line);
|
||
background: var(--surface-1);
|
||
color: var(--color-ink-3);
|
||
font-size: 12px;
|
||
font-weight: 500;
|
||
line-height: 1.4;
|
||
text-decoration: none;
|
||
transition: color var(--dur-fast) var(--ease),
|
||
background-color var(--dur-fast) var(--ease),
|
||
border-color var(--dur-fast) var(--ease);
|
||
}
|
||
.profile-status-chip:hover {
|
||
color: var(--color-primary);
|
||
border-color: var(--color-primary);
|
||
}
|
||
.profile-status-chip.is-active {
|
||
color: var(--color-on-primary, #fff);
|
||
background: var(--color-primary);
|
||
border-color: var(--color-primary);
|
||
}
|
||
.profile-status-chip__count {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-width: 16px;
|
||
height: 16px;
|
||
padding: 0 4px;
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
line-height: 1;
|
||
border-radius: var(--radius-pill);
|
||
background: var(--surface-3);
|
||
color: var(--color-ink-4);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.profile-status-chip.is-active .profile-status-chip__count {
|
||
background: rgba(255, 255, 255, 0.25);
|
||
color: #fff;
|
||
}
|
||
|
||
/* Level icon base sizing is centralized in assets/css/frontend/base.css. */
|
||
|
||
/* 用户中心 layout 间距;双栏 / sticky 见 user-center/shell.css(body.aksrt-user-center)。 */
|
||
.aksrt-profile__layout {
|
||
margin-top: 20px;
|
||
}
|
||
.aksrt-user-center__notice {
|
||
margin-bottom: 16px;
|
||
padding: 12px 14px;
|
||
border-radius: 8px;
|
||
color: #166534;
|
||
background: rgba(34, 197, 94, 0.12);
|
||
}
|
||
.aksrt-user-center__notice--error {
|
||
color: var(--color-error, #b91c1c);
|
||
background: rgba(239, 68, 68, 0.12);
|
||
}
|
||
.aksrt-profile .uc-mobile-tabs a {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
padding: 8px 14px;
|
||
border-radius: 8px;
|
||
color: var(--color-ink-3);
|
||
text-decoration: none;
|
||
}
|
||
.aksrt-profile .uc-mobile-tabs a.is-active {
|
||
color: var(--color-primary);
|
||
background: var(--color-primary-soft);
|
||
}
|
||
.aksrt-profile .dashboard-panel > .widget-card:first-child,
|
||
.aksrt-profile .profile-form > .widget-card:first-child {
|
||
margin-top: 0;
|
||
}
|