"""品牌主题:藏青 / 红 / 金(取自肆带贰队徽)。 提供注入用的 CSS 字符串与若干小型 HTML 构件(队徽、徽章、统计卡)。 CSS 用普通字符串(非 f-string),避免大括号转义。 """ from __future__ import annotations from shiny import ui from .config import CREST_URL CSS = """ :root{ --navy-deep:#0A1730; --navy:#11254A; --navy-2:#16305C; --navy-line:#24417a; --red:#C8102E; --red-2:#E2384B; --gold:#D4AF37; --gold-2:#EBCB6B; --gold-dim:rgba(212,175,55,.30); --blue:#3DA5D9; --green:#1FA971; --cream:#F2ECDD; --muted:#9DB0D0; --ink:#0A1325; } *{box-sizing:border-box} html{background:var(--navy-deep)} body{ margin:0; color:var(--cream); min-height:100vh; font-family:"Segoe UI","Microsoft YaHei","PingFang SC",system-ui,sans-serif; background: radial-gradient(1100px 680px at 88% 0%, rgba(200,16,46,.22), transparent 60%), radial-gradient(900px 600px at 4% 6%, rgba(61,165,217,.16), transparent 58%), linear-gradient(180deg,#0d1b38 0%, var(--navy-deep) 60%, var(--navy-deep) 100%); background-repeat:no-repeat; -webkit-font-smoothing:antialiased; } .sde-shell{max-width:1080px;margin:0 auto;padding:18px 18px 64px} /* ---------- 顶栏 ---------- */ .sde-topbar{display:flex;align-items:center;gap:14px;padding:10px 4px 18px;flex-wrap:wrap} .sde-brand{display:flex;align-items:center;gap:14px} .sde-brand .zh{font-size:26px;font-weight:800;letter-spacing:.14em;line-height:1; background:linear-gradient(180deg,var(--gold-2),var(--gold));-webkit-background-clip:text; background-clip:text;color:transparent} .sde-brand .en{font-size:11px;letter-spacing:.30em;color:var(--muted);margin-top:6px;text-transform:uppercase} .sde-spacer{flex:1} .sde-welcome{color:var(--muted);font-size:14px;margin-right:6px} .sde-welcome b{color:var(--cream)} /* ---------- 队徽 ---------- */ .sde-crest{border-radius:50%;background:radial-gradient(circle at 50% 38%,#ffffff,#eef2f7); border:2px solid var(--gold);box-shadow:0 8px 26px -8px rgba(0,0,0,.7),0 0 0 4px rgba(212,175,55,.12); display:grid;place-items:center;overflow:hidden;flex:0 0 auto} .sde-crest img{width:86%;height:86%;object-fit:contain;display:block} /* ---------- 卡片 ---------- */ .sde-card{background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.015)); border:1px solid var(--gold-dim);border-radius:18px;padding:18px 20px;margin-bottom:18px; box-shadow:0 24px 50px -34px rgba(0,0,0,.85), inset 0 1px 0 rgba(255,255,255,.04)} .sde-card-h{display:flex;align-items:center;gap:10px;margin:0 0 14px} .sde-card-h .t{font-size:15px;font-weight:800;letter-spacing:.10em;color:var(--cream)} .sde-card-h .ic{font-size:18px} .sde-card-h::after{content:"";flex:1;height:1px; background:linear-gradient(90deg,var(--gold-dim),transparent)} .sde-sub{color:var(--muted);font-size:12.5px;margin:-6px 0 14px} /* ---------- 统计卡 ---------- */ .sde-stats{display:grid;grid-template-columns:repeat(5,1fr);gap:12px} .sde-stats.cols-4{grid-template-columns:repeat(4,1fr)} .sde-stats.cols-3{grid-template-columns:repeat(3,1fr)} @media(max-width:760px){.sde-stats,.sde-stats.cols-4,.sde-stats.cols-3{grid-template-columns:repeat(2,1fr)}} .sde-stat{background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.01)); border:1px solid rgba(255,255,255,.08);border-radius:14px;padding:14px 12px;text-align:center} .sde-stat .v{font-size:30px;font-weight:800;line-height:1;color:var(--gold-2)} .sde-stat .l{font-size:12px;color:var(--muted);margin-top:7px;letter-spacing:.05em} .sde-stat .s{font-size:11px;color:var(--muted);margin-top:3px;opacity:.85} .sde-stat.accent-red .v{color:var(--red-2)} .sde-stat.accent-blue .v{color:var(--blue)} .sde-stat.accent-green .v{color:var(--green)} .sde-stat.accent-cream .v{color:var(--cream)} /* ---------- 表格 ---------- */ .sde-table-wrap{overflow-x:auto} .sde-table{width:100%;border-collapse:collapse;font-size:14px} .sde-table th{text-align:left;font-size:11px;letter-spacing:.10em;text-transform:uppercase; color:var(--gold);font-weight:700;padding:8px 10px;border-bottom:1px solid var(--gold-dim);white-space:nowrap} .sde-table td{padding:9px 10px;border-bottom:1px solid rgba(255,255,255,.06);color:var(--cream);vertical-align:middle} .sde-table tbody tr:hover{background:rgba(212,175,55,.06)} .sde-table tr.is-me{background:rgba(212,175,55,.12)} .sde-table tr.is-me td:first-child{box-shadow:inset 3px 0 0 var(--gold)} .sde-num{text-align:right;font-variant-numeric:tabular-nums;font-weight:700} .sde-rank{width:42px;text-align:center;font-weight:800;color:var(--muted)} .sde-jersey{display:inline-block;min-width:30px;padding:1px 7px;margin-right:8px;border-radius:6px; background:rgba(61,165,217,.16);border:1px solid rgba(61,165,217,.35);color:#bfe2f6; font-size:12px;font-weight:700;text-align:center} .sde-me-tag{margin-left:8px;font-size:11px;color:var(--ink);background:var(--gold); padding:0 7px;border-radius:20px;font-weight:800} .sde-empty{color:var(--muted);text-align:center;padding:24px;font-size:13px} /* 结果徽章 */ .badge-res{display:inline-block;width:22px;height:22px;line-height:22px;text-align:center; border-radius:6px;font-size:12px;font-weight:800;color:#fff} .badge-W{background:var(--green)} .badge-D{background:#6b7a99} .badge-L{background:var(--red)} .ha-pill{font-size:11px;padding:1px 8px;border-radius:20px;border:1px solid rgba(255,255,255,.18);color:var(--muted)} .ha-home{color:var(--gold-2);border-color:var(--gold-dim)} /* ---------- 表单 / 控件 ---------- */ .form-label{color:var(--cream);font-size:13px;font-weight:600;margin-bottom:5px} .form-control,.form-select{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.16); color:var(--cream);border-radius:10px} .form-control:focus,.form-select:focus{background:rgba(255,255,255,.09);border-color:var(--gold); box-shadow:0 0 0 .18rem rgba(212,175,55,.22);color:var(--cream)} .form-control::placeholder{color:#7e90b3} .form-select option{color:#10203f;background:#eaf0fb} .form-check-input{background-color:rgba(255,255,255,.12);border-color:rgba(255,255,255,.3)} .form-check-input:checked{background-color:var(--gold);border-color:var(--gold)} .shiny-input-container{margin-bottom:12px} /* 按钮 */ .btn{border-radius:10px;font-weight:700;letter-spacing:.02em} .btn-primary,.btn-default.btn-primary{background:linear-gradient(180deg,var(--gold-2),var(--gold)); border:none;color:#1a1305} .btn-primary:hover{filter:brightness(1.07);color:#1a1305} .btn-danger{background:var(--red);border:none} .btn-outline-light{border-color:rgba(255,255,255,.35);color:var(--cream)} .btn-outline-light:hover{background:rgba(255,255,255,.1);color:#fff} /* 导航 */ .nav-tabs,.nav-pills{border-bottom:1px solid var(--gold-dim);gap:6px;margin-bottom:18px} .nav-tabs .nav-link,.nav-pills .nav-link{color:var(--muted);border:none;font-weight:700; letter-spacing:.04em;padding:9px 16px;border-radius:10px 10px 0 0} .nav-tabs .nav-link:hover{color:var(--cream);background:rgba(255,255,255,.04)} .nav-tabs .nav-link.active,.nav-pills .nav-link.active{color:var(--ink); background:linear-gradient(180deg,var(--gold-2),var(--gold));border:none} /* ---------- 登录页 ---------- */ .sde-login-wrap{display:flex;justify-content:center;padding:6vh 16px 40px} .sde-login{width:100%;max-width:380px;text-align:center} .sde-login .sde-crest{margin:0 auto 18px} .sde-login .zh{font-size:34px;font-weight:800;letter-spacing:.18em; background:linear-gradient(180deg,var(--gold-2),var(--gold));-webkit-background-clip:text; background-clip:text;color:transparent} .sde-login .en{font-size:11px;letter-spacing:.34em;color:var(--muted);margin:10px 0 4px;text-transform:uppercase} .sde-login .city{font-size:12px;color:var(--blue);letter-spacing:.2em;margin-bottom:22px} .sde-login .sde-card{text-align:left} .sde-login .btn-primary{width:100%;padding:9px;margin-top:6px} .sde-login-hint{color:var(--muted);font-size:12px;margin-top:14px;line-height:1.7} .sde-login-hint code{background:rgba(255,255,255,.08);padding:1px 6px;border-radius:5px;color:var(--gold-2)} /* 通知深色化 */ .shiny-notification{background:var(--navy-2);color:var(--cream);border:1px solid var(--gold-dim)} /* 我的数据:紧凑表单 */ .sde-form-table .shiny-input-container{margin:0} .sde-form-table label:empty{display:none} .sde-form-table .form-control{padding:4px 8px;text-align:center} /* ---------- 个人趋势图 ---------- */ .sde-trend-wrap{overflow-x:auto} .sde-legend{display:flex;gap:18px;font-size:12px;color:var(--muted);margin-bottom:10px} .sde-legend > span{display:inline-flex;align-items:center;gap:6px} .sde-dot-g,.sde-dot-a{width:11px;height:11px;border-radius:3px;display:inline-block} .sde-dot-g{background:#EBCB6B} .sde-dot-a{background:#3DA5D9} /* ================= 冲击力榜单(Hero 聚光台 + 奖牌行 + 能量条) ================= */ @keyframes sde-row-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}} @keyframes sde-sheen{0%,55%{transform:translateX(-130%) skewX(-18deg)}100%{transform:translateX(230%) skewX(-18deg)}} @keyframes sde-bar-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}} @keyframes sde-crown-bob{0%,100%{transform:rotate(-8deg)}50%{transform:rotate(6deg) translateY(-2px)}} .sde-board{display:flex;flex-direction:column;gap:8px} /* --- 榜首 Hero --- */ .sde-hero{position:relative;overflow:hidden;border-radius:14px;padding:16px 16px 14px; background: radial-gradient(120% 150% at 100% 0%, rgba(212,175,55,.28), transparent 55%), linear-gradient(135deg, rgba(212,175,55,.16), rgba(17,37,74,.9) 58%); border:1px solid rgba(212,175,55,.55); box-shadow:0 14px 34px -18px rgba(212,175,55,.45), inset 0 1px 0 rgba(255,255,255,.08); animation:sde-row-in .45s ease both} .sde-hero::after{content:"";position:absolute;top:0;bottom:0;width:46%; background:linear-gradient(105deg,transparent,rgba(255,236,180,.16) 45%,transparent 60%); animation:sde-sheen 3.4s ease-in-out infinite;pointer-events:none} .sde-hero .crown{position:absolute;top:8px;right:12px;font-size:26px;opacity:.9; filter:drop-shadow(0 3px 8px rgba(212,175,55,.6));animation:sde-crown-bob 2.6s ease-in-out infinite;transform-origin:60% 90%} .sde-hero .title{font-size:10.5px;font-weight:800;letter-spacing:.34em;color:var(--gold); text-transform:uppercase;margin-bottom:8px;display:flex;align-items:center;gap:8px} .sde-hero .title::after{content:"";flex:0 0 42px;height:1px;background:linear-gradient(90deg,var(--gold),transparent)} .sde-hero .who{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap} .sde-hero .nm{font-size:21px;font-weight:900;letter-spacing:.02em;color:var(--cream); text-shadow:0 2px 14px rgba(212,175,55,.35)} .sde-hero .big{margin-left:auto;display:flex;align-items:baseline;gap:5px} .sde-hero .big .n{font-size:42px;font-weight:900;line-height:.9; background:linear-gradient(180deg,#fff2c4,var(--gold));-webkit-background-clip:text;background-clip:text;color:transparent; font-variant-numeric:tabular-nums;filter:drop-shadow(0 4px 14px rgba(212,175,55,.45))} .sde-hero .big .u{font-size:12px;color:var(--gold-2);font-weight:700} .sde-hero .sub2{margin-top:4px;font-size:12px;color:var(--muted)} .sde-hero .sde-jersey{transform:translateY(-2px)} /* --- 2/3 名奖牌行 + 普通行 --- */ .sde-brow{position:relative;display:flex;align-items:center;gap:10px;padding:9px 12px; border-radius:11px;background:rgba(255,255,255,.028);border:1px solid rgba(255,255,255,.06); animation:sde-row-in .45s ease both;overflow:hidden} .sde-brow:nth-child(2){animation-delay:.06s}.sde-brow:nth-child(3){animation-delay:.12s} .sde-brow:nth-child(4){animation-delay:.18s}.sde-brow:nth-child(5){animation-delay:.24s} .sde-brow:nth-child(6){animation-delay:.30s}.sde-brow:nth-child(7){animation-delay:.36s} .sde-brow:nth-child(8){animation-delay:.42s} .sde-brow.r2{background:linear-gradient(90deg,rgba(203,213,235,.10),rgba(255,255,255,.02) 62%); border-color:rgba(203,213,235,.30)} .sde-brow.r3{background:linear-gradient(90deg,rgba(205,127,50,.12),rgba(255,255,255,.02) 62%); border-color:rgba(205,127,50,.32)} .sde-brow.is-me{border-color:var(--gold);box-shadow:inset 3px 0 0 var(--gold)} .sde-brow .rk{flex:0 0 26px;text-align:center;font-weight:900;font-size:15px;color:var(--muted)} .sde-brow.r2 .rk,.sde-brow.r3 .rk{font-size:17px} .sde-brow .nm{font-weight:700;color:var(--cream);font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .sde-brow .val{margin-left:auto;font-weight:900;font-size:16px;color:var(--gold-2); font-variant-numeric:tabular-nums;white-space:nowrap} .sde-brow .val .u{font-size:11px;color:var(--muted);font-weight:600;margin-left:3px} /* 能量条 */ .sde-brow .bar{position:absolute;left:0;bottom:0;height:2.5px;width:var(--w,0%);border-radius:2px; background:linear-gradient(90deg,var(--gold),rgba(212,175,55,.15));transform-origin:left; animation:sde-bar-grow .8s .25s cubic-bezier(.2,.8,.2,1) both} .sde-brow.c-blue .bar{background:linear-gradient(90deg,var(--blue),rgba(61,165,217,.15))} .sde-brow.c-blue .val{color:#8fd4f5} .sde-brow.c-green .bar{background:linear-gradient(90deg,var(--green),rgba(31,169,113,.15))} .sde-brow.c-green .val{color:#5fd7a7} .sde-hero.c-blue{border-color:rgba(61,165,217,.55); background:radial-gradient(120% 150% at 100% 0%, rgba(61,165,217,.28), transparent 55%), linear-gradient(135deg, rgba(61,165,217,.16), rgba(17,37,74,.9) 58%); box-shadow:0 14px 34px -18px rgba(61,165,217,.45), inset 0 1px 0 rgba(255,255,255,.08)} .sde-hero.c-blue .big .n{background:linear-gradient(180deg,#d9f1ff,var(--blue));-webkit-background-clip:text;background-clip:text} .sde-hero.c-blue .title{color:var(--blue)} .sde-hero.c-green{border-color:rgba(31,169,113,.55); background:radial-gradient(120% 150% at 100% 0%, rgba(31,169,113,.26), transparent 55%), linear-gradient(135deg, rgba(31,169,113,.15), rgba(17,37,74,.9) 58%); box-shadow:0 14px 34px -18px rgba(31,169,113,.45), inset 0 1px 0 rgba(255,255,255,.08)} .sde-hero.c-green .big .n{background:linear-gradient(180deg,#c9f5e2,var(--green));-webkit-background-clip:text;background-clip:text} .sde-hero.c-green .title{color:var(--green)} .sde-hero.c-red{border-color:rgba(226,56,75,.55); background:radial-gradient(120% 150% at 100% 0%, rgba(200,16,46,.30), transparent 55%), linear-gradient(135deg, rgba(200,16,46,.17), rgba(17,37,74,.9) 58%); box-shadow:0 14px 34px -18px rgba(200,16,46,.5), inset 0 1px 0 rgba(255,255,255,.08)} .sde-hero.c-red .big .n{background:linear-gradient(180deg,#ffd2d8,var(--red-2));-webkit-background-clip:text;background-clip:text; filter:drop-shadow(0 4px 14px rgba(200,16,46,.5))} .sde-hero.c-red .title{color:var(--red-2)} .sde-hero.c-red .crown{filter:drop-shadow(0 3px 8px rgba(200,16,46,.6))} .sde-brow.c-red .bar{background:linear-gradient(90deg,var(--red-2),rgba(200,16,46,.15))} .sde-brow.c-red .val{color:#ff9fab} .sde-brow.c-red.r2,.sde-brow.c-red.r3{border-color:rgba(226,56,75,.30)} .sde-board .sde-empty{padding:18px} /* ================= 每场比分 · 战报记分牌 ================= */ .sde-mc-list{display:flex;flex-direction:column;gap:12px} .sde-scorecard{position:relative;overflow:hidden;border-radius:14px;padding:14px 16px 12px; background:linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012)); border:1px solid rgba(255,255,255,.09);animation:sde-row-in .45s ease both; transition:transform .18s ease, box-shadow .18s ease} .sde-scorecard:hover{transform:translateY(-2px);box-shadow:0 18px 40px -22px rgba(0,0,0,.9)} .sde-scorecard::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px} .sde-scorecard.res-W::before{background:linear-gradient(180deg,var(--green),rgba(31,169,113,.25))} .sde-scorecard.res-D::before{background:linear-gradient(180deg,#6b7a99,rgba(107,122,153,.25))} .sde-scorecard.res-L::before{background:linear-gradient(180deg,var(--red),rgba(200,16,46,.25))} .sde-scorecard.res-W{background: radial-gradient(90% 130% at 0% 0%, rgba(31,169,113,.13), transparent 52%), linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012))} .sde-scorecard.res-L{background: radial-gradient(90% 130% at 0% 0%, rgba(200,16,46,.13), transparent 52%), linear-gradient(180deg,rgba(255,255,255,.045),rgba(255,255,255,.012))} .sde-sc-meta{display:flex;align-items:center;gap:9px;flex-wrap:wrap;font-size:12px;color:var(--muted)} .sde-sc-meta .d{font-variant-numeric:tabular-nums;letter-spacing:.04em} .sde-sc-meta .note{opacity:.8} .sde-sc-main{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:12px;margin:10px 0 4px} .sde-sc-side{min-width:0} .sde-sc-side .tn{font-weight:800;font-size:15.5px;color:var(--cream); white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .sde-sc-side.us .tn{color:var(--gold-2)} .sde-sc-side.them{text-align:right} .sde-sc-score{display:flex;align-items:center;gap:10px} .sde-sc-score .n{font-size:37px;font-weight:900;line-height:1;color:var(--cream); font-variant-numeric:tabular-nums;text-shadow:0 3px 16px rgba(0,0,0,.5)} .sde-sc-score .sep{font-size:20px;color:var(--muted);font-weight:300;transform:translateY(-2px)} .sde-scorecard.res-W .sde-sc-score .n.us{color:#6fe3b1;text-shadow:0 0 22px rgba(31,169,113,.55)} .sde-scorecard.res-L .sde-sc-score .n.them{color:var(--red-2);text-shadow:0 0 22px rgba(200,16,46,.5)} .sde-sc-badge{position:absolute;top:12px;right:12px;width:34px;height:34px;border-radius:10px; display:grid;place-items:center;font-weight:900;font-size:16px;color:#fff} .sde-sc-badge.W{background:linear-gradient(160deg,#27c584,#128757);box-shadow:0 6px 18px -6px rgba(31,169,113,.8)} .sde-sc-badge.D{background:linear-gradient(160deg,#8494b5,#5b6b8d);box-shadow:0 6px 18px -6px rgba(107,122,153,.8)} .sde-sc-badge.L{background:linear-gradient(160deg,#e2384b,#a30d26);box-shadow:0 6px 18px -6px rgba(200,16,46,.8)} .sde-sc-detail{display:flex;flex-direction:column;gap:7px;margin-top:10px;padding-top:10px; border-top:1px dashed rgba(255,255,255,.10)} /* 分行明细:标签列(固定宽,右对齐) + 该类芯片 */ .sde-detail-row{display:flex;align-items:flex-start;gap:10px} .sde-dl{flex:0 0 92px;display:inline-flex;align-items:center;justify-content:flex-end;gap:5px; font-size:12.5px;font-weight:800;padding-top:3px;letter-spacing:.02em;white-space:nowrap} .sde-dl .ic{font-size:13px} .sde-dl.mvp{color:#ffe9a8} .sde-dl.dmvp{color:#ffc3cb} .sde-dl.goal{color:var(--gold-2)} .sde-dl.assist{color:#8fd4f5} .sde-dr{display:flex;flex-wrap:wrap;gap:6px 7px;min-width:0} @media(max-width:480px){.sde-dl{flex-basis:84px;font-size:12px}} .sde-chip{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;padding:3px 11px; border-radius:20px;border:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.04);color:var(--cream)} .sde-chip .ic{font-size:12px} .sde-chip.goal{border-color:rgba(212,175,55,.4);background:rgba(212,175,55,.10)} .sde-chip.assist{border-color:rgba(61,165,217,.4);background:rgba(61,165,217,.10)} .sde-chip.mvp{border-color:rgba(212,175,55,.65);background:linear-gradient(90deg,rgba(212,175,55,.22),rgba(212,175,55,.08)); color:#ffe9a8;font-weight:800;box-shadow:0 0 14px -4px rgba(212,175,55,.7)} .sde-chip.dmvp{border-color:rgba(226,56,75,.6);background:linear-gradient(90deg,rgba(200,16,46,.24),rgba(200,16,46,.08)); color:#ffc3cb;font-weight:800;box-shadow:0 0 14px -4px rgba(200,16,46,.7)} /* 比分折叠:默认展示最近 N 场,其余收进
*/ .sde-mc-more{display:block} .sde-mc-more > summary.sde-more-btn{list-style:none;cursor:pointer;user-select:none; display:flex;align-items:center;justify-content:center;gap:8px; padding:9px 14px;border-radius:12px;font-size:13px;font-weight:700;color:var(--muted); background:rgba(255,255,255,.03);border:1px dashed rgba(212,175,55,.35); transition:color .15s ease,border-color .15s ease,background .15s ease} .sde-mc-more > summary.sde-more-btn::-webkit-details-marker{display:none} .sde-mc-more > summary.sde-more-btn:hover{color:var(--gold-2);border-color:var(--gold); background:rgba(212,175,55,.07)} .sde-more-btn .arr{transition:transform .2s ease;font-size:12px} .sde-mc-more[open] > summary .arr{transform:rotate(180deg)} .sde-more-btn .txt-close{display:none} .sde-mc-more[open] > summary .txt-open{display:none} .sde-mc-more[open] > summary .txt-close{display:inline} .sde-mc-more > .sde-mc-list{margin-top:12px} /* 榜单折叠:Hero+2/3名常驻,第4名起收进
(复用 sde-more-btn 样式) */ .sde-board-more{display:block} .sde-board-more > summary.sde-more-btn{margin-top:2px} .sde-board-more-list{display:flex;flex-direction:column;gap:8px;margin-top:8px} /* ============ 我的主场 · 球员卡 Hero ============ */ .sde-pcard{position:relative;overflow:hidden;border-radius:18px;padding:22px 22px 18px;margin-bottom:18px; background: radial-gradient(130% 170% at 100% 0%, rgba(212,175,55,.22), transparent 55%), radial-gradient(90% 120% at 0% 100%, rgba(61,165,217,.10), transparent 50%), linear-gradient(135deg, rgba(212,175,55,.10), rgba(17,37,74,.94) 60%); border:1px solid rgba(212,175,55,.5); box-shadow:0 20px 48px -24px rgba(212,175,55,.45), inset 0 1px 0 rgba(255,255,255,.07); animation:sde-row-in .5s ease both} .sde-pcard::after{content:"";position:absolute;top:0;bottom:0;width:44%; background:linear-gradient(105deg,transparent,rgba(255,236,180,.10) 45%,transparent 60%); animation:sde-sheen 4.2s ease-in-out infinite;pointer-events:none} .sde-pcard .wm{position:absolute;right:-8px;top:-38px;font-size:170px;font-weight:900;line-height:1; color:transparent;-webkit-text-stroke:2px rgba(212,175,55,.22);pointer-events:none; font-variant-numeric:tabular-nums;letter-spacing:-.05em;user-select:none} .sde-pcard .kicker{font-size:10.5px;font-weight:800;letter-spacing:.34em;color:var(--gold); text-transform:uppercase;margin-bottom:6px;display:flex;align-items:center;gap:8px} .sde-pcard .kicker::after{content:"";flex:0 0 46px;height:1px;background:linear-gradient(90deg,var(--gold),transparent)} .sde-pcard .nm{font-size:31px;font-weight:900;color:var(--cream);line-height:1.15; text-shadow:0 2px 18px rgba(212,175,55,.35)} .sde-pcard .rl{font-size:12px;color:var(--muted);letter-spacing:.20em;margin-top:3px;text-transform:uppercase} .sde-badges{display:flex;flex-wrap:wrap;gap:7px;margin-top:13px;position:relative;z-index:1} .sde-badge{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:800; padding:3px 11px;border-radius:20px;border:1px solid rgba(212,175,55,.5); background:linear-gradient(90deg,rgba(212,175,55,.20),rgba(212,175,55,.06));color:#ffe9a8} .sde-badge.b-blue{border-color:rgba(61,165,217,.5);background:linear-gradient(90deg,rgba(61,165,217,.20),rgba(61,165,217,.06));color:#bfe6fb} .sde-badge.b-red{border-color:rgba(226,56,75,.5);background:linear-gradient(90deg,rgba(200,16,46,.22),rgba(200,16,46,.06));color:#ffc3cb} .sde-badge.b-green{border-color:rgba(31,169,113,.5);background:linear-gradient(90deg,rgba(31,169,113,.20),rgba(31,169,113,.06));color:#a9ecd0} .sde-quote{margin-top:15px;padding:11px 15px;border-left:3px solid var(--gold); background:rgba(212,175,55,.07);border-radius:0 11px 11px 0;position:relative;z-index:1} .sde-quote .h{font-weight:900;color:var(--gold-2);font-size:14.5px;letter-spacing:.08em} .sde-quote .b{color:var(--cream);font-size:13px;margin-top:4px;line-height:1.75;opacity:.92} .sde-ptiles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:16px;position:relative;z-index:1} @media(max-width:560px){.sde-ptiles{grid-template-columns:repeat(2,1fr)}.sde-pcard .wm{font-size:120px;top:-24px}} .sde-ptile{background:rgba(10,19,37,.45);border:1px solid rgba(255,255,255,.09); border-radius:12px;padding:12px 10px;text-align:center;backdrop-filter:blur(2px)} .sde-ptile .v{font-size:25px;font-weight:900;color:var(--gold-2);font-variant-numeric:tabular-nums;line-height:1} .sde-ptile .l{font-size:11.5px;color:var(--muted);margin-top:6px;letter-spacing:.04em} .sde-ptile .r{font-size:11px;color:var(--gold);margin-top:3px;font-weight:700} .sde-ptile.t-blue .v{color:#8fd4f5}.sde-ptile.t-blue .r{color:var(--blue)} .sde-ptile.t-green .v{color:#5fd7a7}.sde-ptile.t-green .r{color:var(--green)} .sde-ptile.t-red .v{color:#ff9fab}.sde-ptile.t-red .r{color:var(--red-2)} .sde-ptile.t-cream .v{color:var(--cream)} /* ============ FIFA UT 式球员卡(华丽版) ============ */ @keyframes sde-fifa-in{from{opacity:0;transform:translateY(16px) scale(.96)}to{opacity:1;transform:none}} @keyframes sde-halo{0%,100%{opacity:.55;transform:translateX(-50%) scale(1)}50%{opacity:.95;transform:translateX(-50%) scale(1.12)}} .sde-fifa-wrap{display:flex;justify-content:center;margin-bottom:18px;perspective:900px} .sde-fifa{position:relative;width:300px;padding:28px 26px 24px;text-align:center; clip-path:polygon(12% 0,88% 0,100% 7%,100% 86%,50% 100%,0 86%,0 7%); animation:sde-fifa-in .55s cubic-bezier(.2,.9,.3,1.2) both;overflow:hidden; transition:transform .25s ease} .sde-fifa:hover{transform:rotateX(4deg) rotateY(-5deg) translateY(-5px) scale(1.02)} /* 卡底渐变 + 织物噪点 + 中轴几何雕纹 */ .sde-fifa.gold{background: repeating-conic-gradient(from 30deg at 50% 42%, rgba(255,255,255,.07) 0 8deg, transparent 8deg 16deg), radial-gradient(120% 90% at 50% 0%, #fff6d0 0%, #ffe08a 26%, #f2c247 50%, #d69a2a 78%, #b07d1c 100%); box-shadow:0 26px 60px -20px rgba(245,196,71,.85), 0 0 34px -8px rgba(255,224,138,.55), inset 0 0 0 1px rgba(255,255,255,.55), inset 0 2px 14px rgba(255,255,255,.4)} .sde-fifa.silver{background: repeating-conic-gradient(from 30deg at 50% 42%, rgba(255,255,255,.09) 0 8deg, transparent 8deg 16deg), radial-gradient(120% 90% at 50% 0%, #ffffff 0%, #e6edf6 28%, #bcc9dc 56%, #93a2ba 86%, #7688a1 100%); box-shadow:0 26px 60px -20px rgba(147,162,186,.8), 0 0 30px -8px rgba(220,232,248,.6), inset 0 0 0 1px rgba(255,255,255,.7), inset 0 2px 14px rgba(255,255,255,.5)} .sde-fifa.bronze{background: repeating-conic-gradient(from 30deg at 50% 42%, rgba(255,255,255,.07) 0 8deg, transparent 8deg 16deg), radial-gradient(120% 90% at 50% 0%, #ffe0b8 0%, #f5b578 26%, #e29452 50%, #c1712f 80%, #9c561f 100%); box-shadow:0 26px 60px -20px rgba(226,148,82,.8), 0 0 30px -8px rgba(245,181,120,.55), inset 0 0 0 1px rgba(255,255,255,.5), inset 0 2px 14px rgba(255,236,220,.45)} .sde-fifa.legend{background: repeating-conic-gradient(from 30deg at 50% 42%, rgba(255,255,255,.09) 0 8deg, transparent 8deg 16deg), radial-gradient(120% 90% at 50% 0%, #f6ecff 0%, #d9b8ff 26%, #b483f5 54%, #8a54e0 82%, #6234ac 100%); box-shadow:0 26px 66px -18px rgba(154,108,216,.95), 0 0 40px -6px rgba(200,166,242,.7), inset 0 0 0 1px rgba(255,255,255,.7), inset 0 2px 16px rgba(255,255,255,.55)} /* 双层内描边 */ .sde-fifa::before{content:"";position:absolute;inset:7px;pointer-events:none; clip-path:polygon(12% 0,88% 0,100% 7%,100% 86%,50% 100%,0 86%,0 7%); border:1px solid rgba(70,48,8,.4);box-shadow:inset 0 0 0 3px rgba(255,255,255,.14)} /* 扫光 */ .sde-fifa::after{content:"";position:absolute;top:0;bottom:0;width:55%; background:linear-gradient(105deg,transparent,rgba(255,255,255,.32) 48%,transparent 62%); animation:sde-sheen 3.8s ease-in-out infinite;pointer-events:none} /* 顶部 tier 光冠 */ .sde-fifa .halo{position:absolute;top:-34px;left:50%;transform:translateX(-50%);width:190px;height:70px; background:radial-gradient(50% 100% at 50% 100%, rgba(255,255,255,.55), transparent 70%); filter:blur(6px);animation:sde-halo 3.2s ease-in-out infinite;pointer-events:none} .sde-fifa,.sde-fifa *{color:#3d2b06} .sde-fifa.silver,.sde-fifa.silver *{color:#28303e} .sde-fifa.bronze,.sde-fifa.bronze *{color:#3c2510} .sde-fifa.legend,.sde-fifa.legend *{color:#2c1650} .sde-fifa .top{display:flex;align-items:flex-start;gap:10px;text-align:left} .sde-fifa .ovr{font-size:56px;font-weight:900;line-height:.88;letter-spacing:-.03em; text-shadow:0 1px 0 rgba(255,255,255,.55), 0 3px 10px rgba(60,40,5,.35)} .sde-fifa .meta{display:flex;flex-direction:column;gap:2px;padding-top:6px} .sde-fifa .pos{font-size:17px;font-weight:900;letter-spacing:.1em} .sde-fifa .jer{font-size:12px;font-weight:800;opacity:.75;letter-spacing:.06em} .sde-fifa .crest-s{margin-left:auto;width:46px;height:46px;border-radius:50%;overflow:hidden; border:2px solid rgba(70,48,8,.45);background:#fff;box-shadow:0 3px 10px rgba(60,40,5,.35)} .sde-fifa .crest-s img{width:100%;height:100%;object-fit:contain} .sde-fifa .fname{font-size:23px;font-weight:900;letter-spacing:.06em;margin-top:11px; padding-bottom:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; border-bottom:2px solid rgba(70,48,8,.4); text-shadow:0 1px 0 rgba(255,255,255,.4)} .sde-fifa .grid{display:grid;grid-template-columns:1fr 1fr;gap:4px 22px;margin-top:12px;padding:0 8px} .sde-fifa .st{display:flex;align-items:baseline;justify-content:space-between;gap:8px} .sde-fifa .st .n{font-size:19px;font-weight:900;font-variant-numeric:tabular-nums; text-shadow:0 1px 0 rgba(255,255,255,.4)} .sde-fifa .st .k{font-size:12px;font-weight:800;letter-spacing:.08em;opacity:.8} .sde-fifa .club{margin-top:13px;font-size:10px;font-weight:800;letter-spacing:.3em;opacity:.7;text-transform:uppercase} @media(max-width:400px){.sde-fifa{width:270px}} /* ---- 主页 · 全队球员卡墙 ---- */ .sde-fifa-wall{display:grid;grid-template-columns:repeat(auto-fill,minmax(228px,1fr)); gap:16px;justify-items:center} .sde-fifa-wall .sde-fifa{width:228px;padding:20px 18px 16px} .sde-fifa-wall > :nth-child(2) .sde-fifa{animation-delay:.05s} .sde-fifa-wall > :nth-child(3) .sde-fifa{animation-delay:.1s} .sde-fifa-wall > :nth-child(4) .sde-fifa{animation-delay:.15s} .sde-fifa-wall > :nth-child(n+5) .sde-fifa{animation-delay:.2s} .sde-fifa-wall .ovr{font-size:42px} .sde-fifa-wall .fname{font-size:18px;margin-top:8px;padding-bottom:8px} .sde-fifa-wall .pos{font-size:14px} .sde-fifa-wall .crest-s{width:36px;height:36px} .sde-fifa-wall .grid{gap:2px 14px;margin-top:9px;padding:0 4px} .sde-fifa-wall .st .n{font-size:15px} .sde-fifa-wall .st .k{font-size:10.5px} .sde-fifa-wall .club{margin-top:10px;font-size:8.5px} .sde-fifa-wall .halo{width:140px;height:52px;top:-26px} .sde-fifa.is-me-card{outline:0} .sde-fifa.is-me-card .fname::after{content:" ★";font-size:15px} /* ---- 💎 钻石球星卡(专属皮肤·仅个人页本人可见·纯外观不碰评分) ---- */ @keyframes sde-dia-hue{to{filter:hue-rotate(360deg)}} @keyframes sde-dia-holo{0%{background-position:0% 50%}50%{background-position:100% 50%}100%{background-position:0% 50%}} @keyframes sde-dia-glow{ 0%,100%{box-shadow:0 26px 66px -18px rgba(0,180,220,.7),0 0 40px -6px rgba(60,220,255,.55), inset 0 0 0 1px rgba(180,240,255,.35),inset 0 2px 22px rgba(80,200,255,.18)} 50%{box-shadow:0 26px 74px -14px rgba(0,220,255,.92),0 0 62px -2px rgba(120,240,255,.82), inset 0 0 0 1px rgba(200,250,255,.6),inset 0 2px 26px rgba(120,230,255,.32)}} /* 深黑曜石底 + 冰蓝/四色全息流光 + 几何雕纹 */ .sde-fifa.diamond{ background: repeating-linear-gradient(115deg, rgba(0,245,212,.12) 0px, rgba(51,224,255,.10) 12px, rgba(123,97,255,.10) 24px, rgba(255,46,151,.08) 36px, transparent 36px, transparent 72px), repeating-conic-gradient(from 30deg at 50% 42%, rgba(180,240,255,.06) 0 8deg, transparent 8deg 16deg), radial-gradient(120% 95% at 50% 0%, #16324e 0%, #0e2036 34%, #0a1526 64%, #060b16 100%); background-size:220% 220%, auto, auto; animation:sde-fifa-in .55s cubic-bezier(.2,.9,.3,1.2) both, sde-dia-holo 7s ease-in-out infinite, sde-dia-glow 3.6s ease-in-out infinite} .sde-fifa.diamond,.sde-fifa.diamond *{color:#eafaff} /* 流动的四色钻石切面镶边(沿用卡片六边形轮廓) */ .sde-fifa.diamond::before{ inset:0;padding:2px;border:none;box-shadow:none; background:conic-gradient(from 0deg,#00f5d4,#33e0ff,#7b61ff,#ff2e97,#ffd166,#00f5d4); -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0); -webkit-mask-composite:xor;mask-composite:exclude; animation:sde-dia-hue 6s linear infinite;opacity:.95} /* 更亮更宽的棱镜白光扫过 */ .sde-fifa.diamond::after{ background:linear-gradient(105deg,transparent 30%,rgba(255,255,255,.55) 47%, rgba(180,240,255,.35) 52%,transparent 66%)} /* 冰蓝光冠 */ .sde-fifa.diamond .halo{ background:radial-gradient(50% 100% at 50% 100%, rgba(120,240,255,.7), transparent 72%)} /* 深底下的描边/分割线/高光改冰蓝 */ .sde-fifa.diamond .fname{border-bottom-color:rgba(130,225,255,.5); text-shadow:0 0 10px rgba(0,230,255,.45)} .sde-fifa.diamond .ovr{text-shadow:0 0 14px rgba(90,230,255,.62)} .sde-fifa.diamond .st .n{text-shadow:0 0 8px rgba(0,245,212,.45)} .sde-fifa.diamond .crest-s{border-color:rgba(150,235,255,.65);background:rgba(255,255,255,.92); box-shadow:0 0 12px rgba(80,220,255,.5)} /* 位置角标点亮钻石标识 */ .sde-fifa.diamond .pos::after{content:" 💎";font-size:13px} /* 背面同款冰蓝配色 */ .sde-fifa.diamond .bname{border-bottom-color:rgba(130,225,255,.5)} .sde-fifa.diamond .bst{background:rgba(120,220,255,.12);border-color:rgba(150,235,255,.3)} .sde-fifa.diamond .bquote{background:rgba(120,220,255,.10);border-left-color:rgba(150,235,255,.6)} /* ---- 球星卡 3D 翻面(checkbox+label,零 JS) ---- */ .sde-flip-box{position:relative;width:100%;display:flex;justify-content:center} .sde-flip-cb{position:absolute;opacity:0;pointer-events:none} .sde-flip{display:block;cursor:pointer;perspective:1100px;-webkit-tap-highlight-color:transparent} .sde-flipper{position:relative;transition:transform .62s cubic-bezier(.35,.9,.3,1.05); transform-style:preserve-3d} .sde-flip-cb:checked + .sde-flip .sde-flipper{transform:rotateY(180deg)} .sde-flipper .face{backface-visibility:hidden;-webkit-backface-visibility:hidden} .sde-flipper .face.back{position:absolute;inset:0;transform:rotateY(180deg); display:flex;justify-content:center} .sde-flipper .face.back .sde-fifa{height:100%;display:flex;flex-direction:column} /* 翻面时停掉正面 hover 倾斜,避免和翻转打架 */ .sde-flip .sde-fifa:hover{transform:none} .sde-flip:hover .sde-flipper{transform:rotateY(-6deg)} .sde-flip-cb:checked + .sde-flip:hover .sde-flipper{transform:rotateY(186deg)} /* 正/背面的翻面提示 */ .sde-fifa .fflip,.sde-fifa .bflip{margin-top:9px;font-size:10px;font-weight:800; letter-spacing:.14em;opacity:.55;text-transform:uppercase} /* ---- 背面内容 ---- */ .sde-fifa-back{text-align:center;justify-content:flex-start} .sde-fifa-back .bname{font-size:20px;font-weight:900;letter-spacing:.05em;margin-top:2px; padding-bottom:8px;border-bottom:2px solid rgba(70,48,8,.4); white-space:nowrap;overflow:hidden;text-overflow:ellipsis; text-shadow:0 1px 0 rgba(255,255,255,.4)} .sde-fifa-back .bapps{font-size:11.5px;font-weight:800;opacity:.75;margin-top:7px;letter-spacing:.08em} .sde-fifa-back .bgrid{display:grid;grid-template-columns:1fr 1fr;gap:6px 12px;margin-top:10px;padding:0 4px} .sde-fifa-back .bst{display:flex;align-items:center;justify-content:space-between;gap:6px; background:rgba(255,255,255,.22);border:1px solid rgba(70,48,8,.25); border-radius:9px;padding:6px 9px} .sde-fifa-back .bk{font-size:11px;font-weight:800;opacity:.85;white-space:nowrap} .sde-fifa-back .bn{font-size:17px;font-weight:900;font-variant-numeric:tabular-nums; text-shadow:0 1px 0 rgba(255,255,255,.4)} .sde-fifa-back .bquote{margin-top:10px;padding:8px 11px;text-align:left; background:rgba(255,255,255,.20);border-left:3px solid rgba(70,48,8,.45);border-radius:0 9px 9px 0} .sde-fifa-back .qt{font-size:12.5px;font-weight:900;letter-spacing:.04em} .sde-fifa-back .qb{font-size:11px;line-height:1.65;margin-top:3px;opacity:.88} .sde-fifa-back .bflip{margin-top:auto;padding-top:8px} /* 卡墙内背面字号微调 */ .sde-fifa-wall .sde-fifa-back .bname{font-size:16.5px} .sde-fifa-wall .sde-fifa-back .bn{font-size:15px} .sde-fifa-wall .sde-fifa-back .qb{font-size:10.5px} @media(max-width:560px){ .sde-sc-score .n{font-size:30px} .sde-hero .big .n{font-size:34px} .sde-hero .nm{font-size:18px} } /* ---------- 赛季筛选条 ---------- */ .sde-season-bar{display:flex;justify-content:flex-end;align-items:flex-end;gap:12px;margin:-2px 0 4px} .sde-season-bar .shiny-input-container{width:auto;min-width:150px;margin-bottom:8px} .sde-season-bar label{color:var(--muted);font-size:12px;margin-bottom:3px} .sde-season-bar .btn{margin-bottom:8px;white-space:nowrap} /* ---------- 比赛卡片:主页比分明细 + 我的逐场登记(天生响应式,手机不溢出) ---------- */ .sde-mc-list{display:flex;flex-direction:column;gap:10px} .sde-mc{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.07); border-radius:12px;padding:11px 14px} .sde-mc-top{display:flex;align-items:center;gap:10px;flex-wrap:wrap} .sde-mc-date{font-variant-numeric:tabular-nums;color:var(--muted);font-size:13px;min-width:74px} .sde-mc-opp{font-weight:700;color:var(--cream)} .sde-mc-note{color:var(--muted);font-size:12px;opacity:.8} .sde-mc-score{font-weight:800;font-size:16px;color:var(--gold-2); font-variant-numeric:tabular-nums;letter-spacing:.04em} .sde-mc-detail{display:flex;gap:8px 20px;flex-wrap:wrap;margin-top:9px;padding-top:9px; border-top:1px dashed rgba(255,255,255,.10);font-size:13px} .sde-mc-detail .lbl-goal{color:var(--gold-2);font-weight:700} .sde-mc-detail .lbl-assist{color:var(--blue);font-weight:700} .sde-mc-detail .nm{color:var(--cream)} /* 逐场登记控件:出勤 / 进球 / 助攻,超窄屏自动换行 */ .sde-ctl-row{display:flex;gap:14px 22px;flex-wrap:wrap;align-items:center;margin-top:11px} .sde-ctl{display:flex;align-items:center;gap:9px} .sde-ctl-l{font-size:13px;color:var(--muted);font-weight:600} .sde-mc-form .shiny-input-container{margin-bottom:0} .sde-mc-form .form-control{padding:5px 8px;text-align:center} .sde-foot{color:var(--muted);text-align:center;font-size:12px;margin-top:30px;padding-top:18px; border-top:1px solid rgba(255,255,255,.08)} """ def crest(size: int = 52) -> ui.Tag: """队徽圆形徽章。""" return ui.div( ui.img(src=CREST_URL, alt="肆带贰队徽"), class_="sde-crest", style=f"width:{size}px;height:{size}px", ) def result_badge(r: str) -> ui.Tag: return ui.span(r, class_=f"badge-res badge-{r}") def ha_pill(home_away: str) -> ui.Tag: is_home = home_away == "home" return ui.span("主" if is_home else "客", class_="ha-pill " + ("ha-home" if is_home else "")) def card(title: str, *body, icon: str = "", sub: str = "") -> ui.Tag: head = ui.div( (ui.span(icon, class_="ic") if icon else None), ui.span(title, class_="t"), class_="sde-card-h", ) sub_el = ui.div(sub, class_="sde-sub") if sub else None return ui.div(head, sub_el, *body, class_="sde-card") def stat(value, label: str, sub: str = "", accent: str = "gold") -> ui.Tag: return ui.div( ui.div(str(value), class_="v"), ui.div(label, class_="l"), (ui.div(sub, class_="s") if sub else None), class_=f"sde-stat accent-{accent}", )