:root { --ink:#101a34; --muted:#65708a; --blue:#2454c6; --ice:#eef5ff; --line:#cdd8ed; --paper:#fbfcff; --glass:rgba(235,244,255,.72); }
* { box-sizing:border-box; } html { scroll-behavior:smooth; } body { margin:0; color:var(--ink); background:var(--paper); font-family:Inter,"PingFang SC","Microsoft YaHei",sans-serif; line-height:1.6; overflow-x:hidden; } button,a { font:inherit; } button { cursor:pointer; } a { color:inherit; text-decoration:none; } .skip-link { position:fixed; top:-4rem; left:1rem; z-index:100; background:var(--ink); color:#fff; padding:.6rem 1rem; } .skip-link:focus { top:1rem; }
.site-header { position:fixed; z-index:30; top:18px; left:50%; display:flex; align-items:center; width:min(1360px,calc(100% - 40px)); min-height:60px; padding:0 13px 0 20px; border:1px solid rgba(137,159,201,.42); background:rgba(255,255,255,.87); box-shadow:0 10px 30px rgba(33,65,123,.09); backdrop-filter:blur(16px); transform:translateX(-50%); }
.wordmark { display:flex; align-items:baseline; gap:.5rem; font-weight:800; letter-spacing:.05em; } .wordmark span { color:var(--muted); font-size:.63rem; font-weight:600; letter-spacing:.12em; } .primary-nav { display:flex; align-items:center; gap:4px; margin:auto; } .primary-nav a { padding:.52rem .72rem; border:1px solid transparent; color:#526078; font-size:.82rem; white-space:nowrap; transition:.2s; } .primary-nav a:hover,.primary-nav a.is-active { color:var(--ink); border-color:#d4e1f7; background:linear-gradient(135deg,rgba(255,255,255,.96),rgba(220,235,255,.72)); box-shadow:inset 0 1px rgba(255,255,255,.9),0 3px 10px rgba(69,113,180,.1); border-radius:999px; } .menu-toggle { border:0; background:none; color:var(--ink); font-weight:700; font-size:.8rem; display:none; }
main { max-width:1440px; margin:auto; } .hero,.section,.contact { padding-left:clamp(24px,7vw,112px); padding-right:clamp(24px,7vw,112px); } .hero { position:relative; display:grid; grid-template-columns:1.35fr .65fr; align-items:center; min-height:820px; padding-top:130px; overflow:hidden; } .eyebrow,.index { margin:0 0 .8rem; color:var(--blue); font-family:ui-monospace,monospace; font-size:.71rem; font-weight:800; letter-spacing:.12em; } h1,h2,h3,p { margin-top:0; } h1 { max-width:780px; margin-bottom:1.3rem; font-size:clamp(3.3rem,7vw,7.7rem); line-height:.92; letter-spacing:-.085em; } h1 span { display:block; margin-top:.75rem; color:var(--blue); font-size:clamp(1.2rem,2.3vw,2rem); letter-spacing:.02em; } .statement { max-width:650px; margin-bottom:.8rem; font-size:clamp(1.3rem,2.3vw,2.1rem); font-weight:650; line-height:1.35; } .intro { max-width:600px; color:var(--muted); font-size:1rem; } .hero-links { display:flex; gap:2rem; margin:2.3rem 0; } .text-link { border-bottom:1px solid var(--ink); padding-bottom:.25rem; font-size:.88rem; font-weight:700; } .text-link span { color:var(--blue); } .status { color:var(--muted); font-size:.8rem; }.portrait-wrap { position:relative; min-height:470px; display:grid; place-items:center; }.portrait-placeholder { position:relative; z-index:2; display:flex; flex-direction:column; justify-content:space-between; width:min(290px,78%); aspect-ratio:.76; padding:1rem; overflow:hidden; color:#eaf1fe; background:linear-gradient(145deg,#0d1c3d,#356bcf 55%,#a8c9ff); box-shadow:20px 25px 0 #d9e5f8; }.portrait-placeholder::before { position:absolute; inset:18% 20% 26%; border:1px solid rgba(255,255,255,.55); border-radius:50% 50% 45% 45%; content:""; }.portrait-placeholder strong { margin:auto; color:rgba(255,255,255,.93); font-size:5rem; letter-spacing:-.1em; }.portrait-placeholder small { font-size:.63rem; }.orb { position:absolute; border-radius:50%; background:radial-gradient(circle at 30% 25%,#fff 0,rgba(234,246,255,.8) 15%,rgba(74,125,210,.35) 55%,rgba(25,71,160,.15)); filter:drop-shadow(0 15px 15px rgba(39,75,135,.15)); }.orb-one { top:8%; right:1%; width:130px; aspect-ratio:1; }.orb-two { bottom:5%; left:0; width:70px; aspect-ratio:1; }.scroll-cue { position:absolute; bottom:35px; left:clamp(24px,7vw,112px); color:var(--muted); font-family:ui-monospace,monospace; font-size:.68rem; letter-spacing:.1em; }.scroll-cue span { color:var(--blue); font-size:1rem; }
.section { padding-top:135px; padding-bottom:135px; border-top:1px solid var(--line); }.section-heading { max-width:590px; }.section-heading h2,.contact h2 { margin-bottom:.65rem; font-size:clamp(2.3rem,4vw,4rem); line-height:1; letter-spacing:-.065em; }.section-heading > p:last-child { color:var(--muted); }.timeline-section { position:relative; overflow:hidden; }.timeline-controls { position:absolute; top:145px; right:clamp(24px,7vw,112px); display:flex; align-items:center; gap:.85rem; color:var(--muted); font-family:ui-monospace,monospace; font-size:.7rem; }.timeline-controls button,.gallery-controls button { border:1px solid var(--line); background:#fff; color:var(--ink); width:34px; height:34px; transition:.2s; }.timeline-controls button:hover,.gallery-controls button:hover { background:var(--blue); color:#fff; }.timeline { display:grid; grid-auto-flow:column; grid-auto-columns:minmax(280px,34vw); gap:18px; margin-top:4rem; padding:32px calc(50% - 17vw) 58px; overflow-x:auto; overscroll-behavior-x:contain; scroll-behavior:smooth; scroll-padding-inline:calc(50% - 17vw); scroll-snap-type:x mandatory; scrollbar-width:thin; }.timeline-card { min-height:330px; padding:1.4rem; border:1px solid var(--line); background:#fff; opacity:.62; scroll-snap-align:center; transform:translateY(34px) rotate(-2.5deg) scale(.91); transform-origin:center bottom; transition:transform .45s,opacity .45s,box-shadow .45s,border-color .45s; }.timeline-card[data-distance="-1"] { transform:translateY(10px) rotate(-1.3deg) scale(.96); }.timeline-card[data-distance="1"] { transform:translateY(10px) rotate(1.3deg) scale(.96); }.timeline-card[data-distance="-2"],.timeline-card[data-distance="2"] { opacity:.48; transform:translateY(42px) scale(.86); }.timeline-card.is-current { border-color:#8bafe9; opacity:1; box-shadow:0 24px 48px rgba(48,86,150,.17); transform:translateY(-20px) scale(1.03); }.period { color:var(--blue); font-size:.78rem; font-weight:800; }.timeline-card h3 { margin-bottom:.12rem; font-size:1.2rem; }.card-role { margin-bottom:1rem; color:var(--muted); font-size:.9rem; }.card-summary { min-height:3.6em; font-size:.85rem; }.timeline-card ul { margin:1rem 0 0; padding-left:1.05rem; color:#3f4b63; font-size:.78rem; }.timeline-card li+li { margin-top:.45rem; }
.projects { background:#f3f7fd; }.project-grid { display:grid; grid-template-columns:1.1fr .9fr; gap:20px; margin-top:3rem; }.project-card { position:relative; min-height:390px; padding:1.2rem; border:1px solid #c5d4ee; background:#fff; color:var(--ink); text-align:left; overflow:hidden; transition:transform .25s,box-shadow .25s; }.project-card:hover,.interest-card:hover { box-shadow:0 18px 34px rgba(45,80,142,.16); transform:translateY(-5px); }.project-cover { display:grid; min-height:250px; place-items:center; background:repeating-linear-gradient(45deg,#e6effd,#e6effd 10px,#f9fbff 10px,#f9fbff 20px); color:#6481b4; font-family:ui-monospace,monospace; font-size:.75rem; }.project-2 .project-cover { background:linear-gradient(150deg,#183a7a,#8db6ef); color:#fff; }.project-meta { display:block; margin:1rem 0 .25rem; color:var(--muted); font-size:.75rem; }.project-card strong { display:block; font-size:1.5rem; }.project-open { position:absolute; right:1.2rem; bottom:1.3rem; font-size:.76rem; font-weight:700; }.project-open b { color:var(--blue); font-size:1rem; }
.skills-interests { overflow:hidden; }.skill-groups { display:grid; grid-template-columns:repeat(5,1fr); gap:16px; margin:3rem 0 7rem; }.skill-group { min-height:165px; padding:1rem; border-top:2px solid var(--blue); background:#fff; }.skill-group h3 { font-size:.88rem; }.skill-chip { display:inline-block; margin:0 .28rem .4rem 0; padding:.26rem .45rem; border:1px solid #d3def0; border-radius:999px; color:#43506a; font-size:.72rem; transition:transform .2s; }.skill-chip:hover { transform:translateY(-2px); }.interests { display:grid; grid-template-columns:repeat(4,1fr); border-top:1px solid var(--ink); }.interests-heading { grid-column:1/-1; display:flex; justify-content:space-between; padding:.75rem 0; color:var(--muted); font-size:.71rem; letter-spacing:.1em; }.interests-heading p { margin:0; font-family:ui-monospace,monospace; }.interest-card { position:relative; display:flex; min-height:240px; flex-direction:column; align-items:flex-start; padding:1rem; border:1px solid var(--line); border-left:0; background:linear-gradient(135deg,#f6faff,#e9f3ff); color:var(--ink); text-align:left; transition:transform .25s,box-shadow .25s; }.interest-card:first-of-type { border-left:1px solid var(--line); }.interest-card:nth-child(3) { background:linear-gradient(145deg,#dfeaff,#f8fbff); }.interest-card:nth-child(4) { background:linear-gradient(145deg,#fff,#eef3fb); }.interest-card:nth-child(5) { background:linear-gradient(145deg,#d2e4ff,#f4f8ff); }.interest-card > span { color:var(--blue); font:700 .7rem ui-monospace,monospace; }.interest-card strong { margin:auto 0 .1rem; font-size:1.7rem; }.interest-card em { color:var(--muted); font-size:.78rem; font-style:normal; }.interest-card b { position:absolute; top:1rem; right:1rem; color:var(--blue); }
.contact { position:relative; min-height:680px; padding-top:125px; overflow:hidden; background:#0e214b; color:#fff; }.contact .eyebrow { color:#a6c8ff; }.contact h2 { position:relative; z-index:2; }.email,.phone { position:relative; z-index:2; display:block; width:max-content; margin-top:1.1rem; border-bottom:1px solid rgba(255,255,255,.65); font-size:clamp(1rem,2vw,1.35rem); }.phone { color:#b8d4ff; }.bubble-field i { position:absolute; border:1px solid rgba(220,240,255,.5); border-radius:50%; background:radial-gradient(circle at 34% 22%,rgba(255,255,255,.85),rgba(151,197,255,.26) 35%,rgba(38,76,160,.25) 70%); box-shadow:inset -10px -14px 25px rgba(0,26,96,.28),0 12px 35px rgba(0,0,0,.17); animation:float 7s ease-in-out infinite alternate; }.bubble-field i:nth-child(1) { width:170px;height:170px;right:10%;top:11%; }.bubble-field i:nth-child(2) { width:72px;height:72px;right:30%;top:20%;animation-delay:-2s; }.bubble-field i:nth-child(3) { width:215px;height:215px;right:18%;bottom:-35px;animation-delay:-4s; }.bubble-field i:nth-child(4) { width:42px;height:42px;right:4%;bottom:28%; }.bubble-field i:nth-child(5) { width:105px;height:105px;right:43%;bottom:8%;animation-delay:-1s; }.bubble-field i:nth-child(6) { width:58px;height:58px;right:36%;top:43%; }.bubble-field i:nth-child(7) { width:28px;height:28px;right:7%;top:48%; }.contact footer { position:absolute; z-index:2; bottom:22px; color:#b6c8e8; font-size:.7rem; }
.modal[hidden] { display:none; }.modal { position:fixed; z-index:60; inset:0; display:grid; place-items:center; padding:22px; }.modal-backdrop { position:absolute; inset:0; background:rgba(9,19,43,.6); backdrop-filter:blur(7px); }.modal-panel { position:relative; width:min(780px,100%); max-height:min(780px,calc(100vh - 44px)); overflow:auto; padding:clamp(1.4rem,4vw,3.6rem); background:#fbfdff; box-shadow:0 25px 80px rgba(0,0,0,.28); }.modal-close { position:absolute; top:.9rem; right:.9rem; width:36px; height:36px; border:0; background:#e9f2ff; color:var(--ink); font-size:1.5rem; }.modal-lead { color:var(--muted); }.gallery-art { display:grid; min-height:350px; place-items:center; color:#fff; background:linear-gradient(145deg,#0d285b,#75a5e8); }.gallery-art span { font-size:clamp(4rem,15vw,10rem); font-weight:800; opacity:.55; }.gallery-2 { background:linear-gradient(145deg,#7b97aa,#d3e7f5,#3c5e8d); }.gallery-3 { background:linear-gradient(145deg,#45345e,#9985c2,#d9c7dc); }.gallery-4 { background:linear-gradient(145deg,#0d4860,#72acba,#e6e7d1); }.gallery-controls { display:flex; align-items:center; justify-content:space-between; margin-top:1rem; font:700 .76rem ui-monospace,monospace; }.gallery-controls button { width:auto; padding:0 .8rem; }.case-study { display:grid; grid-template-columns:repeat(2,1fr); gap:1px; margin-top:2rem; background:var(--line); border:1px solid var(--line); }.case-study article { padding:1rem; background:#fff; }.case-study h3 { margin-bottom:.3rem; color:var(--blue); font-size:.78rem; }.case-study p,.detail-slot p { margin:0; color:#4b5871; font-size:.85rem; }.detail-slot { min-height:240px; display:grid; place-items:center; padding:2rem; border:1px dashed #88a9dc; background:linear-gradient(135deg,#f5f9ff,#e6f0ff); text-align:center; }.detail-slot span { color:var(--blue); font:700 .72rem ui-monospace,monospace; }
:focus-visible { outline:3px solid #efaa38; outline-offset:3px; } .modal-open { overflow:hidden; } @keyframes float { to { transform:translate3d(10px,-18px,0) scale(1.05); } }
@media (max-width:1200px) { .site-header { width:calc(100% - 24px); }.primary-nav { gap:0; }.primary-nav a { padding:.48rem .48rem; font-size:.75rem; }.skill-groups { grid-template-columns:repeat(3,1fr); }.timeline { grid-auto-columns:minmax(260px,42vw); padding-inline:calc(50% - 21vw); scroll-padding-inline:calc(50% - 21vw); }.hero { min-height:720px; } }
@media (max-width:900px) { .site-header { min-height:56px; }.menu-toggle { display:block; margin-left:auto; }.primary-nav { position:absolute; top:calc(100% + 8px); right:0; display:none; width:min(320px,calc(100vw - 24px)); padding:8px; border:1px solid var(--line); background:#fff; box-shadow:0 16px 32px rgba(24,53,104,.15); }.primary-nav.is-open { display:grid; }.primary-nav a { padding:.65rem; }.resume-unavailable { margin:0 0 0 10px; color:var(--muted); font-size:.7rem; }.hero { grid-template-columns:1fr .55fr; }.portrait-placeholder { width:85%; }.timeline { grid-auto-columns:minmax(250px,58vw); padding-inline:calc(50% - 29vw); scroll-padding-inline:calc(50% - 29vw); }.interests { grid-template-columns:repeat(2,1fr); }.interest-card:nth-of-type(3) { border-left:1px solid var(--line); }.contact { min-height:620px; } }
@media (max-width:700px) { .site-header { top:8px; width:calc(100% - 16px); padding-left:13px; }.wordmark span { display:none; }.resume-download { margin-left:8px; padding:.44rem .5rem .44rem .72rem; font-size:.72rem; }.hero,.section,.contact { padding-left:20px; padding-right:20px; }.hero { display:flex; min-height:auto; flex-direction:column; align-items:stretch; padding-top:112px; padding-bottom:100px; }.hero-copy { display:contents; }.hero .eyebrow { order:0; }.hero h1 { order:1; }.portrait-wrap { order:2; min-height:330px; margin:1.2rem 0; }.statement { order:3; }.intro { order:4; }.hero-links { order:5; }.status { order:6; }.portrait-placeholder { width:190px; }.portrait-placeholder strong { font-size:3.8rem; }.scroll-cue { left:20px; bottom:22px; }.section { padding-top:85px; padding-bottom:85px; }.timeline-controls { position:static; justify-content:flex-end; margin-top:1.5rem; }.timeline { grid-auto-columns:calc(100% - 28px); gap:14px; margin-top:1.4rem; padding:16px 14px 30px; scroll-padding-inline:14px; }.timeline-card { min-width:0; min-height:300px; transform:translateY(12px) scale(.95); }.timeline-card[data-distance="-1"],.timeline-card[data-distance="1"] { transform:translateY(7px) scale(.98); }.timeline-card.is-current { transform:translateY(-5px) scale(1); }.project-grid { grid-template-columns:1fr; margin-top:2rem; }.project-card { min-height:340px; }.project-cover { min-height:210px; }.skill-groups { grid-template-columns:repeat(2,1fr); gap:9px; margin:2rem 0 4rem; }.skill-group { min-height:135px; }.interests { grid-template-columns:1fr; }.interest-card,.interest-card:nth-of-type(3) { min-height:160px; border-left:1px solid var(--line); border-bottom:0; }.interest-card:last-child { border-bottom:1px solid var(--line); }.contact { min-height:600px; padding-top:90px; }.bubble-field i:nth-child(1) { right:-26px; top:8%; }.bubble-field i:nth-child(3) { right:-42px; }.case-study { grid-template-columns:1fr; }.modal { padding:10px; }.modal-panel { max-height:calc(100vh - 20px); padding:3rem 1.2rem 1.4rem; }.gallery-art { min-height:260px; } }
@media (prefers-reduced-motion:reduce) { html { scroll-behavior:auto; } *,*::before,*::after { animation-duration:.01ms !important; animation-iteration-count:1 !important; transition-duration:.01ms !important; } .bubble-field i { animation:none; } }

/* Confirmed 2026-09 sakura hero */
main { max-width:1600px; }
.site-header { top:20px; width:min(1360px,calc(100% - 48px)); min-height:70px; padding:0 24px 0 32px; border-color:rgba(255,255,255,.9); border-radius:20px; background:rgba(255,255,255,.78); box-shadow:0 14px 42px rgba(74,55,77,.1); backdrop-filter:blur(20px); }
.wordmark { color:#25242c; font-size:.92rem; font-weight:700; letter-spacing:.22em; }
.primary-nav { gap:12px; }
.primary-nav a { padding:.6rem 1rem; color:#55515a; font-size:.82rem; }
.primary-nav a:hover,.primary-nav a.is-active { border-color:rgba(255,255,255,.4); color:#fff; background:linear-gradient(145deg,#26252b,#09090b); box-shadow:0 9px 20px rgba(18,16,22,.18); }
/* 顶部栏「简历」：不再展开菜单，点了直接下载——右侧那个深色圆底向下箭头就是「可下载」的记号 */
.resume-download { display:inline-flex; flex:0 0 auto; align-items:center; gap:.44rem; margin-left:12px; padding:.5rem .6rem .5rem .92rem; border:1px solid rgba(218,213,220,.78); border-radius:999px; background:rgba(255,255,255,.66); color:#3f3b44; font-weight:600; font-size:.8rem; line-height:1; white-space:nowrap; transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease,background .18s ease; }
.resume-download__ico { display:grid; place-items:center; width:1.3rem; height:1.3rem; color:#2a2535; }
.resume-download__ico svg { width:1rem; height:1rem; stroke-width:1.9; }
.resume-download:hover { transform:translateY(-1px); border-color:rgba(186,178,194,.95); background:rgba(255,255,255,.94); box-shadow:0 10px 22px rgba(60,45,70,.14); }
.resume-download:focus-visible { outline:2px solid #b247ff; outline-offset:2px; }

.hero { isolation:isolate; grid-template-columns:minmax(430px,.86fr) minmax(520px,1.14fr); min-height:min(940px,100vh); padding-top:130px; padding-bottom:0; }
.hero::after { position:absolute; z-index:-3; inset:0; background:linear-gradient(90deg,rgba(255,255,255,.16),rgba(255,255,255,.58) 47%,rgba(255,255,255,.1)); content:""; }
.hero-copy { position:relative; z-index:4; align-self:center; padding:1rem 0 7rem 1.25rem; }
.hero-kicker { margin-bottom:1.5rem; color:#aaa2ac; font-size:.62rem; font-weight:700; letter-spacing:.2em; }
.hero h1 { max-width:610px; margin-bottom:1rem; color:#17161d; font-size:clamp(4rem,5.5vw,6rem); font-weight:800; line-height:1.08; letter-spacing:-.065em; }
.hero h1 .hero-hi { display:block; margin:0 0 .14em; color:inherit; font-size:1em; letter-spacing:inherit; }
.hero-role { position:relative; width:fit-content; margin:0 0 1.25rem; color:#b247ff; font-size:clamp(1.35rem,2vw,2rem); font-weight:800; line-height:1.2; text-shadow:0 5px 18px rgba(190,92,255,.2); }
.hero .statement { margin:0; color:#4c4851; font-size:clamp(1rem,1.4vw,1.26rem); font-weight:450; line-height:1.65; }
.hero-tags { display:flex; flex-wrap:wrap; gap:12px; margin-top:1.7rem; }
.hero-tags span { min-width:98px; padding:.62rem 1rem; border:1px solid rgba(225,214,224,.74); border-radius:12px; background:rgba(255,255,255,.54); box-shadow:inset 0 1px rgba(255,255,255,.9),0 8px 22px rgba(143,105,139,.05); color:#514c54; font-size:.78rem; text-align:center; backdrop-filter:blur(8px); }
.hero .hero-links { display:flex; gap:16px; margin:2.1rem 0 0; }
.hero-button { display:grid; width:160px; min-height:56px; place-items:center; border:1px solid rgba(224,216,225,.65); border-radius:14px; font-size:.9rem; font-weight:600; transition:transform .18s ease,box-shadow .18s ease,background .18s ease; }
.hero-button:hover { transform:translateY(-2px); }
.hero-button--primary { border-color:#151418; background:linear-gradient(145deg,#26252a,#09090b); box-shadow:0 12px 24px rgba(21,19,23,.18); color:#fff; }
.hero-button--secondary { background:rgba(255,255,255,.72); box-shadow:0 9px 24px rgba(108,84,108,.07); color:#252229; backdrop-filter:blur(10px); }

.portrait-wrap { position:relative; z-index:2; align-self:end; min-height:760px; height:calc(100% - 112px); pointer-events:none; }
.portrait-halo { position:absolute; z-index:-1; right:8%; bottom:3%; width:min(620px,92%); height:72%; border-radius:50% 50% 8% 8% / 54% 54% 8% 8%; background:linear-gradient(145deg,rgba(238,213,248,.75),rgba(220,210,255,.46) 60%,rgba(255,255,255,.12)); filter:blur(.2px); }
.portrait-photo { position:absolute; right:0; bottom:0; width:min(700px,100%); height:100%; object-fit:contain; object-position:center bottom; mix-blend-mode:multiply; filter:saturate(.88) contrast(.98); -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 86%,transparent 100%); mask-image:linear-gradient(to bottom,#000 0%,#000 86%,transparent 100%); }
.hero-aside { position:absolute; z-index:4; top:27%; right:2.5%; display:flex; flex-direction:column; gap:.35rem; color:#a9a3ad; font-size:.62rem; letter-spacing:.18em; }
.hero-aside i { display:block; width:1px; height:58px; margin-top:1.2rem; background:#ccc5ce; }
.scroll-cue { z-index:5; bottom:40px; display:flex; flex-direction:column; gap:.55rem; color:#aaa3ad; letter-spacing:.18em; }
.scroll-cue span { color:#76717a; font-size:1.1rem; }

.sakura-field { position:absolute; z-index:3; inset:0; overflow:hidden; pointer-events:none; }
.sakura-petal { --petal-opacity:.62; position:absolute; top:-14vh; left:var(--petal-left); width:var(--petal-size); height:calc(var(--petal-size) * .72); border-radius:78% 22% 70% 30% / 58% 30% 70% 42%; background:linear-gradient(145deg,rgba(255,255,255,.96),rgba(255,183,215,.88) 58%,rgba(235,122,180,.76)); box-shadow:0 2px 7px rgba(232,129,178,.18); opacity:var(--petal-opacity); transform:rotate(var(--petal-rotation)); animation:sakura-fall var(--petal-duration) linear var(--petal-delay) infinite; will-change:transform; }
.sakura-petal::after { position:absolute; right:7%; bottom:5%; width:48%; height:42%; border-radius:50%; background:rgba(255,255,255,.45); content:""; filter:blur(1px); }
.sakura-petal--far { --petal-opacity:.28; filter:blur(1.6px); }
.sakura-petal--middle { --petal-opacity:.5; filter:blur(.55px); }
.sakura-petal--near { --petal-opacity:.76; box-shadow:0 4px 10px rgba(229,125,179,.22); }
@keyframes sakura-fall { 0% { transform:translate3d(0,-8vh,0) rotate(var(--petal-rotation)); } 28% { transform:translate3d(calc(var(--petal-drift) * -.28),28vh,0) rotate(calc(var(--petal-rotation) + 110deg)); } 62% { transform:translate3d(calc(var(--petal-drift) * .55),66vh,0) rotate(calc(var(--petal-rotation) + 250deg)); } 100% { transform:translate3d(var(--petal-drift),112vh,0) rotate(calc(var(--petal-rotation) + 430deg)); } }

@media (max-width:1100px) {
  .hero { grid-template-columns:minmax(390px,.9fr) minmax(430px,1.1fr); }
  .portrait-wrap { min-height:680px; }
  .hero-aside { display:none; }
  .primary-nav { gap:2px; }
  .primary-nav a { padding:.55rem .6rem; }
}
@media (max-width:900px) {
  .site-header { width:calc(100% - 24px); min-height:58px; border-radius:16px; }
  .hero { grid-template-columns:1fr .85fr; min-height:760px; padding-top:105px; }
  .hero-copy { padding-left:0; }
  .portrait-wrap { min-height:610px; height:calc(100% - 90px); }
  .hero-tags span { min-width:82px; padding:.5rem .72rem; }
  .hero-button { width:138px; min-height:50px; }
}
@media (max-width:700px) {
  .hero { display:grid; grid-template-columns:1fr; min-height:auto; padding-top:112px; padding-bottom:86px; }
  .hero-copy { display:block; padding:2rem 0 0; }
  .hero-kicker { margin-bottom:1rem; }
  .hero h1 { font-size:clamp(3.4rem,15vw,4.8rem); }
  .hero-role { font-size:1.3rem; }
  .hero .statement { font-size:.98rem; }
  .portrait-wrap { min-height:440px; height:auto; margin:0; }
  .portrait-photo { right:50%; width:min(430px,112%); transform:translateX(50%); }
  .portrait-halo { right:3%; width:94%; height:80%; }
  .hero-tags { gap:8px; }
  .hero-tags span { flex:1 1 calc(50% - 8px); }
  .hero .hero-links { gap:10px; }
  .hero-button { width:auto; flex:1; }
  .scroll-cue { display:none; }
  .sakura-petal:nth-child(3n) { display:none; }
}
@media (prefers-reduced-motion:reduce) { .sakura-petal { animation:none; } }

/* Reference palette: warm paper, blush at left, lavender at lower right. */
main { max-width:none; }
/* ==========================================================================
   整站底色（2026-09-11 修正）
   页面是连续的一条瀑布流，底色就只能是「一整张」，而不是每个模块各铺一层。
   做法：底色只画在 body::before 这一层，并 fixed 在视口上——它不属于任何 section，
   所以模块与模块之间不可能出现接缝；往下滚，同一片粉紫始终垫在所有内容下面。
   配色直接沿用首屏原本那套径向渐变，首屏观感零变化。
   注意：body 自己不能再有不透明底色，否则会盖住这一层；底色交给 html。
   ========================================================================== */
html { background:#faf6f3; }
body { background:transparent; }
body::before {
  position:fixed; z-index:-1; inset:0; content:"";
  background:
    radial-gradient(ellipse at 25% 20%,rgba(255,220,238,.55),transparent 49%),
    radial-gradient(ellipse at 96% 92%,rgba(228,224,245,.62),transparent 50%),
    radial-gradient(ellipse 42% 36% at 70% 54%,rgba(255,240,248,.42),transparent 68%),
    #faf6f3;
}
/* 一屏一模块：高度取视口，内容自适应；620px 为兜底，仅极矮窗口才允许滚动 */
.hero { min-height:620px; height:100svh; padding:112px max(5vw,calc((100vw - 1200px)/2)) 0; grid-template-columns:1fr 1.05fr; }
.hero::after { display:none; }
.site-header { top:18px; width:min(1244px,calc(100% - 64px)); min-height:72px; border:1px solid rgba(255,255,255,.65); background:rgba(255,250,251,.74); box-shadow:0 14px 36px rgba(116,83,105,.09); border-radius:22px; }
.wordmark { font-weight:500; }
.nav-pending { border:0; padding:.6rem 1rem; background:transparent; color:#55515a; font:inherit; font-size:.82rem; white-space:nowrap; opacity:1; cursor:default; }
.hero-copy { padding:0 0 50px; }
.hero h1 { font-size:clamp(58px,5.5vw,92px); }
.hero-tags { flex-wrap:nowrap; }
.hero-tags span { min-width:0; }
.portrait-wrap { align-self:stretch; height:auto; min-height:0; margin:0; }
.portrait-frame { display:contents; }
.portrait-photo { position:absolute; top:auto; right:0; bottom:0; left:auto; width:100%; max-width:none; height:96%; object-fit:contain; object-position:center bottom; mix-blend-mode:normal; filter:none; mask-image:none; -webkit-mask-image:none; }
.hero-role { color:#bf67f1; text-shadow:0 3px 12px #d9a5fa77; }
/* 「Product Manager / 产品经理」底下那条暖橙粗杠：伪元素画，
   粗细 / 位置都写成 em，跟着字号一起缩放（窄屏 15px 与宽屏 32px 观感一致） */
.hero-role::after { position:absolute; left:-.015em; right:-.015em; bottom:-.31em; height:.25em; border-radius:999px; background:linear-gradient(90deg,#ffceaa,#f79a63 48%,#ffceaa); box-shadow:0 2px 6px rgba(247,154,99,.25); content:""; z-index:-1; }
@media (max-width:1100px) { .nav-pending { padding:.5rem .45rem; } .hero { grid-template-columns:1fr 1fr; } .hero h1 { font-size:60px; } .hero-role { font-size:23px; } }
@media (max-width:900px) { .nav-pending { text-align:left; padding:.65rem; } .hero { padding-inline:30px; } .hero h1 { font-size:52px; } .hero-tags { gap:6px; } .hero-tags span { padding:.5rem; } .portrait-photo { top:auto; width:100%; height:96%; } }

/* 顶部导航在笔记本宽度下保持完整展示，仅在 700px 以下折叠为「目录」 */
@media (min-width:701px) and (max-width:940px) {
  .menu-toggle { display:none; }
  .primary-nav { position:static; display:flex; width:auto; margin:auto; padding:0; gap:2px; border:0; background:none; box-shadow:none; }
  .primary-nav a, .nav-pending { padding:.5rem .45rem; font-size:.76rem; text-align:center; white-space:nowrap; }
  .resume-download { margin-left:8px; padding:.46rem .54rem .46rem .78rem; font-size:.74rem; }
  .wordmark { font-size:.84rem; }
}
/* 移动端一屏：文案随视口高度微缩，照片区吃掉剩余高度，任何视口都不滚动 */
@media (max-width:700px) {
  .site-header { width:calc(100% - 24px); padding:0 16px; min-height:56px; }
  .wordmark { font-size:.78rem; }
  .hero { height:100svh; min-height:0; display:flex; flex-direction:column; padding:86px 20px 0; }
  .hero-copy { padding:0; }
  .hero h1 { margin-bottom:clamp(.6rem,1.6svh,.95rem); font-size:clamp(30px,min(10.5vw,5.2svh),48px); }
  .hero-role { margin-bottom:clamp(.5rem,1.3svh,.8rem); font-size:clamp(15px,min(4.9vw,2.9svh),21px); }
  .hero .statement { font-size:clamp(12.5px,min(3.8vw,2.3svh),15.5px); line-height:1.5; }
  .hero-tags { flex-wrap:wrap; gap:clamp(5px,1.1svh,8px); margin-top:clamp(9px,1.9svh,18px); }
  .hero-tags span { flex:1 1 calc(50% - 7px); padding:clamp(.3rem,.95svh,.45rem) .5rem; font-size:clamp(10.5px,1.8svh,12px); }
  .hero .hero-links { margin-top:clamp(10px,2svh,20px); gap:10px; }
  .hero-button { min-height:clamp(44px,5.9svh,56px); font-size:clamp(.8rem,1.9svh,.9rem); }
  .portrait-wrap { flex:1 1 auto; width:100%; height:auto; min-height:196px; margin-top:clamp(6px,1.4svh,14px); }
  .portrait-photo { top:auto; bottom:0; left:auto; right:50%; width:min(340px,96%); height:100%; transform:translateX(50%); object-position:center bottom; }
}

/* ==========================================================================
   教育背景 —— 两张等大的竖版信息卡（2026-09-12 第四轮：对齐 + 加大 + 铺满）
   版面依据用户给的竖版卡片参考图：上半张校园照，下半「序号 + 校名 + 三项信息 + 标签」。
   两张卡等宽等高、结构完全对称。引导区是左上角「标题 / 英文 / 寄语」三行堆叠。
   ========================================================================== */
.edu {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column;
  /* 高度固定占满一屏：这样 flex 链能把「卡片台面」的高度确定下来，
     slot 的 height:100% 才会真正生效（否则 stage 高度被卡片内容撑高、卡片永远超出一屏）。
     卡片高度 = 台面高，永远落在 100svh 之内，一屏就能显示完。 */
  height:100svh; min-height:640px;
  /* —— 水平版心**必须**与其它模块一致（.hero / .exp 都是 max(5vw,calc((100vw - 1200px)/2))），
     这样「教育背景」的标题左边缘和下方各模块标题在同一条竖线上。
     上一版这里单独写成 1440px，标题就比别的模块整体错开了一截 —— 别再写成分外的值。 —— */
  --edu-hgutter:max(5vw,calc((100vw - 1200px)/2));
  /* 上下留白上大下小：顶部躲开悬浮导航条（top:18px + min-height:72px ⇒ 底边 90px）。
     —— 用户第五、六轮反复要求「文案往下坐一点、卡片往上提一点」：
     顶部留白调到 96~128（1536×703 下 = 104），标题墨迹离导航条底边约 17px；
     底部留白同步放大到 20~34，卡片底边离视口底约 24px，整组不再贴底。 —— */
  --edu-pad-t:clamp(96px,14.8svh,128px);
  --edu-pad-b:clamp(20px,3svh,34px);
  --edu-gap:clamp(14px,1.7vw,30px);
  --edu-lead-gap:clamp(10px,1.6svh,20px);
  /* 卡片整块的「高宽比预算」：卡内纵向各块加起来 = 115u（u = 1% 卡宽），
     即内容天然需要约 1.153 倍卡宽的高度。这里取 1.17 留 ~1.5% 余量。
     ⚠ 这个数必须 ≥ 卡内纵向预算（见下面 .edu-card / .edu-media / .edu-meta 等处的 --u 倍数），
     否则卡片会算得过宽、内容排不下 —— 改卡内留白时同步改这里。 */
  --edu-card-ratio:1.17;
  /* 引导区实测高度 = 标题行 + 英文行 + 寄语两行（寄语里是 <br>，行数固定）。
     这里把 .exp-intro 那套字号**逐项**写进算式，而不是拍一个「约 300px」的常数 ——
     以后改引导区字号，改上面那几个 clamp，这个算式跟着同步即可。 */
  --edu-intro-h:calc(
      clamp(34px,6svh,80px) * 1.02
    + clamp(1px,.5svh,8px) + clamp(16px,2.7svh,35px) * 1.15
    + clamp(9px,1.7svh,26px) + clamp(11px,1.55svh,15.5px) * 1.7 * 2
  );
  /* 卡片可用高度 = 一屏 - 上下留白 - 引导区 - 间距；夹一个 300px 下限，
     极矮窗口也不会算出负数把卡片挤没。 */
  --edu-stage-h:max(300px,calc(100svh - var(--edu-pad-t) - var(--edu-pad-b) - var(--edu-intro-h) - var(--edu-lead-gap)));
  padding:var(--edu-pad-t) var(--edu-hgutter) var(--edu-pad-b);
  /* 底色属于整站那一层（body::before），这里只加一团居中柔光做氛围 */
  background:radial-gradient(ellipse 34% 30% at 50% 54%,rgba(206,194,238,.32),transparent 72%);
}
.edu-petals { z-index:1; }
.edu-inner { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; gap:var(--edu-lead-gap); width:100%; max-width:1200px; margin:0 auto; }

/* —— 引导区：标题 / 英文 / 寄语三行左对齐堆叠 ——
   字号、行高、上边距逐项对齐工作经历页的 .exp-intro，两个模块的文案块同规格。
   用户希望「左文案往下坐一点」——这里给 intro 加一个 margin-top
   把整块文案下推(下一行);配合 .edu-stage 的负 margin-top 把卡片上拉,
   两者在 section 中部自然错开,视觉上更和谐。 */
.edu-intro { display:flex; flex-direction:column; align-items:flex-start; margin-top:clamp(24px,3.5svh,52px); }
.edu-intro h2 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(34px,6svh,80px); line-height:1.02; letter-spacing:-.05em; }
.edu-en { margin:clamp(1px,.5svh,8px) 0 0; color:#6c5ce7; font-weight:800; font-size:clamp(16px,2.7svh,35px); line-height:1.15; letter-spacing:-.015em; }
.edu-lead { margin:clamp(9px,1.7svh,26px) 0 0; max-width:26em; color:#55668a; font-size:clamp(11px,1.55svh,15.5px); line-height:1.7; }

/* —— 卡片台面：两张等大卡片，整组水平居中。
   上一版在这里加了 translateX 右移，结果左边空出一大片、左右不对称 —— 已撤掉。 —— */
/* 卡片台面：两张等大卡片，整组水平居中。
   上一版在这里加了 translateX 右移，结果左侧空出一大片、左右不对称 —— 已撤掉。
   这次把「右移」重新加回来，但右移量锁死在「右侧可用余量」之内（见 --edu-shift），
   1920 一类宽屏下卡片已占满版心，余量为负就自动不移动，不会溢出。 */
.edu-stage {
  display:flex; flex:1 1 auto; align-items:center; justify-content:center;
  gap:var(--edu-gap); min-height:0;
  container-type:inline-size;
  /* 用户希望「右卡片往上提一点」——这里给 stage 加一个负 margin-top,
     把整组卡片往上拉(与 .edu-intro 的正向 margin-top 配合,实现「左下右上」错位)。
     clamp 上限用 0 防止某些窗口算成正数把布局推乱。 */
  margin-top:clamp(-100px,-12svh,-52px);
  /* 卡片宽取「半个台面宽」与「台面高 / 卡片比例」里小的，slot 继承这个变量当宽度。
     ⚠ 第一项用 50%（不是 50cqw）：cq 单位只认**祖先**容器，元素自己身上写 cqw 会退化成
     视口尺寸 —— 宽屏上会算出「半个屏幕宽」，两张卡直接冲出屏幕。50% 在本元素（transform）
     和子元素（slot 的 width）里都按「台面宽度」解析，两边一致。
     ⚠ 第二项的分母是 --edu-card-ratio（卡内纵向预算 1.153 倍卡宽 + 余量）。
     第五轮这里写的是 1.2，比卡内实际需要的 1.366 小 —— 卡片被算宽了 14%，
     卡内「标签行」正好被 overflow:hidden 切掉，用户看到的就是「内容没显示完」。
     现在卡片高度由内容决定（.edu-slot/.edu-card 都是 height:auto），宽度守住这个比例，
     内容永远排得下。 */
  --card-w:min(calc(50% - var(--edu-gap) / 2),calc(var(--edu-stage-h) / var(--edu-card-ratio)));
  /* 整组右移：取「右侧可用余量的一半以内」，永远不会溢出屏幕 */
  --edu-shift:min(clamp(0px,11cqw,160px),calc((100cqw - 2 * var(--card-w) - var(--edu-gap)) / 2));
  transform:translateX(var(--edu-shift));
}

/* 容器查询另立一层 .edu-slot：cq 单位**不能**引用元素自身，
   若把 container-type 直接挂在 .edu-card 上，卡自己的 padding / radius
   会落回视口尺寸（1440×900 下 1cqmin 变 9px 而不是 4.4px），卡内字号跟着错位。
   放在外层 slot 上，卡片和卡内所有子元素就都量到同一个「卡片尺寸」。

   卡宽取两个约束里小的那个：
     ① 一半台面宽（再减半个间距）—— 两张卡 + 间距正好填满与其它模块对齐的那条版心；
     ② 台面高 / 1.2 —— 卡片不能顶出屏幕。1.2 是卡片的「标称」高宽比，
        照片用 flex 把富余高度全吸走，所以实际比例只会比它更大、不会裁到文字。

   ⚠ 这里写的是 50cqw 而不是 50%：.edu-stage 也是一层 container，
   50cqw = 台面宽度的一半。**不能写百分比** —— --card-w 下面还要用在 max-height 上，
   而百分比在 height/max-height 里是按「高度」解析的，会被算成「(台面高-间距)/2」，
   卡片会突然变矮一截（正是用户在 1152×720 一类窗口上会踩到的坑）。 */
.edu-slot {
  container-type:inline-size;
  /* --card-w 定义在 .edu-stage（container 挂在 stage 上，50cqw 才是「半台面宽」），
     这里只继承使用；slot 自带的 container 仅服务于卡内 --u:1cqw。
     高度交回内容（height:auto）：卡有多高由卡内各块决定，
     --card-w 的比例约束保证它 ≤ 台面高，于是「内容完整 + 不超一屏」同时成立。 */
  width:var(--card-w);
  height:auto;
}
.edu-card {
  position:relative; overflow:hidden;
  display:flex; flex-direction:column;
  --u:1cqw;
  width:100%; height:auto;
  padding:calc(var(--u) * 4) calc(var(--u) * 4.4) calc(var(--u) * 4.2);
  border:1px solid rgba(255,255,255,.94);
  border-radius:calc(var(--u) * 6.6);
  background:linear-gradient(168deg,#ffffff,#fdfcff 44%,#f6f1ff);
  box-shadow:0 24px 54px rgba(112,84,152,.14),inset 0 1px rgba(255,255,255,.94);
  opacity:0; transform:translateY(18px);
  transition:opacity .6s ease,transform .6s cubic-bezier(.22,.61,.36,1),box-shadow .35s ease;
}
.edu-card.is-visible { opacity:1; transform:none; }
.edu-card:hover { box-shadow:0 32px 66px rgba(112,84,152,.2),inset 0 1px rgba(255,255,255,.94); transform:translateY(-4px); }

/* 照片：高度由比例定，不再用 flex 吸剩余高度 ——
   卡片高度改成由内容决定后，「剩余高度」这个概念没有了；
   照片写死 aspect-ratio（1.85 ≈ 49u 高）是为了让整卡高度 = 一个确定的 u 总数，
   这样 --edu-card-ratio 才能和卡内预算严格对上（见 .edu 与 .edu-stage 的注释）。
   ⚠ min-height:0 不能省：flex 项的自动最小尺寸（min-height:auto）会用「图片本身的高度」当
   下限，aspect-ratio 就被顶掉了 —— 实测卡片会因此高出 58px，把标签行整个顶出台面。
   取景用 .edu-slot:nth-child() 选中（用 .edu-card:nth-child() 会两张都命中：
   卡片是各自 slot 里的第一个子元素）。 */
.edu-media { flex:0 0 auto; aspect-ratio:1.85; min-height:0; margin:0; }
.edu-photo-clip { display:block; height:100%; overflow:hidden; border-radius:calc(var(--u) * 4.4); background:#e8e4f2; }
.edu-photo { display:block; width:100%; height:100%; object-fit:cover; object-position:center; transition:transform .55s cubic-bezier(.22,.61,.36,1); }
.edu-stage .edu-slot:nth-child(1) .edu-photo { object-position:center 8%; }
.edu-stage .edu-slot:nth-child(2) .edu-photo { object-position:center 27%; }
.edu-card:hover .edu-photo { transform:scale(1.045); }

/* —— 序号 + 校名：浅紫大字 + 一条竖线 + 校名 / 英文名 ——
   下面四块的上下间距（3.4→2.9、5→4、1.4→1.15、5.2/4.4→4.2/3.4）是第六轮为「一屏排下」
   统一收紧的一档：合计省下约 5.5u（≈ 卡宽的 5.5%），换成照片高度的余量。 */
.edu-head { display:flex; flex:0 0 auto; align-items:center; gap:calc(var(--u) * 2.6); margin-top:calc(var(--u) * 2.9); }
.edu-no { flex:0 0 auto; margin:0; color:#d5cbf8; font-weight:800; font-size:calc(var(--u) * 16.4); line-height:.86; letter-spacing:-.05em; }
.edu-name { min-width:0; padding-left:calc(var(--u) * 3.2); border-left:1px solid #e5e1f3; }
.edu-name h3 { margin:0; color:#1e2a3c; font-weight:800; font-size:calc(var(--u) * 8.4); line-height:1.06; letter-spacing:-.03em; }
.edu-en-name { margin:calc(var(--u) * 1.4) 0 0; color:#69779c; font-weight:600; font-size:calc(var(--u) * 3.2); letter-spacing:.19em; white-space:nowrap; }

/* —— 三项信息：图标 + 标签 + 值。三个标签都是四个字，值自然对齐 —— */
.edu-meta { display:grid; flex:0 0 auto; gap:calc(var(--u) * 1.15); margin:calc(var(--u) * 4) 0 0; padding:0; list-style:none; }
.edu-meta li { display:flex; align-items:center; gap:calc(var(--u) * 2.6); color:#7d8cab; font-size:calc(var(--u) * 4.4); line-height:1.2; }
.edu-meta svg { flex:0 0 auto; width:calc(var(--u) * 6.6); height:calc(var(--u) * 6.6); color:#7b68f2; }
.edu-meta strong { margin-left:calc(var(--u) * 1.4); color:#233246; font-weight:700; }

/* —— 底部标签：一条淡分隔线 + 短紫杠 + 双一流 · 985 · 211 ——
   line-height 必须写死：这行是 <p>，不写会继承 body 的大行高。 */
.edu-tags { display:flex; flex:0 0 auto; align-items:center; gap:calc(var(--u) * 4.6); margin:calc(var(--u) * 4.2) 0 0; padding-top:calc(var(--u) * 3.4); border-top:1px solid #eae7f6; color:#2f3e56; font-size:calc(var(--u) * 4.6); font-weight:700; line-height:1.25; }
.edu-tags i { display:block; flex:0 0 auto; width:calc(var(--u) * 8.7); height:calc(var(--u) * 1.1); border-radius:999px; background:linear-gradient(90deg,#9d8aec,#7b68f2); }

/* 校徽（2026-09-12 第三轮）：用户要求整体去掉，卡内卡外都不再放 logo，
   素材 assets/logo-*.webp 仍保留在仓库里，只是不再引用。 */

/* 矮屏：上一版这里用 @media (max-height:860px/700px) 把 --edu-pad-t 压到 92/88px，
   结果在 1536×703（笔记本 125% 缩放）这类窗口上把新写的 96~128 clamp 又盖回去了 ——
   文案被顶到导航条底下、卡片贴住视口底边。现在上下留白全部由 .edu 里那两条 svh clamp
   自适应（屏越矮留白越小），不再另写覆盖值。 */

/* 移动端：两张卡上下排，卡片高度交回内容；容器查询轴仍是 inline-size、--u 用 1cqw，
   照片要给回固定比例（此时纵向没有 stage 高度可吸） */
@media (max-width:700px) {
  .edu { min-height:100svh; padding:96px 20px 56px; }
  .edu-inner { gap:20px; }
  /* 窄屏不需要「错位」效果,两个 margin 都清掉 */
  .edu-intro { margin-top:0; }
  .edu-stage { flex-direction:column; align-items:stretch; gap:20px; transform:none; margin-top:0; }
  .edu-slot { width:100%; height:auto; }
  .edu-card { height:auto; }
  .edu-media { flex:0 0 auto; aspect-ratio:1.5; min-height:0; }
  .edu-head { margin-top:calc(var(--u) * 5.6); }
  .edu-tags { margin-top:calc(var(--u) * 7); }
}

/* ==========================================================================
   工作经历 —— 三张实习卡片插在「文件夹」口袋里，点击可换到中间 + 居中详情弹窗
   版面依据用户给的参考图：左侧引导文案、右上短句、下方居中的文件夹与扇形卡片。
   背景沿用首屏那套粉紫径向渐变，只把两处光斑再错开一次——色彩连续，但不重复。
   ========================================================================== */
.exp {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; justify-content:center;
  height:100svh; min-height:620px;
  padding:88px var(--exp-gutter) 18px;
  /* 卡片高度是唯一的「主尺寸」，文件夹、袋口深度、下沉量、扇形张角、
     卡片内所有字号，全部按参考图实测比例由它推出 —— 改一个数整体等比缩放。
     参考图（1536×1024）实测量得：
       卡片宽高比 1 : 1.19（.84，接近方卡，不是瘦长条）；
       文件夹高 = .70 × 卡片高（是一只又宽又高的大托盘，占视口下方约 1/3）；
       袋口弧线最低点离文件夹底边 = .44 × 文件夹高（约在托盘高度正中）；
       左右两张的横向偏移 = .92 × 卡片宽（三张卡紧挨成一扇）。
     卡片「插进」文件夹，是本页的核心观感：
       默认（插入态）卡片整体下沉 --card-sink，下缘被前袋盖住约 15% 卡高；
       点一下（升起态）卡片上浮，只剩约 4% 卡高没入袋口 —— 像把卡片从文件夹里抽出来。
     尺寸同时受两个上限约束，取小：
       高度 —— 升起态需要「卡片底边到顶」= --card-rise + 卡片高 = 1.268 × 卡片高，
               叠加顶栏 88、文案区约 18svh、下留白 18 → 70svh − 140px；
       宽度 —— 文件夹不能比「视口两侧各留 clamp(16px,4vw,80px)」更宽，否则窄窗口被裁
               （.3903 = 1 ÷ (1.19 × 3.05 × 1.075)，由卡片高推回卡片宽再推回卡片高）。 */
  --exp-gutter:max(5vw,calc((100vw - 1200px)/2));
  --folder-max:min(calc(100vw - 2 * clamp(16px,4vw,80px)),2000px);
  /* 卡片比上一版整体放大约 8%(74svh / 0.42)：
     1) 让标签/名字/role 字号自然跟着变粗,不再有"大字配小字"的空荡感;
     2) 扇形 3 张撑满文件夹后,中间那张抽出来视觉重量更稳;
     3) --card-rise/.12/.05 这一组比例保持不动,只放大基准尺寸,不会改变"没入袋口"那一截的相对位置。 */
  /* 卡片比上一版再放大一档(78svh / .44 / 880):
     背面要装下 header + "主要工作" + 3 段每段 ~3-4 行的详细工作,
     原 .42 算出来背面可用高度 ~580px,3 段+头~550px 时刚好贴边,排版一紧就溢出;
     调到 .44 后可用 ~610px,留出 60px 缓冲。卡片整体高了约 5%,扇形比例不变。 */
  --card-h:min(clamp(340px,calc(78svh - 145px),880px),calc(var(--folder-max) * .44));
  --card-w:calc(var(--card-h) * .84);
  --folder-h:calc(var(--card-h) * .70);
  --pocket-lip:calc(var(--folder-h) * .44);   /* 袋口弧线最低点距文件夹底边 */
  --card-rise:calc(var(--card-h) * .308);     /* 升起态：卡片底边刚好落在袋口线上（没入 0%） */
  --card-sink:calc(var(--card-h) * .12);      /* 插入态相对升起态下沉多少（没入约 12%） */
  --fan-x:calc(var(--card-w) * .92);
  --overhang:calc(var(--card-h) - var(--folder-h) + var(--card-rise));
  --folder-w:calc(var(--card-w) * 3.05);
  --folder-r:calc(var(--card-w) * .058);
  --card-pad:calc(var(--card-w) * .052);
  /* 只留一团居中的柔光，不含底色——接缝问题的根因就是不透明底色 */
  background:radial-gradient(ellipse 34% 30% at 50% 62%,rgba(214,204,242,.34),transparent 70%);
}
.exp-petals { z-index:1; }
.exp-inner { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; min-height:0; }

/* —— 引导文案 / 右上短句 —— */
.exp-intro { padding-top:clamp(2px,.8svh,14px); }
.exp-intro h2 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(34px,6svh,80px); line-height:1.02; letter-spacing:-.05em; }
.exp-en { margin:clamp(1px,.5svh,8px) 0 0; color:#6c5ce7; font-weight:800; font-size:clamp(16px,2.7svh,35px); line-height:1.15; letter-spacing:-.015em; }
.exp-lead { margin:clamp(9px,1.7svh,26px) 0 0; max-width:26em; color:#55668a; font-size:clamp(11px,1.55svh,15.5px); line-height:1.7; }
.exp-aside { position:absolute; top:clamp(5px,1.4svh,20px); right:0; display:flex; flex-direction:column; gap:clamp(2px,.4svh,5px); margin:0; color:#7c86a4; font-size:clamp(10px,1.45svh,13.5px); letter-spacing:.16em; text-align:right; }
.exp-aside i { display:block; width:clamp(26px,3.4vw,48px); height:3px; margin:0 0 clamp(5px,.9svh,11px) auto; border-radius:3px; background:linear-gradient(90deg,rgba(151,132,226,0),#a998e8); }

/* —— 舞台：给卡片「探出文件夹」的那截预留高度；文件夹贴底，
      富余的高度全部落在文案与卡片之间（高分辨率大屏才不会下面吊一块空白） —— */
.exp-stage { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; align-items:center; justify-content:flex-end; padding-top:var(--overhang); min-height:0; }

/* —— 文件夹：背面底板 + 前袋。前袋占满文件夹整个高度，
      袋口是一条「两端高、中间下凹约 27%」的浅弧，卡片从这里插进去。 —— */
.exp-folder { position:relative; flex:0 0 auto; width:min(var(--folder-w),var(--folder-max)); height:var(--folder-h); }
.exp-folder__back { position:absolute; z-index:0; inset:0; border-radius:var(--folder-r); background:linear-gradient(170deg,#f9f7ff,#f1ecfe); box-shadow:0 24px 56px rgba(126,96,150,.1),inset 0 1px rgba(255,255,255,.75); }
.exp-fan { position:absolute; z-index:1; inset:0; }
/* 前袋压在整个卡片层之上（外层 .exp-fan 的 z-index:1 已形成层叠上下文，
   所以这里只要比 1 大即可）：卡片下缘因此「没入」袋口，才是从文件夹抽出来的观感 */
.exp-folder__pocket { position:absolute; z-index:3; inset:0; overflow:hidden; border-radius:var(--folder-r); }
.exp-pocket-shape { display:block; width:100%; height:100%; }
.exp-pocket-mark { position:absolute; bottom:calc(var(--folder-h) * .07); left:50%; display:flex; flex-direction:column; align-items:center; gap:clamp(5px,.9svh,10px); transform:translateX(-50%); }
.exp-pocket-mark i { display:block; width:calc(var(--card-w) * .15); height:3px; border-radius:3px; background:linear-gradient(90deg,rgba(151,132,226,0),#a08fe0,rgba(151,132,226,0)); }
.exp-pocket-mark em { color:#8d7fd0; font-style:italic; font-weight:600; font-size:max(9px,calc(var(--card-w) * .042)); line-height:1.44; letter-spacing:.01em; text-align:center; }

/* —— 卡片：竖向卡（图在上、文在下），以底边中点为轴心做扇形旋转 ——
   卡内所有尺寸一律写成 --card-w 的百分比：卡片多大字就多大，
   不会再出现「卡片放大了、字还是原来那么小」的单薄感。
   卡片本身保留原来的扇形位移/旋转/缩放，3D 翻面交给子元素 .exp-card__inner，
   两套 transform 互不干扰。 */
.exp-card {
  position:absolute; left:50%;
  /* 卡片底边位置 = 升起位 − 当前下沉量。
     默认（插入态）沉在文件夹里，下缘被前袋盖掉约 24% 卡高；
     加 .is-active 后 --card-drop 归零，卡片上浮到「升起位」，只剩约 8% 没入袋口。 */
  bottom:calc(var(--card-rise) - var(--card-drop) + var(--fan-lift,0px));
  --card-drop:var(--card-sink);
  display:flex; flex-direction:column;
  width:var(--card-w); height:var(--card-h);
  /* 下留白故意比左右大：卡片下缘是「没入袋口」的那一截,
     标签底边必须落在袋口弧线之上,所以不能用四边等距的内边距。
     历史: .22 → .16 → .08。.16 仍然让卡片下半露出 128px 白底,
     用户反馈"下面空白很多,紫色框范围还可以扩大",
     改 .08 后白底缩到 64px,face 紫框往下延伸覆盖更多卡面,袋口吞感略减。 */
  padding:var(--card-pad) var(--card-pad) calc(var(--card-h) * .08);
  border:1px solid rgba(255,255,255,.92); border-radius:calc(var(--card-w) * .045);
  background:linear-gradient(168deg,#fff,#fdfbff);
  box-shadow:0 18px 38px rgba(112,84,152,.16),inset 0 1px rgba(255,255,255,.9);
  transform-origin:50% 100%;
  transform:translateX(calc(-50% + var(--fx,0px))) translateY(calc(var(--fy,0px) + var(--lift,0px))) rotate(var(--rot,0deg)) scale(var(--sc,1));
  transition:transform .62s cubic-bezier(.22,.61,.36,1),bottom .62s cubic-bezier(.22,.61,.36,1),opacity .5s ease,box-shadow .4s ease;
  opacity:1; cursor:pointer;
  /* 之前有 overflow:hidden（2026-09-12 撤掉）—— 原本是为"被袋口吞"做兜底,
     但袋子其实是用 .exp-folder__pocket (z-index:3) 盖在卡片下沿上,不是靠裁切。
     卡片自身的 overflow:hidden 反而会兜底切掉 03 那段主要工作,
     撤掉后 .exp-card__face 内的内容能自然溢出 inner 边界,文字不再被卡。 */
  /* 3D 翻面需要 perspective,但只对居中那张生效 —— 旁边两张 scale .88 又斜转,
     perspective 太大会让左右卡也跟着歪,看起来像没对准。 */
  perspective:1200px;
}
/* 「抽出来」的那张：浮到升起位，完整露出 */
.exp-card.is-active { --card-drop:0px; }
.exp-card.is-center { --fx:0px; --rot:0deg; --sc:1; z-index:3; }
/* 左右两张要额外抬一点：它们缩到 .88、又斜着转，缩放让卡内下留白跟着缩水，
   但被袋口吃掉的高度是绝对值 —— 不补这一截，最外侧那颗标签就会压在袋口线上。
   补偿量 = 缩放损失（约 .12 陪下留白）+ 旋转让外侧下角多掉的十几像素。 */
.exp-card.is-right { --fx:var(--fan-x); --rot:6.6deg; --sc:.88; --fan-lift:calc(var(--card-h) * .05); z-index:2; }
.exp-card.is-left { --fx:calc(-1 * var(--fan-x)); --rot:-6.6deg; --sc:.88; --fan-lift:calc(var(--card-h) * .05); z-index:1; }
.exp-card:hover { --lift:calc(var(--card-h) * -.022); box-shadow:0 26px 52px rgba(112,84,152,.22),inset 0 1px rgba(255,255,255,.9); }
.exp-card:focus-visible { outline:3px solid rgba(124,104,238,.6); outline-offset:4px; }
/* 入场：先从袋口里"升"出来。默认态可读（JS 失效时卡片照常显示），未展开时才隐藏 */
.exp-stage:not(.is-visible) .exp-card { opacity:0; --fy:32%; }

/* —— 3D 翻面：内层做旋转，外层只管扇形位置 —— */
.exp-card__inner {
  position:relative; flex:1 1 auto; min-height:0;
  transform-style:preserve-3d;
  transition:transform .85s cubic-bezier(.22,.61,.36,1);
}
.exp-card.is-flipped .exp-card__inner { transform:rotateY(180deg); }
/* face 底边溢出 inner 8%*card-h（= 64px）= .exp-card 下 padding 区域,
   让 face 紫渐变背景覆盖到卡片下沿,没有"卡底白边"。
   配合 .exp-card 撤掉 overflow:hidden (2026-09-12) 一起工作,
   翻面时 face 整体跟着 inner 水平旋转,延伸部分不参与旋转,仍在卡底位置。 */
.exp-card__face {
  position:absolute; top:0; left:0; right:0; bottom:calc(var(--card-h) * -.08);
  display:flex; flex-direction:column;
  border-radius:calc(var(--card-w) * .045);
  background:linear-gradient(168deg,#fff,#fdfbff);
  -webkit-backface-visibility:hidden; backface-visibility:hidden;
  /* 背面预转 180°,这样被翻到正面时朝向才对（否则镜像）
     用 preserve-3d 才会真的翻过去,否则两面相同时正面直接覆盖背面,翻不动 */
  transform:rotateY(0deg);
}
.exp-card__face--back { transform:rotateY(180deg); background:linear-gradient(170deg,#fdfbff,#f6f1fe); }

/* 数字提到图片上方,跟图分开 —— 不再压在照片上,改成独立的紫色编号行。
   字号比原来小一档(从 .072 卡宽降到 .058):不再像海报上的烫金大字,
   而更像目录/章节的序号,跟 logo + 名字那行视觉权重接近。 */
.exp-no { display:block; color:#6c5ce7; font-weight:800; font-size:max(16px,calc(var(--card-w) * .058)); line-height:1; letter-spacing:-.02em; margin:0 0 calc(var(--card-w) * .02); }

.exp-card__media { position:relative; flex:0 0 auto; width:100%; aspect-ratio:1.6; overflow:hidden; border-radius:calc(var(--card-w) * .028); background:#e9e3f4; }
/* object-fit: cover 铺满整个图片区 —— 用户截图是 16:9 偏宽,媒体区 1.6 偏方,
   横向多出来的部分用 object-position:center 自动左右均匀裁掉,
   主体内容(车/聊天窗/虚拟舞台)本来就在画面正中,裁掉两侧留白不影响。
   上一版用 contain + 浅紫底补空,被反馈"比例不对没占满",改回 cover。 */
.exp-cover { display:block; width:100%; height:100%; object-fit:cover; object-position:center; transition:transform .55s cubic-bezier(.22,.61,.36,1); }
.exp-card:hover .exp-cover { transform:scale(1.035); }
/* 封面底部柔光层：让右下角"周期"白字压在照片上时还能读 —— 因为现在用 contain,
   图片上下可能有留白,这个渐变要跟着图片底部走,不能只跟 media 底部。
   简单办法:在 media 内再叠一层,把渐变放在图片"显示区域"的下沿。
   取 100% 渐变太靠下,改 70%~100% 让柔光在视觉中线下方。 */
.exp-media__shade { position:absolute; inset:0; pointer-events:none; background:linear-gradient(180deg,rgba(40,30,70,0) 70%,rgba(40,30,70,.32) 100%); }
.exp-media__period { position:absolute; right:calc(var(--card-w) * .03); bottom:calc(var(--card-w) * .022); display:inline-flex; align-items:center; gap:calc(var(--card-w) * .012); padding:calc(var(--card-w) * .012) calc(var(--card-w) * .022); border-radius:999px; background:rgba(255,255,255,.86); color:#3b3a5a; font-size:max(10px,calc(var(--card-w) * .03)); font-weight:600; line-height:1; letter-spacing:.02em; backdrop-filter:blur(6px); }
.exp-media__period svg { color:#6c5ce7; }

.exp-card__body { display:flex; flex:1 1 auto; flex-direction:column; min-height:0; padding-top:calc(var(--card-w) * .022); }
.exp-card__head { display:flex; align-items:center; gap:calc(var(--card-w) * .022); }
/* 头里的箭头 hint:占右侧一点空间、不抢戏;hover 卡片时整条右移 2px 提示"点这里翻"。
   用 transform 而不是 margin —— 移回去不留空隙、不影响布局。 */
.exp-card__hint { margin-left:auto; display:inline-flex; align-items:center; color:rgba(108,92,231,.55); transition:transform .3s cubic-bezier(.22,.61,.36,1),color .25s ease; }
.exp-card:hover .exp-card__hint { color:#6c5ce7; transform:translateX(calc(var(--card-w) * .012)); }
/* 背面 hint 镜像 + 变浅,提示"再点翻回" */
.exp-card__hint--back { color:rgba(108,92,231,.4); transform:scaleX(-1); }
.exp-card.is-flipped:hover .exp-card__hint--back { color:#6c5ce7; transform:scaleX(-1) translateX(calc(var(--card-w) * .012)); }
/* 已经翻到背面的卡,正面的 hint 隐藏(视觉上只剩背面那只) */
.exp-card.is-flipped .exp-card__face--front .exp-card__hint { opacity:0; }
.exp-tile { display:grid; flex:0 0 auto; place-items:center; width:calc(var(--card-w) * .125); aspect-ratio:1; overflow:hidden; border-radius:28%; background:transparent; }
.exp-tile--plate { border:1px solid #eceaf4; background:#fff; box-shadow:0 2px 6px rgba(104,84,150,.08); }
.exp-tile__img { display:block; width:76%; height:76%; object-fit:contain; }
.exp-tile:not(.exp-tile--plate) .exp-tile__img { width:100%; height:100%; object-fit:cover; }
.exp-card__names { display:flex; flex-direction:column; min-width:0; }
.exp-card__name { display:flex; align-items:baseline; gap:.3em; color:#1e2a3c; font-weight:800; font-size:max(12px,calc(var(--card-w) * .048)); line-height:1.2; letter-spacing:-.012em; }
.exp-card__en { color:#3b4a63; font-weight:700; font-size:.86em; letter-spacing:.02em; }
.exp-card__role { margin-top:calc(var(--card-w) * .007); color:#7b8dab; font-style:normal; font-weight:600; font-size:max(9.5px,calc(var(--card-w) * .036)); line-height:1.35; }
.exp-motto { margin:calc(var(--card-w) * .028) 0 0; color:#4c5f80; font-size:max(10px,calc(var(--card-w) * .04)); line-height:1.55; }
/* tags 紧贴 motto 上方,不再用 margin:auto 0 0 把 tags 推到 body 最底。
   之前:auto 让 tags 一直沉在 body 底部,跟 motto 之间留出大段空白,"和上面内容很脱离"。
   现在:margin:0 + padding-top:.012 ≈ 9px,让 tags 跟 motto 形成自然节奏,下方留白留给卡片整体呼吸。
   gap .019 + padding .016 .036 字号 .034 维持原样,只是位置往上挪。 */
.exp-tags { display:flex; flex-wrap:wrap; gap:calc(var(--card-w) * .019); margin:0; padding:calc(var(--card-w) * .012) 0 0; list-style:none; }
.exp-tags li { padding:calc(var(--card-w) * .016) calc(var(--card-w) * .036); border-radius:999px; background:#ece7fb; color:#6c5ce7; font-weight:700; font-size:max(8.5px,calc(var(--card-w) * .034)); line-height:1.5; white-space:nowrap; }

/* —— 正面底部「查看详情」入口已改为头部的 .exp-card__hint 箭头 ——
   上一版的"查看详情"按钮被反馈"太丑",改成贴 head 右侧的细箭头,只在 hover 时
   微微右移提示"点这儿翻"。这样按钮和文字标签共享一行,卡内更整洁。 */

/* 旧的 .exp-card__flip-btn / .exp-card__flip-back 规则全部移除:
   - 正面:点卡片本身即可翻,不需要按钮入口
   - 背面:再点卡片即可折回,不需要"返回"按钮 */

/* —— 背面：标题区 + 周期 + 摘要 + 主要工作 + 标签 + 返回 ——
   整体 padding 比正面小一档,让文字有呼吸感而不挤;
   "主要工作"用带序号的列表,序号是浅紫大字,内容是深色正文,视觉上比纯 bullet 更"作品集"。 */
/* 上下 padding 改成对称,数值从 card-h 算;
   .035 配合上面把 --card-h 调到 78svh 后,背面可用高度从 ~580 提到 ~640,
   3 段详细工作 + 头能完整装下。
   配合 face 延伸底 8%*card-h (2026-09-12),face 实际可用高度
   = inner(下pad=.08) + 延伸(.08) - 上下padding(.07) = 740px 左右,
   头+中间(垂直居中)+hint 都能布得开。 */
.exp-card__face--back { padding:calc(var(--card-h) * .035) calc(var(--card-w) * .07); }
.exp-back__head { display:flex; align-items:center; gap:calc(var(--card-w) * .03); margin:0; }
.exp-back__title { display:flex; flex-direction:column; min-width:0; }
.exp-back__name { display:flex; align-items:baseline; gap:.3em; color:#1e2a3c; font-weight:800; font-size:max(13px,calc(var(--card-w) * .05)); line-height:1.2; letter-spacing:-.012em; }
.exp-back__en { color:#3b4a63; font-weight:700; font-size:.82em; letter-spacing:.02em; }
.exp-back__role { margin-top:calc(var(--card-w) * .005); color:#7b8dab; font-style:normal; font-weight:600; font-size:max(9.5px,calc(var(--card-w) * .032)); line-height:1.35; }
/* summary 和 tags、period 已从背面移除(2026-09-12):用户希望背面只保留
   头部(logo+name+role) + 主要工作,所以删掉它们的死 CSS。
   序号/正文字号略收、间距收一档,让精简后的 3 条文案整体放进卡内不溢出。 */
.exp-back__subtitle { margin:calc(var(--card-w) * .022) 0 calc(var(--card-w) * .012); color:#1e2a3c; font-weight:800; font-size:max(10.5px,calc(var(--card-w) * .034)); letter-spacing:.02em; display:flex; align-items:center; gap:calc(var(--card-w) * .016); }
.exp-back__subtitle::after { content:''; flex:1 1 auto; height:1px; background:linear-gradient(90deg,rgba(108,92,231,.35),transparent); }
/* list 用 flex:1 1 auto + 内部列居中 —— 配合 face 高度延伸到卡底 (.08) 后,
   list 占据中间剩余空间,3 条 li 在 list 区域垂直居中,上下均有紫底呼吸,
   解决"下面空白很多"的问题（不再是文字聚顶、紫底空一大块）。 */
.exp-back__list { flex:1 1 auto; display:flex; flex-direction:column; justify-content:center; gap:calc(var(--card-w) * .022); margin:0; padding:0; list-style:none; }
.exp-back__list li { display:flex; align-items:flex-start; gap:calc(var(--card-w) * .02); color:#3a4860; font-size:max(10.5px,calc(var(--card-w) * .034)); line-height:1.55; }
.exp-back__num { flex:0 0 auto; color:#c5b8f5; font-weight:800; font-size:max(11.5px,calc(var(--card-w) * .044)); line-height:1.4; font-feature-settings:"tnum"; }
.exp-back__text { flex:1 1 auto; min-width:0; }
/* hint 翻面按钮:用 margin-top:auto 把它推到 face 底边附近,
   跟 list 居中形成上下呼应,头在顶、hint 在底、内容居中。 */
.exp-card__hint--back { margin-top:auto; align-self:flex-end; }

.exp-card__flip-back {
  position:absolute; top:calc(var(--card-w) * .03); right:calc(var(--card-w) * .03);
  display:inline-flex; align-items:center; gap:calc(var(--card-w) * .01);
  padding:calc(var(--card-w) * .012) calc(var(--card-w) * .022);
  border:1px solid rgba(108,92,231,.22); border-radius:999px;
  background:rgba(255,255,255,.7); color:#6c5ce7;
  font-size:max(9px,calc(var(--card-w) * .028)); font-weight:700; line-height:1.4;
  cursor:pointer; backdrop-filter:blur(6px);
  transition:background .2s ease,color .2s ease,border-color .2s ease,transform .25s cubic-bezier(.22,.61,.36,1);
}
.exp-card__flip-back:hover,
.exp-card__flip-back:focus-visible { background:#6c5ce7; color:#fff; border-color:#6c5ce7; transform:translateX(calc(var(--card-w) * -.008)); }
.exp-card__flip-back svg { flex:0 0 auto; transition:transform .25s ease; }
.exp-card__flip-back:hover svg { transform:translateX(-2px); }

/* 翻面激活时,卡片的 focus 轮廓要跟着翻过去 —— 否则正面 outline 留在原地像 bug */
.exp-card.is-flipped:focus-visible { outline-color:rgba(124,104,238,.7); }

/* 旧的 .exp-card__flip-back 按钮规则已删除(再点卡片就翻回,不需要按钮)。 */

/* —— 详情弹窗：居中面板 + 灰色遮罩 —— */
.ui-modal { position:fixed; z-index:60; inset:0; display:grid; place-items:center; padding:clamp(16px,3vw,40px); }
.ui-modal[hidden] { display:none; }
.ui-modal__scrim { position:absolute; inset:0; background:rgba(38,32,54,.42); backdrop-filter:blur(7px); opacity:0; transition:opacity .26s ease; }
.ui-modal.is-open .ui-modal__scrim { opacity:1; }
.ui-modal__panel { position:relative; z-index:1; width:min(560px,100%); max-height:min(84svh,760px); overflow-y:auto; overscroll-behavior:contain; padding:clamp(20px,3.4svh,34px); border:1px solid rgba(255,255,255,.9); border-radius:clamp(18px,2.4svh,28px); background:linear-gradient(168deg,#fff,#fdfaff); box-shadow:0 40px 90px rgba(60,42,96,.3); opacity:0; transform:translateY(16px) scale(.96); transition:opacity .26s ease,transform .3s cubic-bezier(.22,.61,.36,1); }
.ui-modal.is-open .ui-modal__panel { opacity:1; transform:none; }
.ui-modal__panel:focus { outline:none; }
.ui-modal__close { position:absolute; top:clamp(12px,1.8svh,18px); right:clamp(12px,1.8svh,18px); display:grid; place-items:center; width:clamp(28px,3.5svh,36px); aspect-ratio:1; border:1px solid #e7e2f3; border-radius:12px; background:rgba(255,255,255,.92); color:#4d4763; transition:background .18s ease,color .18s ease,border-color .18s ease; }
.ui-modal__close:hover { border-color:#241f2e; background:#241f2e; color:#fff; }
.ui-modal__close svg { width:52%; height:52%; }
.ui-modal__head { display:flex; align-items:center; gap:clamp(9px,1.1vw,15px); padding-right:clamp(32px,4vw,46px); }
.ui-modal__head .exp-tile { width:clamp(38px,5.2svh,58px); border-radius:26%; }
.ui-modal__names { display:flex; flex-direction:column; min-width:0; }
.ui-modal__names h3 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(15px,2.1svh,21px); line-height:1.28; letter-spacing:-.02em; }
.ui-modal__role { margin:clamp(3px,.5svh,6px) 0 0; color:#6c5ce7; font-weight:700; font-size:clamp(11px,1.5svh,14.5px); }
.ui-modal__period { display:flex; align-items:center; gap:clamp(5px,.6vw,8px); margin:clamp(14px,2.1svh,22px) 0 0; color:#8296b3; font-size:clamp(11px,1.45svh,14px); }
.ui-modal__period svg { flex:0 0 auto; width:1.3em; height:1.3em; color:#8474f2; }
.ui-modal__summary { margin:clamp(9px,1.4svh,15px) 0 0; padding:clamp(10px,1.5svh,15px) clamp(11px,1.3vw,16px); border-radius:clamp(10px,1.3svh,15px); background:#f7f5fd; color:#3d4c66; font-size:clamp(11.5px,1.55svh,15px); line-height:1.75; }
.ui-modal__subtitle { display:flex; align-items:center; gap:clamp(6px,.7vw,10px); margin:clamp(16px,2.3svh,24px) 0 0; color:#1e2a3c; font-weight:800; font-size:clamp(11.5px,1.55svh,15px); letter-spacing:.02em; }
.ui-modal__subtitle::before { display:block; width:clamp(14px,1.9vw,24px); height:3px; border-radius:3px; background:#8474f2; content:""; }
.ui-modal__list { display:grid; gap:clamp(8px,1.25svh,13px); margin:clamp(9px,1.4svh,15px) 0 0; padding:0; list-style:none; }
.ui-modal__list li { position:relative; padding-left:clamp(14px,1.6vw,20px); color:#42536e; font-size:clamp(11.5px,1.5svh,14.5px); line-height:1.72; }
.ui-modal__list li::before { position:absolute; top:.62em; left:0; width:clamp(5px,.6vw,8px); aspect-ratio:1; border-radius:50%; background:#c3b6f2; content:""; }
.ui-modal__tags { display:flex; flex-wrap:wrap; gap:clamp(5px,.6vw,8px); margin:clamp(16px,2.3svh,24px) 0 0; padding:clamp(12px,1.8svh,18px) 0 0; border-top:1px solid #eceaf5; list-style:none; }
.ui-modal__tags li { padding:clamp(3px,.5svh,6px) clamp(9px,1vw,14px); border-radius:999px; background:#ece7fb; color:#6c5ce7; font-weight:700; font-size:clamp(10px,1.3svh,13px); }

/* 弹窗打开时锁住底部长页滚动，并补回滚动条宽度，避免整页左右跳动 */
html.is-modal-open { overflow:hidden; }

/* 矮屏收紧：1366×768、1280×720，以及笔记本 125% 缩放折算出的 1152×720
   （顶部留白压到 92px 后高度预算刚好够用，卡片尺寸不用再单独缩） */
@media (min-width:701px) and (max-height:820px) {
  .exp { padding-top:92px; padding-bottom:18px; }
  .exp-lead { margin-top:clamp(7px,1.7svh,18px); }
}
/* 极矮屏兜底 */
@media (min-width:701px) and (max-height:660px) {
  .exp { padding-top:88px; padding-bottom:20px; }
  .exp-intro h2 { font-size:clamp(30px,7svh,52px); }
  .exp-en { font-size:clamp(15px,2.8svh,24px); }
}

/* 移动端：扇形与袋口在窄屏没有意义，改为整列堆叠，点击卡片直接开详情 */
@media (max-width:700px) {
  .exp { height:auto; min-height:100svh; padding:96px 20px 52px; }
  .exp-inner { display:block; }
  .exp-aside { position:static; margin:clamp(12px,2svh,18px) 0 0; align-items:flex-start; text-align:left; }
  .exp-aside i { margin:0 0 clamp(5px,.9svh,9px); }
  .exp-stage { display:block; padding-top:clamp(18px,3svh,28px); }
  .exp-folder { width:100%; max-width:none; height:auto; }
  .exp-folder__back, .exp-folder__pocket { display:none; }
  .exp-fan { position:static; display:grid; gap:clamp(12px,2.4vw,18px); }
  .exp-card, .exp-card.is-center, .exp-card.is-left, .exp-card.is-right {
    position:static; --fx:0px; --fy:0px; --rot:0deg; --sc:1; --lift:0px;
    width:100%; height:auto; padding:12px; transform:none; overflow:visible; cursor:pointer;
    perspective:none; /* 窄屏 3D 翻面容易触控误触,直接禁用,详情走模态 */
  }
  .exp-stage:not(.is-visible) .exp-card { --fy:0px; }
  .exp-card__inner { transition:none; }
  .exp-card.is-flipped .exp-card__inner { transform:none; }
  /* 窄屏只显示正面,背面整张藏起来 —— 详情走模态 */
  .exp-card__face--back { display:none; }
  .exp-card__face--front { position:static; }
  /* 旧版 .exp-card__flip-btn / .flip-back 按钮已删,无需 display:none;
     .exp-card__hint 箭头保留(它是视觉提示,不是按钮,窄屏一样能起到"点这里看详情"的引导) */
  .exp-card__media { aspect-ratio:1.6; }
  .exp-card__body { padding-top:12px; }
  .exp-card__name { font-size:15px; }
  .exp-card__role { font-size:11.5px; }
  .exp-motto { margin-top:10px; font-size:12.5px; }
  .exp-tags { margin-top:12px; padding-top:0; }
  .exp-tags li { padding:3px 10px; font-size:11px; }
  .ui-modal { padding:16px; }
  .ui-modal__panel { padding:20px 18px; }
  .ui-modal__close { top:10px; right:10px; }
  .ui-modal__head { padding-right:38px; }
}

/* ==========================================================================
   个人作品（2026-09-11）
   版面依据用户给的参考图：左侧引导文案 + 右上英文短句，下方两行作品。
   每行 = 序号条 + 文案栏（标题/标签/简介/按钮）+ 一整屏「产品界面示意」。
   项目暂时没有真实截图，那屏示意是 DOM+CSS 画的等比缩小界面（.pj-mock），
   换成真图时整块替换即可。背景依旧只留一团透明柔光，底色只属于整站那一层。
   —— 尺寸全部走「容器查询单位」：行高由栅格决定、屏高由行高决定，
      行内字号写成行高的百分比，所以从 1440 到 1280 都是一次性等比缩放，
      不用为每档视口单独调数值。不支持容器查询单位的浏览器退回固定 px。
   ========================================================================== */
.pj {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; justify-content:center;
  height:100svh; min-height:620px;
  padding:96px var(--pj-gutter) 20px;
  --pj-gutter:max(5vw,calc((100vw - 1200px)/2));
  background:radial-gradient(ellipse 38% 32% at 52% 62%,rgba(216,206,244,.24),transparent 72%);
}
.pj-petals { z-index:1; }
.pj-inner { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; min-height:0; width:100%; max-width:1400px; margin:0 auto; }

/* —— 引导文案（与教育页/经历页同一套字号节奏）+ 手写体小注 —— */
.pj-intro, .sk-intro { padding-top:clamp(2px,.8svh,14px); }
.pj-intro h2, .sk-intro h2 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(34px,6svh,80px); line-height:1.02; letter-spacing:-.05em; }
.pj-en, .sk-en { margin:clamp(1px,.5svh,8px) 0 0; color:#6c5ce7; font-weight:800; font-size:clamp(16px,2.7svh,35px); line-height:1.15; letter-spacing:-.015em; }
.pj-lead, .sk-lead { margin:clamp(9px,1.7svh,26px) 0 0; max-width:26em; color:#55668a; font-size:clamp(11px,1.55svh,15.5px); line-height:1.7; }
/* 手写小注：拉丁文用系统里的手写体（Windows 有 Segoe Script / Ink Free），
   中文与缺字体环境会自然落到普通字体，不会变成方块。 */
.pj-scribble, .sk-scribble {
  display:flex; align-items:center; gap:.6em; margin:0 0 clamp(2px,.6svh,7px);
  color:#a58fd8; font-family:"Segoe Script","Ink Free","Bradley Hand",cursive;
  font-size:clamp(10px,1.3svh,13.5px); letter-spacing:.02em; transform:rotate(-1.4deg); transform-origin:left center;
}
.pj-scribble::after, .sk-scribble::after { width:clamp(24px,3vw,46px); height:1.5px; background:linear-gradient(90deg,rgba(165,143,216,.75),rgba(165,143,216,0)); content:""; }
.pj-aside, .sk-aside { position:absolute; top:clamp(5px,1.4svh,20px); right:0; display:flex; flex-direction:column; gap:clamp(2px,.4svh,5px); margin:0; color:#7c86a4; font-size:clamp(10px,1.45svh,13.5px); letter-spacing:.16em; text-align:right; }
.pj-aside i, .sk-aside i { display:block; width:clamp(26px,3.4vw,48px); height:3px; margin:0 0 clamp(5px,.9svh,11px) auto; border-radius:3px; background:linear-gradient(90deg,rgba(151,132,226,0),#a998e8); }

/* —— 作品区：两行等高，行高由剩余高度平分 —— */
.pj-stage { display:grid; flex:1 1 auto; grid-template-rows:repeat(2,minmax(168px,1fr)); gap:clamp(10px,1.5svh,18px); min-height:0; }
.pj-row {
  position:relative; display:flex; align-items:stretch;
  /* --r = 行高的 1%（兜底写成固定值，容器查询可用时改为 1cqh） */
  --r:2.4px;
  --row-pad:calc(var(--r) * 5.2);
  --f-no:calc(var(--r) * 13.5); --f-title:calc(var(--r) * 8.4); --f-en:calc(var(--r) * 3.5);
  --f-tag:calc(var(--r) * 4.2); --f-desc:calc(var(--r) * 5.2); --f-btn:calc(var(--r) * 4.7);
  border:1px solid rgba(255,255,255,.92); border-radius:clamp(14px,2.6svh,26px);
  background:linear-gradient(140deg,rgba(255,255,255,.9),rgba(255,250,253,.72));
  box-shadow:0 16px 40px rgba(126,96,150,.1),inset 0 1px rgba(255,255,255,.9);
  backdrop-filter:blur(14px);
  opacity:0; transform:translateY(18px);
  transition:opacity .6s ease,transform .6s cubic-bezier(.22,.61,.36,1),box-shadow .35s ease;
}
@supports (container-type:size) { .pj-row { container-type:size; --r:1cqh; } }
.pj-row.is-visible { opacity:1; transform:none; }
.pj-row:hover { box-shadow:0 24px 54px rgba(112,84,152,.16),inset 0 1px rgba(255,255,255,.9); }

.pj-row__no {
  display:grid; flex:0 0 auto; place-items:center;
  width:calc(var(--f-title) * 3.1); margin:var(--row-pad) 0 var(--row-pad) var(--row-pad);
  border-radius:calc(var(--f-title) * .55);
  background:linear-gradient(160deg,#f5f1fe,#e8dffc);
  color:#b4a3ea; font-weight:800; font-size:var(--f-no); line-height:1; letter-spacing:-.05em;
}
.pj-row__text { display:flex; flex:1 1 auto; flex-direction:column; justify-content:center; min-width:0; padding:var(--row-pad) calc(var(--row-pad) * 1.1); }
.pj-row__head { display:flex; flex-wrap:wrap; align-items:baseline; gap:.55em; }
.pj-row__title { margin:0; color:#1e2a3c; font-weight:800; font-size:var(--f-title); line-height:1.16; letter-spacing:-.028em; }
.pj-row__en { margin:0; color:#9aa3bb; font-weight:700; font-size:var(--f-en); letter-spacing:.16em; text-transform:uppercase; }
.pj-tags { display:flex; flex-wrap:wrap; gap:calc(var(--row-pad) * .32); margin:calc(var(--row-pad) * .52) 0 0; padding:0; list-style:none; }
.pj-tags li { padding:calc(var(--row-pad) * .14) calc(var(--row-pad) * .62); border-radius:999px; background:#ece7fb; color:#6c5ce7; font-weight:700; font-size:var(--f-tag); line-height:1.5; white-space:nowrap; }
.pj-row__desc { margin:calc(var(--row-pad) * .5) 0 0; color:#55668a; font-size:var(--f-desc); line-height:1.62; }
.pj-actions { display:flex; flex-wrap:wrap; align-items:center; gap:calc(var(--row-pad) * .5); margin-top:calc(var(--row-pad) * .78); }
.pj-btn { display:inline-flex; align-items:center; gap:.45em; padding:calc(var(--row-pad) * .32) calc(var(--row-pad) * .88); border:1px solid #e8e2f6; border-radius:999px; background:rgba(255,255,255,.94); color:#3a3350; box-shadow:0 6px 16px rgba(112,84,152,.08); font-size:var(--f-btn); font-weight:700; letter-spacing:.02em; transition:transform .18s ease,box-shadow .18s ease,background .18s ease; }
.pj-btn:hover { transform:translateY(-2px); }
.pj-btn svg { width:1.12em; height:1.12em; }
.pj-btn--primary { border-color:rgba(255,255,255,.34); background:linear-gradient(145deg,#8b74ee,#6c5ce7); box-shadow:0 10px 22px rgba(108,92,231,.26); color:#fff; }
.pj-btn--primary svg { fill:rgba(255,255,255,.92); }
.pj-more { display:inline-flex; align-items:center; gap:.4em; margin-left:auto; border:0; padding:calc(var(--row-pad) * .3) 0; background:none; color:#3a3350; font-size:var(--f-btn); font-weight:700; transition:color .2s ease,gap .2s ease; }
.pj-more:hover { gap:.7em; color:#6c5ce7; }
.pj-more svg { width:1.16em; height:1.16em; color:#6c5ce7; }

/* —— 右侧那屏「产品界面示意」——
   --m = 屏高的 1%。屏的宽高比恒为 1.98，所以 1cqh = (1/1.98)cqw，
   用 inline-size 容器就能拿到与高度等价的比例尺（不必要求高度是定值）。 */
.pj-mock { position:relative; flex:0 0 auto; align-self:center; height:calc(100% - var(--row-pad) * 2); margin:0 var(--row-pad) 0 0; aspect-ratio:1.98; border-radius:calc(var(--row-pad) * .95); background:linear-gradient(150deg,#efe9fd,#f8f5ff); box-shadow:0 12px 28px rgba(112,84,152,.1),inset 0 1px rgba(255,255,255,.8); --m:2px; }
@supports (container-type:inline-size) { .pj-mock { container-type:inline-size; --m:.505cqw; } }
/* 2026-09-12:有真截图时 .pj-mock 直接放图,不再用 DOM mockup + 角标 chip(已删) */
.pj-mock--cover { background:transparent; box-shadow:0 18px 40px rgba(112,84,152,.18),0 2px 6px rgba(112,84,152,.08); }
.pj-cover { display:block; width:100%; height:100%; object-fit:cover; border-radius:inherit; }

.pj-win { position:absolute; inset:8.5% 5%; display:flex; flex-direction:column; overflow:hidden; border-radius:calc(var(--m) * 3.4); border:1px solid rgba(255,255,255,.9); background:#fff; box-shadow:0 10px 26px rgba(90,64,140,.12); }
.pj-win__bar { display:flex; flex:0 0 auto; align-items:center; gap:calc(var(--m) * 2.6); height:calc(var(--m) * 13); padding:0 calc(var(--m) * 3.6); border-bottom:1px solid #f2eefa; }
.pj-win__logo { flex:0 0 auto; width:calc(var(--m) * 4.4); aspect-ratio:1; border-radius:32%; background:linear-gradient(145deg,#8b74ee,#c9aef8); }
.pj-win__logo--live { background:linear-gradient(145deg,#ff7f6e,#ee4a37); }
.pj-win__name { color:#25243a; font-weight:800; font-size:calc(var(--m) * 4.4); letter-spacing:-.02em; }
.pj-win__state { color:#9a93b0; font-size:calc(var(--m) * 3.6); }
.pj-win__time { margin-left:auto; color:#9a93b0; font-size:calc(var(--m) * 3.6); }
.pj-win__tabs { display:flex; gap:calc(var(--m) * 3.4); margin-left:auto; }
.pj-win__tabs i { color:#9a93b0; font-style:normal; font-size:calc(var(--m) * 3.6); }
.pj-win__tabs i:first-child { color:#6c5ce7; font-weight:700; }

/* 模拟面试：左视频、右评估 */
.pj-call { display:grid; flex:1 1 auto; grid-template-columns:1.44fr 1fr; gap:calc(var(--m) * 3); min-height:0; padding:calc(var(--m) * 3.4); }
.pj-call__stage { position:relative; display:flex; flex-direction:column; overflow:hidden; border-radius:calc(var(--m) * 3); background:linear-gradient(160deg,#dde3f4,#c6d0e9); }
/* 人物占位：纯 CSS 画的「头 + 肩」剪影，换真实画面时替换整块即可 */
.pj-call__face { position:absolute; inset:0; }
.pj-call__face::before { position:absolute; top:16%; left:50%; width:25%; aspect-ratio:1; border-radius:50%; background:rgba(255,255,255,.78); content:""; transform:translateX(-50%); }
.pj-call__face::after { position:absolute; top:49%; left:50%; width:58%; height:46%; border-radius:50% 50% 0 0; background:rgba(255,255,255,.72); content:""; transform:translateX(-50%); }
.pj-call__wave { position:relative; display:flex; align-items:center; justify-content:center; gap:calc(var(--m) * .8); height:calc(var(--m) * 12); margin:auto calc(var(--m) * 3.4) calc(var(--m) * 15); border-radius:999px; background:rgba(255,255,255,.74); }
.pj-call__wave i { width:calc(var(--m) * .95); height:var(--h); max-height:64%; border-radius:999px; background:#8a90bd; }
.pj-call__ctrl { position:absolute; bottom:calc(var(--m) * 3.2); left:50%; display:flex; gap:calc(var(--m) * 2.6); transform:translateX(-50%); }
.pj-call__ctrl i { display:grid; place-items:center; width:calc(var(--m) * 10.5); aspect-ratio:1; border-radius:50%; background:rgba(255,255,255,.92); color:#3d4a66; box-shadow:0 2px 8px rgba(60,46,96,.2); }
.pj-call__ctrl i svg { width:50%; height:50%; }
.pj-call__ctrl .pj-call__ctrl--end { background:linear-gradient(145deg,#f2604f,#dd3524); color:#fff; }
.pj-eval { display:flex; flex-direction:column; padding:calc(var(--m) * 3.2); border:1px solid #efeafb; border-radius:calc(var(--m) * 3); background:#fff; box-shadow:0 3px 10px rgba(112,84,152,.06); }
.pj-eval__head { display:flex; align-items:center; justify-content:space-between; color:#25243a; font-weight:800; font-size:calc(var(--m) * 4.2); }
.pj-eval__head svg { width:calc(var(--m) * 4.8); height:calc(var(--m) * 4.8); color:#b3a8c8; }
.pj-eval__top { display:flex; align-items:center; gap:calc(var(--m) * 3); margin-top:calc(var(--m) * 2.8); }
.pj-ring { position:relative; display:grid; flex:0 0 auto; place-items:center; width:calc(var(--m) * 16); aspect-ratio:1; }
.pj-ring svg { position:absolute; inset:0; width:100%; height:100%; }
.pj-ring b { color:#25243a; font-weight:800; font-size:calc(var(--m) * 5.8); letter-spacing:-.04em; }
.pj-eval__label { padding:calc(var(--m) * .9) calc(var(--m) * 2.4); border-radius:999px; background:#ece7fb; color:#6c5ce7; font-weight:700; font-size:calc(var(--m) * 3.6); white-space:nowrap; }
.pj-bars { display:grid; gap:calc(var(--m) * 2); margin:calc(var(--m) * 2.8) 0 0; padding:0; list-style:none; }
.pj-bars li { display:grid; grid-template-columns:calc(var(--m) * 16) 1fr calc(var(--m) * 6); align-items:center; gap:calc(var(--m) * 2); }
.pj-bars span { color:#7c88a3; font-size:calc(var(--m) * 3.4); white-space:nowrap; }
.pj-bars i { position:relative; height:calc(var(--m) * 1.6); border-radius:999px; background:#efeafc; }
.pj-bars i::after { position:absolute; inset:0 auto 0 0; width:var(--v); border-radius:999px; background:linear-gradient(90deg,#8b74ee,#c3a8f5); content:""; }
.pj-bars b { color:#3a3350; font-weight:700; font-size:calc(var(--m) * 3.4); text-align:right; }

/* Scene Words：检索行 + 影片片段 + 相关片段列表 */
.pj-search { display:flex; flex:0 0 auto; align-items:center; gap:calc(var(--m) * 2); margin:calc(var(--m) * 2.8) calc(var(--m) * 3.4) 0; padding:calc(var(--m) * 2) calc(var(--m) * 2.8); border:1px solid #ece7fa; border-radius:999px; background:#faf8ff; color:#9a93b0; font-size:calc(var(--m) * 3.6); }
.pj-search svg { flex:0 0 auto; width:calc(var(--m) * 4); height:calc(var(--m) * 4); color:#b3a8c8; }
.pj-search__go { flex:0 0 auto; width:calc(var(--m) * 5); aspect-ratio:1; margin-left:auto; border-radius:50%; background:linear-gradient(145deg,#8b74ee,#6c5ce7); }
.pj-scene { display:grid; flex:1 1 auto; grid-template-columns:1.52fr 1fr; gap:calc(var(--m) * 3); min-height:0; padding:calc(var(--m) * 3) calc(var(--m) * 3.4) calc(var(--m) * 3.4); }
.pj-still { position:relative; overflow:hidden; border-radius:calc(var(--m) * 2.6); background:linear-gradient(152deg,#7d8bab,#bfaecf 52%,#e6d2da); }
/* 影片画面占位：一枚半透明的胶片记号，让这块色块读起来是「视频」而不是「空」 */
.pj-still__mark { position:absolute; top:44%; left:50%; width:22%; aspect-ratio:1; color:rgba(255,255,255,.46); transform:translate(-50%,-50%); }
.pj-still__mark svg { width:100%; height:100%; }
.pj-still__sub { position:absolute; right:0; bottom:calc(var(--m) * 2.6); left:0; padding:0 calc(var(--m) * 2.6); color:#fff; text-shadow:0 1px 7px rgba(24,18,44,.5); }
.pj-still__sub b { display:block; font-size:calc(var(--m) * 4.3); }
.pj-still__sub em { display:block; margin-top:.15em; font-style:normal; font-size:calc(var(--m) * 3.3); opacity:.88; }
.pj-clips { display:flex; flex-direction:column; gap:calc(var(--m) * 2.2); min-height:0; }
.pj-clips__title { margin:0; color:#25243a; font-weight:800; font-size:calc(var(--m) * 3.7); }
.pj-clips ul { display:grid; flex:1 1 auto; gap:calc(var(--m) * 1.8); margin:0; padding:0; list-style:none; }
.pj-clips li { display:grid; grid-template-columns:calc(var(--m) * 7.4) 1fr; grid-template-rows:auto auto; align-content:center; column-gap:calc(var(--m) * 2.2); }
.pj-clips__thumb { grid-row:1 / 3; align-self:center; width:calc(var(--m) * 7.4); aspect-ratio:1; border-radius:calc(var(--m) * 1.5); background:linear-gradient(140deg,#cdbff0,#e9e1f8); }
.pj-clips b { color:#3a3350; font-size:calc(var(--m) * 3.4); }
.pj-clips em { color:#9a93b0; font-style:normal; font-size:calc(var(--m) * 3); }

/* 「链接还没填」的提示条（fixed，不占版面） */
.site-toast { position:fixed; z-index:70; bottom:clamp(18px,4svh,38px); left:50%; margin:0; padding:.72rem 1.1rem; border:1px solid rgba(255,255,255,.28); border-radius:14px; background:rgba(38,32,54,.92); box-shadow:0 16px 34px rgba(38,32,54,.28); color:#fff; font-size:.78rem; opacity:0; transform:translate(-50%,10px); transition:opacity .24s ease,transform .24s ease; backdrop-filter:blur(8px); }
.site-toast.is-on { opacity:1; transform:translate(-50%,0); }
.site-toast[hidden] { display:none; }

/* 作品详情弹窗里的两处专属样式 */
.pj-modal__no { display:grid; flex:0 0 auto; place-items:center; width:clamp(40px,5.6svh,58px); aspect-ratio:1; border-radius:24%; background:linear-gradient(160deg,#f5f1fe,#e8dffc); color:#8b74ee; font-weight:800; font-size:clamp(16px,2.3svh,23px); line-height:1; letter-spacing:-.04em; }
.pj-modal__tags { margin-top:clamp(12px,1.9svh,20px); padding-top:0; border-top:0; }
.pj-modal__scene { margin:clamp(14px,2svh,20px) 0 0; padding:clamp(11px,1.6svh,16px) clamp(12px,1.4vw,17px); border-radius:clamp(10px,1.3svh,15px); background:#f7f5fd; color:#3d4c66; font-size:clamp(11.5px,1.55svh,15px); line-height:1.72; }
.pj-modal__scene b { display:block; margin-bottom:.28em; color:#6c5ce7; font-size:.86em; letter-spacing:.06em; }

/* 矮屏收紧：1366×768、1280×720、1152×720 */
@media (min-width:701px) and (max-height:820px) {
  .pj { padding-top:92px; padding-bottom:16px; }
  .pj-lead { margin-top:clamp(7px,1.5svh,16px); }
  .pj-stage { grid-template-rows:repeat(2,minmax(158px,1fr)); gap:clamp(8px,1.2svh,13px); }
}
@media (min-width:701px) and (max-height:660px) {
  .pj { padding-top:86px; padding-bottom:14px; }
  .pj-scribble { display:none; }
}

/* 移动端：整页改为自然高度，每行改成「序号 → 文案 → 界面示意」竖排 */
@media (max-width:700px) {
  .pj { height:auto; min-height:100svh; padding:96px 20px 52px; }
  .pj-inner { display:block; }
  .pj-aside { position:static; margin:clamp(12px,2svh,18px) 0 0; align-items:flex-start; text-align:left; }
  .pj-aside i { margin:0 0 clamp(5px,.9svh,9px); }
  .pj-stage { display:grid; grid-template-rows:none; gap:14px; margin-top:clamp(16px,2.4svh,22px); }
  .pj-row { display:block; padding:14px; container-type:normal; --r:2.7px; }
  .pj-row__no { width:auto; margin:0; padding:calc(var(--r) * 2) calc(var(--r) * 3.2); border-radius:calc(var(--r) * 2.4); }
  .pj-row__text { padding:calc(var(--r) * 3.2) 0 0; }
  .pj-row__title { font-size:19px; }
  .pj-row__en { font-size:9.5px; }
  .pj-tags li { font-size:11px; }
  .pj-row__desc { font-size:12.5px; }
  .pj-btn { font-size:11.5px; }
  .pj-more { font-size:11.5px; margin-left:0; }
  .pj-actions { gap:8px; }
  .pj-mock, .pj-mock--scene { width:100%; height:auto; aspect-ratio:1.86; margin:calc(var(--r) * 4) 0 0; }
}
/* 移动端的比例尺改由宽度推（aspect-ratio 固定，1% 屏高 = 1/1.86 的屏宽）：
   这里用 cqw 需要内联尺寸容器 —— 单独一条规则，避免上面 --m 的百分比写法被误解 */
@media (max-width:700px) {
  .pj-mock { --m:.538cqw; }
}
@supports not (container-type:inline-size) {
  .pj-mock { --m:2.2px; }
}

/* ==========================================================================
   技能与爱好（2026-09-11）
   版面依据用户给的参考图：左侧引导文案，下面一块「左技能列 + 右爱好卡扇」。
   技能只有四组、占版少，所以给它一列；爱好五张卡片用扇形轮播，
   五张卡配色各不相同（粉/蓝/紫/奶油/薄荷）—— 呼应参考图那种丰富感。
   ========================================================================== */
.sk {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; justify-content:center;
  height:100svh; min-height:620px;
  padding:96px var(--sk-gutter) 20px;
  --sk-gutter:max(5vw,calc((100vw - 1200px)/2));
  background:
    radial-gradient(ellipse 34% 30% at 20% 74%,rgba(255,224,240,.3),transparent 72%),
    radial-gradient(ellipse 38% 32% at 84% 28%,rgba(214,204,242,.26),transparent 72%);
}
.sk-petals { z-index:1; }
.sk-inner { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; min-height:0; width:100%; max-width:1400px; margin:0 auto; justify-content:center; padding-top:clamp(20px,3.2svh,52px); }
/* —— 专业技能区(2026-09-12 第三次重设计)——
   只保留 3 张大卡片,去掉下方黑底工具条、左侧紫色边框、Beyond/Tools
   装饰 scribble、工具是手/思维是根 aside。卡片要更"有设计感":
   - 粉紫毛玻璃质感(半透明 + backdrop-filter blur + 粉紫光晕)
   - 三个 logo 统一粉紫渐变 + 白色 icon(不再三色)
   - 卡片加高,顶面右上角有装饰光晕
   - hover 时:整卡上浮 + 阴影加深 + icon 旋转 -6° 并放大
   - 第四次(2026-09-12):删右上角紫色光晕(用户觉得不必要),三张卡的
     logo / 文案 / tags 严格对齐(tags 用 margin-top:auto 贴卡底)。
   - 第五次(2026-09-12):删 margin-top:auto 让卡片居中(用户说"卡片太靠底,应该居中")。 */
.sk-skills { display:flex; flex-direction:column; gap:clamp(14px,2.2svh,24px); margin-top:clamp(20px,2.6svh,36px); }
.sk-cards { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:clamp(18px,1.8vw,28px); align-items:stretch; }
.sk-card { position:relative; display:flex; flex-direction:column; gap:clamp(14px,1.6svh,20px); min-height:clamp(220px,28svh,340px); padding:clamp(24px,2.6svh,32px) clamp(20px,2.2vw,28px) clamp(24px,2.4svh,30px); border:1px solid rgba(255,255,255,.92); border-radius:clamp(20px,2.4svh,28px); background:linear-gradient(155deg,rgba(255,255,255,.62) 0%,rgba(244,232,253,.55) 100%); box-shadow:0 20px 48px rgba(126,96,150,.14),inset 0 1px rgba(255,255,255,.9); backdrop-filter:blur(18px) saturate(1.4); -webkit-backdrop-filter:blur(18px) saturate(1.4); overflow:hidden; transition:transform .35s cubic-bezier(.22,.61,.36,1),box-shadow .35s ease,background .35s ease; }
/* 左下角白色小光晕:装饰用,跟整站卡片"通透感"对齐 */
.sk-card::after { content:""; position:absolute; bottom:-40px; left:-30px; width:100px; height:100px; border-radius:50%; background:radial-gradient(circle,rgba(255,255,255,.5) 0%,rgba(255,255,255,0) 70%); pointer-events:none; transition:transform .5s cubic-bezier(.22,.61,.36,1); }
.sk-card:hover { transform:translateY(-8px); box-shadow:0 32px 64px rgba(126,96,150,.24),inset 0 1px rgba(255,255,255,.9); background:linear-gradient(155deg,rgba(255,255,255,.72) 0%,rgba(244,232,253,.68) 100%); }
.sk-card:hover::after { transform:scale(1.4); }

/* 统一粉紫渐变 logo:三张卡同色,呼应整站紫色调 */
.sk-card__ico { position:relative; z-index:1; display:grid; flex:0 0 auto; align-self:flex-start; place-items:center; width:clamp(56px,6.2svh,72px); aspect-ratio:1; border-radius:50%; color:#fff; background:linear-gradient(150deg,#e0c5fa 0%,#b9a0f0 55%,#9b7adf 100%); box-shadow:0 14px 28px rgba(155,122,223,.4),inset 0 -3px 0 rgba(0,0,0,.08),inset 0 1px 0 rgba(255,255,255,.35); transition:transform .4s cubic-bezier(.22,.61,.36,1); }
.sk-card:hover .sk-card__ico { transform:rotate(-6deg) scale(1.08); }
.sk-card__ico svg { width:54%; height:54%; stroke-width:2; }

.sk-card__title { position:relative; z-index:1; margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(20px,2.4svh,26px); line-height:1.2; letter-spacing:-.025em; }
.sk-card__desc { position:relative; z-index:1; margin:0; color:#4a5a7a; font-size:clamp(12px,1.45svh,15px); line-height:1.75; }
/* tags 始终贴卡底:用 margin-top:auto 把上方空间吃掉,
   数量不同的 tags 块(三卡 3/4/2 个)在三张卡里底部 baseline 对齐 */
.sk-card__tags { position:relative; z-index:1; display:flex; flex-wrap:wrap; gap:clamp(5px,.6vw,8px); margin-top:auto; padding:0; list-style:none; }
.sk-card__tags li { padding:clamp(4px,.5svh,6px) clamp(10px,1vw,14px); border-radius:999px; background:rgba(236,231,251,.92); color:#6c5ce7; font-size:clamp(11px,1.35svh,14px); font-weight:700; line-height:1.5; white-space:nowrap; border:1px solid rgba(108,92,231,.15); transition:transform .2s ease,background .2s ease; }
.sk-card__tags li:hover { transform:translateY(-1px); background:#ece7fb; }

/* ==========================================================================
   兴趣爱好（2026-09-12 独立成 #interests section,顶栏独立 nav 项）
   4 张卡轮播（摄影/旅行/手作/烹饪）+ 底部 dots + 圆形左右箭头按钮。
   4 张卡配色（粉/蓝/紫/奶油）呼应参考图那种丰富感。
   --hb-w 在 .hb 容器上定义：容器高度由内容决定，卡片高度不必参与
   自身尺寸推导，避免「卡高由容器高推、容器高又由卡高推」的循环。
   ========================================================================== */
.hb {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; justify-content:center;
  height:100svh; min-height:620px;
  padding:96px var(--hb-gutter) 20px;
  --hb-gutter:max(5vw,calc((100vw - 1200px)/2));
  background:
    radial-gradient(ellipse 34% 30% at 20% 74%,rgba(255,224,240,.3),transparent 72%),
    radial-gradient(ellipse 38% 32% at 84% 28%,rgba(214,204,242,.26),transparent 72%);
}
@supports (container-type:size) {
  .hb { container-type:size; --hb-w:min(calc((100cqh - 140px) * .715), 31cqw); }
}
.hb-petals { z-index:1; }
.hb-inner { position:relative; z-index:2; display:flex; flex:1 1 auto; flex-direction:column; min-height:0; width:100%; max-width:1400px; margin:0 auto; }
/* 2026-09-12 删了 .hb-scribble ("More/Than Skills" 装饰英文) 和
   .hb-aside ("在热爱的世界里/遇见更好的自己" 右上角短句)——用户觉得不贴风格。 */
.hb-intro { padding-top:clamp(2px,.8svh,14px); }
.hb-intro h2 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(34px,6svh,80px); line-height:1.02; letter-spacing:-.05em; }
.hb-en { margin:clamp(1px,.5svh,8px) 0 0; color:#6c5ce7; font-weight:800; font-size:clamp(16px,2.7svh,35px); line-height:1.15; letter-spacing:-.015em; }
.hb-lead { margin:clamp(9px,1.7svh,26px) 0 0; max-width:26em; color:#55668a; font-size:clamp(11px,1.55svh,15.5px); line-height:1.7; }

/* 4 张卡轮播 + 底部 dots + 箭头 */
.hb-fan-wrap { flex:1 1 auto; position:relative; min-height:0; display:grid; place-items:center; }
/* 2026-09-12:4 张主卡恢复扇形轮播(用户反馈"4 列平铺没设计感,喜欢之前那种
   倾斜+一点点重叠的样式")。--hb-w 在 .hb section 上用 cqh 推算,
   避免循环依赖。点击交互换成"打开画廊",不再切 center。 */
.hb-fan { position:relative; width:100%; height:calc(var(--hb-w) / .78 + var(--hb-w) * .08); }
.hb-card {
  position:absolute; bottom:calc(var(--hb-w) * .04); left:50%;
  display:flex; flex-direction:column;
  width:var(--hb-w); aspect-ratio:0.78;
  padding:clamp(10px,1vw,14px);
  border:1px solid rgba(255,255,255,.94); border-radius:clamp(16px,1.9svh,22px);
  background:linear-gradient(168deg,rgba(255,255,255,.72),rgba(253,251,255,.6));
  box-shadow:0 14px 30px rgba(112,84,152,.14),inset 0 1px rgba(255,255,255,.9);
  backdrop-filter:blur(14px) saturate(1.4);
  -webkit-backdrop-filter:blur(14px) saturate(1.4);
  transform-origin:50% 100%;
  transform:translateX(calc(-50% + var(--fx,0) * var(--hb-w))) rotate(var(--rot,0deg)) scale(var(--sc,1));
  transition:transform .6s cubic-bezier(.22,.61,.36,1),box-shadow .4s ease,opacity .4s ease,background .4s ease;
  opacity:0; cursor:pointer;
}
.hb-fan.is-visible .hb-card { opacity:.92; }
.hb-fan.is-visible .hb-card.is-center { opacity:1; }
.hb-card.is-center { box-shadow:0 28px 58px rgba(112,84,152,.22),inset 0 1px rgba(255,255,255,.9); background:linear-gradient(168deg,rgba(255,255,255,.84),rgba(253,251,255,.72)); }
/* hover 时保留原 transform 只放大,避免重置中心位置 */
.hb-card:hover { transform:translateX(calc(-50% + var(--fx,0) * var(--hb-w))) rotate(var(--rot,0deg)) scale(calc(var(--sc,1) * 1.04)); box-shadow:0 30px 62px rgba(112,84,152,.24),inset 0 1px rgba(255,255,255,.9); }
.hb-card:focus-visible { outline:3px solid rgba(124,104,238,.6); outline-offset:4px; }
.hb-card__media { position:relative; flex:1 1 auto; min-height:0; overflow:hidden; border-radius:clamp(12px,1.4svh,16px); }
.hb-card__photo { display:block; width:100%; height:100%; object-fit:cover; transition:transform .6s cubic-bezier(.22,.61,.36,1); }
.hb-card:hover .hb-card__photo { transform:scale(1.05); }
.hb-card__icon { position:absolute; inset:0; display:grid; place-items:center; color:rgba(255,255,255,.94); }
.hb-card__icon svg { width:34%; height:34%; }
.hb-card__body { flex:0 0 auto; padding:calc(var(--hb-w) * .058) calc(var(--hb-w) * .012) 0; }
.hb-card__name { display:block; color:#1e2a3c; font-weight:800; font-size:calc(var(--hb-w) * .082); line-height:1.2; letter-spacing:-.025em; }
.hb-card__name em { display:block; margin-top:.16em; color:#8b93ad; font-style:normal; font-weight:700; font-size:.58em; letter-spacing:.12em; text-transform:uppercase; }
.hb-card__detail { margin:calc(var(--hb-w) * .028) 0 0; color:#55668a; font-size:calc(var(--hb-w) * .058); line-height:1.55; }
/* 四张卡四种底色:blush / sky / lilac / cream */
.hb-card--blush .hb-card__media { background:linear-gradient(152deg,#ffd9e7,#ffbfd6 58%,#f5a9c9); }
.hb-card--sky .hb-card__media { background:linear-gradient(152deg,#d2e4ff,#a9c9f7 58%,#8bb2ec); }
.hb-card--lilac .hb-card__media { background:linear-gradient(152deg,#e8deff,#cfbcf8 58%,#b8a0f0); }
.hb-card--cream .hb-card__media { background:linear-gradient(152deg,#ffefcd,#f9dda3 58%,#efcb82); }

/* ==========================================================================
   画廊展开(2026-09-12 第四次重做):点 hb-card 触发,
   参考用户给的"3 张电影海报"展开样式——极简黑白风:
   - .hb-mask 浅灰白蒙层(不再是紫黑)
   - .hb-photo 白底 + 黑色细边 + 圆角(像电影海报框)
   - 中间正、两侧倾斜缩放(2:3 宽高比)
   - 底部居中 2 个圆形 prev/next 按钮(白底黑边)
   切组用 Web Animations API 触发入场(2026-09-12 修"只显示一张"bug)。
   退出:✕ 按钮 / 蒙层空白 / Esc 键
   ========================================================================== */
.hb-mask { position:fixed; inset:0; z-index:80; background:rgba(245,246,250,.78); backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); opacity:0; transition:opacity .35s ease; pointer-events:none; }
.hb-mask.is-open { opacity:1; pointer-events:auto; }
/* 全屏居中展开(2026-09-12) */
.hb-gallery { position:fixed; z-index:81; inset:0; display:flex; align-items:center; justify-content:center; padding:clamp(40px,5svh,80px) clamp(28px,4vw,80px); opacity:0; transition:opacity .38s cubic-bezier(.22,.61,.36,1); pointer-events:none; }
/* 2026-09-12 修复:HTML 的 hidden 属性默认 display:none,但上面那条
   .hb-gallery { display:flex } 会把 hidden 覆盖掉,导致画廊其实一直常驻屏幕
   (opacity:0 让它视觉上不可见,但 .hb-gallery__inner 设了 pointer-events:auto,
   在 z-index:81 层级覆盖所有 .hb-card,把所有卡片点击事件全部拦截——所以用户
   点 hb-card 看起来"没反应",其实是事件被画廊透明容器吃掉了)。
   与 .ui-modal[hidden] 的兜底规则保持一致。 */
.hb-gallery[hidden] { display:none; }
/* 2026-09-12:外层 hb-gallery 始终透传点击,只让内层 .hb-gallery__inner 接收交互;
   这样在 inner 之外(但 .hb-mask 之内)的空白处点击会落到 mask → 触发 closeGallery。 */
.hb-gallery.is-open { opacity:1; }
.hb-gallery__inner { position:relative; width:100%; max-width:1320px; display:flex; flex-direction:column; align-items:center; pointer-events:auto; }
/* 删了之前底部紫粉橙光晕(参考图极简风) */
/* ✕ 关闭按钮(2026-09-12 用户反馈):
   高度跟 .hb-gallery__title 标题字号(24-34px)接近,看起来更协调。
   位置在"简历"tag 按钮(顶栏右上,right:80px 左右)的正下方(top:56-60px),
   右侧也跟"简历"按钮对齐,不再贴在画廊右上角。 */
.hb-close { position:absolute; top:60px; right:clamp(28px,4vw,80px); display:grid; place-items:center; width:clamp(28px,3.2svh,34px); height:clamp(28px,3.2svh,34px); border:1.5px solid #1e2a3c; border-radius:50%; background:#fff; color:#1e2a3c; cursor:pointer; transition:transform .25s cubic-bezier(.22,.61,.36,1),background .2s ease; z-index:5; box-shadow:0 6px 18px rgba(20,12,40,.16); }
.hb-close svg { width:48%; height:48%; }
.hb-close:hover { transform:rotate(90deg); background:#f5f5f8; }
.hb-close:focus-visible { outline:3px solid rgba(108,92,231,.55); outline-offset:3px; }
/* 标题:深色文字(不再是白色)。
   2026-09-12 用户反馈"文案有点顶到顶部栏":加 padding-top:12px 让标题
   离画廊顶(也就是顶栏下方)留点呼吸,图片位置不动。 */
.hb-gallery__head { text-align:center; margin-bottom:clamp(20px,2.4svh,32px); color:#1e2a3c; padding-top:12px; }
.hb-gallery__title { margin:0 0 4px; font-weight:800; font-size:clamp(24px,2.9svh,34px); letter-spacing:-.02em; }
.hb-gallery__sub { margin:0; color:#7a87a3; font-size:clamp(12px,1.4svh,15px); letter-spacing:.04em; }

/* 6 张图循环轮播舞台(2026-09-12):6 张 absolute 居中卡,
   距焦点 ±1 可见(中间正两侧倾斜),距焦点 ±2 隐藏(opacity:0)。
   位置由 JS Web Animations API 写入;CSS 只保留静态基础样式。 */
.hb-gallery__stage { position:relative; width:100%; height:clamp(380px,60vh,540px); display:flex; align-items:center; justify-content:center; }
.hb-photo-list { position:relative; width:100%; height:100%; margin:0; padding:0; list-style:none; }
.hb-photo {
  position:absolute; left:50%; top:50%;
  width:clamp(180px,22vw,280px); aspect-ratio:2/3;
  overflow:hidden; border-radius:clamp(14px,1.7svh,20px);
  background:#fff;
  border:1.5px solid #1e2a3c;
  box-shadow:0 18px 40px rgba(20,12,40,.2);
  /* 位置由 Web Animations API (JS) 写入;CSS 只保留静态初始值 */
}
.hb-photo__img { display:block; width:100%; height:100%; object-fit:cover; transition:transform .5s ease; }
.hb-photo--center:hover .hb-photo__img { transform:scale(1.04); }
/* 占位:按 tone 区分(填充时用户实际图会覆盖) */
.hb-photo__placeholder { display:block; width:100%; height:100%; background:linear-gradient(150deg,#f0eef6,#e7e3f3 58%,#d8d2e8); }
.hb-photo[data-tone="blush"] .hb-photo__placeholder { background:linear-gradient(150deg,#ffe7ef,#ffd0dd 58%,#f5b6c8); }
.hb-photo[data-tone="sky"] .hb-photo__placeholder { background:linear-gradient(150deg,#e2edff,#bfd2f7 58%,#9ebae9); }
.hb-photo[data-tone="lilac"] .hb-photo__placeholder { background:linear-gradient(150deg,#ede4ff,#d6c5f8 58%,#bba8f0); }
.hb-photo[data-tone="cream"] .hb-photo__placeholder { background:linear-gradient(150deg,#fff1d6,#f8dfa8 58%,#eccd87); }

/* 切组导航:左/右圆形按钮 + 中间组号指示(白底黑边,参考图风格) */
.hb-gallery__nav { display:flex; align-items:center; justify-content:center; gap:clamp(14px,1.4vw,22px); margin-top:clamp(20px,2.4svh,32px); }
.hb-nav { display:grid; place-items:center; width:46px; height:46px; border:1.5px solid rgba(30,42,60,.8); border-radius:50%; background:#fff; color:#1e2a3c; cursor:pointer; transition:transform .2s ease,background .2s ease,box-shadow .2s ease; box-shadow:0 4px 12px rgba(20,12,40,.12); }
.hb-nav:hover { transform:translateY(-2px); background:#f5f5f8; box-shadow:0 6px 16px rgba(20,12,40,.18); }
.hb-nav:focus-visible { outline:3px solid rgba(108,92,231,.55); outline-offset:3px; }
.hb-nav--next { background:#1e2a3c; border-color:#1e2a3c; color:#fff; }
.hb-nav--next:hover { background:#2a3a55; }
.hb-nav svg { width:42%; height:42%; }
/* 2026-09-12:删了 .hb-nav__dot 组号指示("1 / 2"那种)——用户要 6 张图循环不分组 */

/* 蒙层打开时锁 body 滚动(避免背景跟着滚) */
.hb-locked { overflow:hidden; }

@media (min-width:701px) and (max-height:820px) {
  .sk { padding-top:92px; padding-bottom:16px; }
  .sk-lead { margin-top:clamp(7px,1.5svh,16px); }
  .hb { padding-top:92px; padding-bottom:16px; }
  .hb-lead { margin-top:clamp(7px,1.5svh,16px); }
}
@media (min-width:701px) and (max-height:660px) {
  .sk { padding-top:86px; padding-bottom:14px; }
  .hb { padding-top:86px; padding-bottom:14px; }
}

/* 移动端：技能与爱好都改成自然流；技能卡 1 列堆叠,爱好四张卡改为横向滚动,箭头负责把卡片滚进视野 */
@media (max-width:700px) {
  .sk { height:auto; min-height:100svh; padding:96px 20px 52px; }
  .sk-inner { display:block; }
  .sk-skills { margin-top:clamp(16px,2.4svh,22px); gap:12px; }
  .sk-cards { grid-template-columns:1fr; gap:12px; }
  .sk-card { min-height:0; padding:18px 18px 20px; gap:10px; }

  .hb { height:auto; min-height:100svh; padding:96px 20px 52px; container-type:normal; --hb-w:230px; }
  .hb-inner { display:block; }
  .hb-fan-wrap { display:block; margin-top:clamp(16px,2svh,22px); }
  /* 移动端 4 张主卡改为 2x2 网格,更便于点击 */
  .hb-fan { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; height:auto; }
  .hb-card { position:static; left:auto; bottom:auto; width:100%; transform:none; aspect-ratio:0.82; opacity:1; }
  .hb-card__name { font-size:15px; }
  .hb-card__name em { font-size:9.5px; }
  .hb-card__detail { font-size:11.5px; }

  /* 移动端画廊:只显示中间这张大图(两侧隐藏,避免太挤) */
  .hb-gallery { padding:96px 16px 40px; }
  .hb-gallery__stage { min-height:60vh; }
  .hb-photo-list { min-height:60vh; }
  .hb-photo { width:clamp(220px,55vw,300px); }
  .hb-photo--left, .hb-photo--right { display:none; }
  .hb-gallery__nav { margin-top:24px; gap:14px; }
  .hb-nav { width:40px; height:40px; }
}

/* ==========================================================================
   联系我（2026-09-12）
   版面依据用户给的参考图：左侧标题 + 三张联系方式卡，右侧一张手绘明信片。
   明信片整块是 DOM + 内联 SVG 画的（邮票齿孔、邮戳波浪、落日与天际线
   都不依赖图片），将来要换实拍照片只动 .ct-stamp__art 内部。
   ========================================================================== */
.ct {
  position:relative; isolation:isolate;
  display:flex; flex-direction:column; justify-content:center;
  height:100svh; min-height:620px;
  padding:84px var(--ct-gutter) 76px;
  --ct-gutter:max(5vw,calc((100vw - 1200px)/2));
  background:
    radial-gradient(ellipse 36% 34% at 14% 28%,rgba(255,224,240,.34),transparent 72%),
    radial-gradient(ellipse 40% 34% at 88% 78%,rgba(214,204,242,.3),transparent 72%);
}
.ct-petals { z-index:1; }
/* 2026-09-12 移除装饰曲线 + 笑脸涂鸦(用户要求),相关 .ct-curl / .ct-doodle 样式一并清理 */
.ct-inner { position:relative; z-index:2; display:grid; flex:1 1 auto; grid-template-columns:minmax(0,.84fr) minmax(0,1.16fr); align-items:center; gap:clamp(16px,3vw,54px); min-height:0; width:100%; max-width:1400px; margin:0 auto; }

/* —— 左栏：标题 + 联系方式卡 —— */
.ct-left { display:flex; flex-direction:column; min-width:0; }
.ct-intro { position:relative; }
.ct-intro h2 { margin:0; color:#1e2a3c; font-weight:800; font-size:clamp(34px,6svh,80px); line-height:1.02; letter-spacing:-.05em; }
.ct-en { margin:clamp(1px,.5svh,8px) 0 0; color:#6c5ce7; font-weight:800; font-size:clamp(16px,2.7svh,35px); line-height:1.15; letter-spacing:-.015em; }
.ct-lead { margin:clamp(9px,1.7svh,26px) 0 0; max-width:26em; color:#55668a; font-size:clamp(11px,1.55svh,15.5px); line-height:1.7; }

.ct-list { display:grid; gap:clamp(18px,2.9svh,30px); margin:clamp(14px,2.4svh,34px) 0 0; padding:0; list-style:none; max-width:clamp(232px,21vw,316px); }
.ct-item { min-width:0; }
/* 邮箱/手机是 <a>，小红书没填链接时是 <button>：两者共用同一套观感 */
/* 2026-09-13:卡片本身不再做主操作,改成 div,hover 右侧露出"复制"小按钮 */
/* 2026-09-13:卡片做扁一点,加毛玻璃质感:
   - 垂直 padding 缩小,整体高度收下来;
   - 背景换成半透明白渐变,让后面明信片的颜色透上来;
   - backdrop-filter 加大 blur + saturate,边缘再加一圈高光,玻璃感更明显。 */
.ct-card { position:relative; display:flex; align-items:center; gap:clamp(8px,.9vw,13px); width:100%; padding:clamp(7px,1.12svh,13px) clamp(10px,.95vw,15px); border:1px solid rgba(255,255,255,.72); border-radius:clamp(12px,1.8svh,18px); background:linear-gradient(140deg,rgba(255,255,255,.58),rgba(255,252,255,.42)); box-shadow:0 10px 26px rgba(126,96,150,.10),inset 0 1px rgba(255,255,255,.78),inset 0 -1px rgba(126,96,150,.06); color:inherit; font:inherit; text-align:left; text-decoration:none; backdrop-filter:blur(18px) saturate(160%); -webkit-backdrop-filter:blur(18px) saturate(160%); transition:transform .22s cubic-bezier(.22,.61,.36,1),box-shadow .22s ease,background .22s ease,border-color .22s ease; }
.ct-card:hover { transform:translateY(-3px); background:linear-gradient(140deg,rgba(255,255,255,.72),rgba(255,252,255,.56)); border-color:rgba(255,255,255,.88); box-shadow:0 18px 36px rgba(126,96,150,.16),inset 0 1px rgba(255,255,255,.9),inset 0 -1px rgba(126,96,150,.06); }
/* 复制按钮:默认 opacity 0 + 略偏右 8px,hover 卡片时淡入并归位;
   pointer-events: none 避免未显示时还拦截 hover 事件 */
.ct-card__copy {
  position:absolute; right:clamp(8px,.9vw,14px); top:50%;
  display:inline-flex; align-items:center; gap:.42em;
  padding:clamp(5px,.7svh,9px) clamp(9px,.95vw,13px);
  border:1px solid rgba(255,255,255,.92); border-radius:999px;
  background:linear-gradient(140deg,#fff,#f3edff);
  color:#5b4bb8; font-size:clamp(10px,1.22svh,12px); font-weight:700; letter-spacing:.02em;
  box-shadow:0 8px 18px rgba(112,84,152,.18);
  opacity:0; transform:translate(8px,-50%);
  transition:opacity .22s cubic-bezier(.22,.61,.36,1),transform .22s cubic-bezier(.22,.61,.36,1),color .18s ease;
  pointer-events:none; cursor:pointer;
}
.ct-card__copy svg { width:clamp(12px,1.4svh,14px); height:clamp(12px,1.4svh,14px); }
.ct-card:hover .ct-card__copy,
.ct-card:focus-within .ct-card__copy {
  opacity:1; transform:translate(0,-50%);
  pointer-events:auto;
}
.ct-card__copy:hover { color:#3a2ec4; box-shadow:0 10px 22px rgba(112,84,152,.26); }
.ct-card__copy.is-copied { color:#2fb974; }
.ct-card:focus-visible { outline:2px solid #8b74ee; outline-offset:3px; }
.ct-card__ico { display:grid; flex:0 0 auto; place-items:center; width:clamp(26px,3.4svh,38px); aspect-ratio:1; border-radius:32%; color:#fff; }
.ct-card__ico svg { width:54%; height:54%; }
.ct-card--mail .ct-card__ico { background:linear-gradient(150deg,#a58bf0,#7d63e8); box-shadow:0 8px 18px rgba(125,99,232,.32); }
.ct-card--phone .ct-card__ico { background:linear-gradient(150deg,#63d69a,#2fb974); box-shadow:0 8px 18px rgba(47,185,116,.28); }
.ct-card--xhs .ct-card__ico { background:linear-gradient(150deg,#ff5b76,#f4243f); box-shadow:0 8px 18px rgba(244,36,63,.28); }
.ct-card__body { display:flex; flex-direction:column; gap:.15em; min-width:0; }
.ct-card__label { display:flex; align-items:baseline; gap:.5em; color:#7c86a4; font-style:normal; font-weight:700; font-size:clamp(9px,1.15svh,11.5px); }
.ct-card__label i { color:#c3cadd; font-style:normal; font-weight:700; font-size:.8em; letter-spacing:.18em; }
.ct-card__value { color:#1e2a3c; font-weight:700; font-size:clamp(11.5px,1.5svh,15px); letter-spacing:-.01em; overflow-wrap:anywhere; }

/* —— 右栏：明信片 ——
   宽度取「右栏宽度」与「视口高的 0.775 倍」中的小者，高度由 1.52 反推：
   宽屏下明信片正好填满右栏，窄屏又不会顶破一屏高度。
   卡内一切尺寸写成 cqh 的倍数（--pc = 容器高的 1%），
   于是邮票、邮戳、字号随明信片整体等比缩放，改一个数就整块跟着变。 */
.ct-stage { position:relative; display:grid; place-items:center; min-width:0; padding:clamp(20px,3.4svh,40px) 0; }
/* 2026-09-13 主卡片下方垫一张"和主明信片同尺寸"的渐变装饰卡,
   跟主卡片同 width / aspect-ratio,顺时针旋转 15°、不放大不偏移,
   旋转后外接的尖角自然从主卡片的上方和下方都露出来。
   色彩走粉/紫/蓝的渐变,让"一摞明信片"的层次更明显。 */
.ct-postcard-under {
  position:absolute; left:50%; top:50%;
  width:min(100%,clamp(340px,77.52svh,700px));
  aspect-ratio:1.52;
  border-radius:clamp(13px,1.9svh,26px);
  background:linear-gradient(140deg,#f4ecff 0%,#ffe7ef 45%,#e6eeff 100%);
  box-shadow:0 26px 56px rgba(112,84,152,.16),inset 0 1px rgba(255,255,255,.86);
  transform:translate(-50%,-50%) rotate(6deg);
  z-index:1; pointer-events:none;
}
.ct-postcard {
  position:relative; z-index:3; container-type:size;
  --pc:1cqh;
  width:min(100%,clamp(340px,77.52svh,700px));
  height:auto; aspect-ratio:1.52;
  border-radius:clamp(10px,1.15vw,18px);
  background:linear-gradient(155deg,#ffffff,#fdfbff 58%,#f8f3ff);
  box-shadow:0 32px 66px rgba(112,84,152,.2),0 3px 9px rgba(112,84,152,.09),inset 0 1px rgba(255,255,255,.92);
  /* 2026-09-12 重新加回斜着(用户希望明信片回到"随手放着"的感觉,底下再垫两张不同方向) */
  transform:rotate(-4.4deg);
}
.ct-postcard__kicker { position:absolute; left:9%; top:14%; display:flex; flex-direction:column; gap:.34em; margin:0; color:#9aa3bb; font-weight:700; font-size:calc(var(--pc) * 3); letter-spacing:.2em; line-height:1.32; }
.ct-postcard__kicker em { font-style:normal; }
.ct-postcard__kicker i { font-style:normal; font-size:.92em; letter-spacing:.13em; color:#b8becf; }
/* 手写体：中文优先行楷/楷体，英文签名优先 Segoe Script（Windows 自带） */
.ct-note { position:absolute; left:9.2%; top:38%; margin:0; color:#5b4bb8; font-family:'STXingkai','KaiTi','STKaiti','Segoe Script','Bradley Hand',cursive; font-size:calc(var(--pc) * 7); line-height:1.6; letter-spacing:.03em; }
.ct-note__heart { display:inline-block; width:.82em; height:.82em; margin-left:.5em; color:#c3a7ef; vertical-align:.02em; }
.ct-note__heart svg { display:block; width:100%; height:100%; }
.ct-sign-line { position:absolute; left:17.6%; top:75%; width:9.5%; height:2px; border-radius:2px; background:linear-gradient(90deg,rgba(150,130,220,.5),rgba(150,130,220,.12)); }
.ct-sign { position:absolute; left:30%; top:69.6%; margin:0; color:#7d68e0; font-family:'Segoe Script','Bradley Hand','STXingkai',cursive; font-size:calc(var(--pc) * 5.4); letter-spacing:.03em; white-space:nowrap; }
.ct-postcard__foot { position:absolute; right:8.2%; bottom:6%; margin:0; color:#a2a9bd; font-weight:700; font-size:calc(var(--pc) * 2.8); line-height:1.78; letter-spacing:.15em; text-align:right; }
.ct-stamp { position:absolute; right:8.4%; top:13.6%; width:calc(var(--pc) * 29.2); aspect-ratio:104/128; filter:drop-shadow(0 7px 15px rgba(112,84,152,.17)); }
.ct-stamp__art { display:block; width:100%; height:100%; }
/* 邮戳压在邮票左下角、波浪线朝右下走出卡外 —— 右移到位，别压到手写文案 */
.ct-postmark { position:absolute; right:4.5%; top:55%; width:calc(var(--pc) * 42); color:#8b74ee; }

/* —— 矮屏收紧（1366×768、1280×720、1152×720）—— */
@media (min-width:701px) and (max-height:820px) {
  .ct { padding-top:84px; padding-bottom:58px; }
  .ct-lead { margin-top:clamp(7px,1.5svh,16px); }
  .ct-list { margin-top:clamp(12px,2svh,22px); gap:clamp(7px,1.1svh,11px); }
}
@media (min-width:701px) and (max-height:660px) {
  .ct { padding-top:80px; padding-bottom:40px; }
  .ct-doodle { display:none; }
}

/* —— 中等宽度：左右并排会挤，改成上下两块，整页放回自然高度 —— */
@media (max-width:1000px) {
  .ct { height:auto; min-height:100svh; padding:100px 26px 46px; }
  .ct-inner { grid-template-columns:minmax(0,1fr); gap:clamp(20px,4svh,40px); }
  .ct-list { max-width:min(100%,460px); }
  .ct-postcard { width:min(100%,600px); }
}
@media (max-width:700px) {
  .ct { padding:96px 20px 52px; }
  .ct-postcard { transform:none; border-radius:14px; }
  .ct-list { max-width:none; }
  /* 2026-09-12 窄屏下层叠装饰卡太挤,只保留主卡片 */
  .ct-postcard-deco { display:none; }
  .ct-stage { padding:0; }
}
