/* ============================================================
   ENTROPI 设计系统（design-system.md，2026-07-02 版）
   Electric Violet #C933FD 主 · Cyber Teal #30F8DF 辅
   Poppins 全角色 · 退役色 #00C48C / #7C3AED 一律不用
   ============================================================ */

@font-face{font-family:Poppins;src:url(/fonts/poppins-400.woff2)format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:Poppins;src:url(/fonts/poppins-500.woff2)format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:Poppins;src:url(/fonts/poppins-700.woff2)format('woff2');font-weight:700;font-display:swap}
@font-face{font-family:Poppins;src:url(/fonts/poppins-800.woff2)format('woff2');font-weight:800;font-display:swap}

:root{
  --violet:#C933FD;
  --violet-ink:#8f14bd;
  --violet-soft:#f7e9fe;
  --teal:#30F8DF;
  --teal-ink:#0b6a5d;
  --teal-soft:#e2fdf9;
  --accent:#F9E349;
  --red:#FF3131;
  --red-soft:#ffecec;
  --canvas:#F9F5F2;
  --paper:#ffffff;
  --charcoal:#2E2E2E;
  --charcoal-2:#5c5c5c;
  --muted:#8a8580;
  --line:#D9D9D9;
  --line-2:#ebe7e3;
  --black:#0A0A0A;
  --r:12px;
  --r-sm:9px;
  --shadow:0 1px 2px rgba(10,10,10,.05), 0 8px 24px -12px rgba(10,10,10,.14);
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; background:var(--canvas); color:var(--charcoal);
  font:400 15.5px/1.65 Poppins,-apple-system,"PingFang SC","Hiragino Sans GB","Microsoft YaHei",sans-serif;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:var(--violet-ink)}

/* ---------- 导航 ---------- */
.nav{background:var(--black);color:#F9F5F2}
.nav-in{max-width:1080px;margin:0 auto;padding:15px 20px;display:flex;align-items:center;gap:16px}
/* 后台的三条横条（logo / 导航 / 内容）必须同宽同内边距，否则 logo 那行
   比下面缩进 50px，看着就是错位。达人端仍然是 1080。 */
.nav.admin .nav-in{max-width:1400px;padding-left:28px;padding-right:28px}
.nav img{height:24px;width:auto}
.nav .tagline{
  margin-left:auto;font-size:12px;letter-spacing:.06em;color:#b9b3ad;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}

/* ---------- Hero ---------- */
.hero{background:var(--black);color:#F9F5F2;position:relative;overflow:hidden}
.hero::after{
  content:"";position:absolute;inset:auto -14% -62% 34%;height:340px;
  background:radial-gradient(circle at 50% 50%,rgba(201,51,253,.34),transparent 66%);
  pointer-events:none;
}
.hero-in{max-width:1080px;margin:0 auto;padding:44px 20px 52px;position:relative;z-index:1}
.kicker{
  display:inline-flex;align-items:center;gap:7px;
  font-size:11.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--teal);border:1px solid rgba(48,248,223,.34);
  background:rgba(48,248,223,.07);border-radius:999px;padding:5px 13px;
}
.hero h1{
  margin:17px 0 0;font-weight:800;letter-spacing:-.025em;
  font-size:clamp(29px,6.2vw,45px);line-height:1.12;text-wrap:balance;max-width:19ch;
}
.hero h1 em{font-style:normal;color:var(--violet)}
.hero p.sub{margin:15px 0 0;color:#c9c3bd;max-width:44ch;font-size:16px}
.perks{list-style:none;margin:26px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:9px}
.perks li{
  font-size:13.5px;font-weight:500;padding:7px 14px;border-radius:999px;
  background:rgba(249,245,242,.07);border:1px solid rgba(249,245,242,.14);
}
.perks li b{font-weight:700;color:var(--accent)}

/* ---------- 步骤条 ---------- */
.steps{background:var(--paper);border-bottom:1px solid var(--line-2)}
.steps-in{
  max-width:1080px;margin:0 auto;padding:0 20px;
  display:flex;gap:0;overflow-x:auto;scrollbar-width:none;
}
.steps-in::-webkit-scrollbar{display:none}
.step{
  display:flex;align-items:center;gap:9px;padding:15px 20px 15px 0;
  font-size:13.5px;color:var(--muted);white-space:nowrap;
}
.step .num{
  flex:0 0 auto;width:23px;height:23px;border-radius:50%;
  display:grid;place-items:center;font-size:12px;font-weight:700;
  background:var(--canvas);color:var(--muted);border:1px solid var(--line);
}
.step[aria-current="step"]{color:var(--charcoal);font-weight:600}
.step[aria-current="step"] .num{background:var(--violet);color:#fff;border-color:var(--violet)}
.step.done .num{background:var(--teal-soft);color:var(--teal-ink);border-color:var(--teal)}
.step.done{color:var(--charcoal-2)}

/* ---------- 主体 ---------- */
main{max-width:1080px;margin:0 auto;padding:26px 20px 90px;display:flex;flex-direction:column;gap:20px}
.card{background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);box-shadow:var(--shadow)}
.card > header{padding:19px 22px 0;display:flex;flex-direction:column;gap:4px}
.card > header h2{margin:0;font-size:19px;font-weight:700;letter-spacing:-.01em}
.card > header p{margin:0;color:var(--charcoal-2);font-size:14px}
.card > .body{padding:18px 22px 22px;display:flex;flex-direction:column;gap:17px}
.card.locked{opacity:.5;pointer-events:none;filter:saturate(.4)}
/* <form> is a semantic wrapper here, not a layout box, but as a flex item it
   swallows the parent's gap: everything inside it collapses to zero spacing.
   That put the apply page's cards flush against each other and pushed every
   admin field into the submit button below it. gap:inherit picks up whichever
   parent it lands in (main is 20px, .card > .body is 17px). Forms that carry
   their own class (.filters, .inline) bring their own layout and stay out. */
main > form:not([class]),
.card > .body > form:not([class]){display:flex;flex-direction:column;gap:inherit}

/* ---------- 搜索 ---------- */
.search{position:relative}
.search-field{display:flex;align-items:center;gap:10px;
  border:2px solid var(--line);border-radius:var(--r-sm);background:var(--paper);
  padding:0 14px;transition:border-color .14s}
.search-field:focus-within{border-color:var(--violet);box-shadow:0 0 0 4px var(--violet-soft)}
.search-field svg{flex:0 0 auto;color:var(--muted)}
.search-field input{
  flex:1;min-width:0;border:0;outline:0;background:none;
  padding:14px 0;font:500 16px/1.4 Poppins,-apple-system,"PingFang SC",sans-serif;color:var(--charcoal);
}
.search-field input::placeholder{color:var(--muted);font-weight:400}
/* One ring only: .search-field:focus-within already draws it around the whole
   field. Without this reset the global `input:focus-visible` rule below adds a
   second 3px violet-soft shadow on the input itself, which paints over the
   parent's 2px border along the top and bottom of the text area. The border
   survives only beside the icon and inside the right padding, so the ring
   reads as two disconnected stubs. */
.search-field input:focus-visible{box-shadow:none}
.search-hint{margin:8px 0 0;font-size:13px;color:var(--muted)}

.results{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-direction:column;gap:8px}
.results:empty{display:none}
.hit{
  display:flex;flex-direction:column;gap:3px;width:100%;text-align:left;
  padding:13px 15px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--paper);cursor:pointer;font:inherit;color:inherit;
  transition:border-color .12s,background .12s;
}
.hit:hover:not(:disabled){border-color:var(--violet);background:var(--violet-soft)}
.hit:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.hit:disabled{cursor:not-allowed;background:var(--canvas);color:var(--muted)}
.hit-top{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
.hit-brand{font-weight:700;font-size:15px}
.hit-label{font-size:14.5px;color:var(--charcoal-2)}
.hit-where{font-size:13px;color:var(--muted)}
.hit-slots{
  margin-left:auto;font-size:11.5px;font-weight:700;letter-spacing:.03em;
  padding:2px 9px;border-radius:999px;white-space:nowrap;
  background:var(--teal-soft);color:var(--teal-ink);
}
.hit-slots.full{background:var(--line-2);color:var(--muted)}
/* 未开放和已满都是灰的，但用虚线边框区分：
   「已满」是来晚了，「本期暂未开放」是这一期没排这家店，达人的下一步不一样 */
.hit-slots.closed{background:transparent;color:var(--muted);
  border:1px dashed var(--line);padding:1px 8px}
.state-msg{margin:12px 0 0;font-size:14px;color:var(--muted);text-align:center;padding:16px 0}

/* ---------- 已选门店 ---------- */
.picked{border:2px solid var(--violet);border-radius:var(--r-sm);background:var(--violet-soft);padding:15px 17px;
  display:flex;flex-direction:column;gap:9px}
.picked-head{display:flex;align-items:flex-start;gap:12px}
.picked-name{font-weight:700;font-size:16px;line-height:1.4}
.picked-addr{font-size:13.5px;color:var(--charcoal-2);margin-top:2px}
.picked button{
  margin-left:auto;flex:0 0 auto;background:none;border:0;padding:2px 0;
  font:600 13px Poppins,sans-serif;color:var(--violet-ink);cursor:pointer;text-decoration:underline;
}
.rules{background:var(--paper);border:1px solid var(--violet);border-radius:var(--r-sm);padding:13px 15px;
  display:flex;flex-direction:column;gap:7px}
.rules h3{margin:0;font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--violet-ink)}
.rules ul{margin:0;padding-left:19px;display:flex;flex-direction:column;gap:4px;font-size:14px}

/* ---------- 表单 ---------- */
.grid{display:grid;grid-template-columns:1fr 1fr;gap:15px}
@media (max-width:620px){.grid{grid-template-columns:1fr}}
.field{display:flex;flex-direction:column;gap:6px;min-width:0}
.field.wide{grid-column:1/-1}
.field > label{font-size:13.5px;font-weight:600}
.field .hint{font-size:12.5px;color:var(--muted);line-height:1.5}
.req::after{content:" *";color:var(--violet)}
input[type=text],input[type=tel],input[type=url],input[type=password],input[type=date],
input[type=time],input[type=file],select{
  width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--paper);color:var(--charcoal);
  font:400 15.5px/1.4 Poppins,-apple-system,"PingFang SC",sans-serif;
}
input:focus-visible,select:focus-visible{outline:0;border-color:var(--violet);box-shadow:0 0 0 3px var(--violet-soft)}
input[type=file]{padding:9px 11px;font-size:14px}

fieldset{border:0;margin:0;padding:0;display:flex;flex-direction:column;gap:7px;min-width:0}
fieldset legend{padding:0;font-size:13.5px;font-weight:600}
.choices{display:flex;flex-wrap:wrap;gap:8px}
.choices label{
  border:1px solid var(--line);border-radius:999px;padding:8px 15px;
  font-size:14px;cursor:pointer;background:var(--paper);transition:.12s;
}
.choices input{position:absolute;opacity:0;width:0;height:0}
.choices label:has(input:checked){border-color:var(--violet);background:var(--violet);color:#fff;font-weight:600}
.choices label:has(input:focus-visible){outline:2px solid var(--violet);outline-offset:2px}

.check{display:flex;gap:10px;align-items:flex-start;font-size:14px;line-height:1.55;cursor:pointer}
.check input{flex:0 0 auto;margin-top:4px;width:17px;height:17px;accent-color:var(--violet)}
.divider{height:1px;background:var(--line-2);border:0;margin:3px 0}
.group-title{font-size:12px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin:0}

/* ---------- 提交 ---------- */
.submit{
  width:100%;padding:16px;border:0;border-radius:var(--r-sm);cursor:pointer;
  background:var(--violet);color:#fff;font:700 16.5px Poppins,sans-serif;letter-spacing:.01em;
  transition:background .14s,transform .06s;
}
.submit:hover{background:var(--violet-ink)}
.submit:active{transform:translateY(1px)}
.submit:disabled{background:var(--line);color:var(--muted);cursor:not-allowed}
.submit-note{font-size:12.5px;color:var(--muted);text-align:center;margin:0}

/* ---------- 提示条 ---------- */
.notice{border-radius:var(--r-sm);padding:14px 16px;font-size:14px;line-height:1.6;
  border:1px solid var(--line);background:var(--paper)}
.notice.bad{border-color:var(--red);background:var(--red-soft);color:#a01c1c}
.notice.good{border-color:var(--teal);background:var(--teal-soft);color:var(--teal-ink)}

/* ---------- 页脚 ---------- */
footer.site{background:var(--black);color:#9c9691;margin-top:auto}
.foot-in{max-width:1080px;margin:0 auto;padding:30px 20px 38px;
  display:flex;flex-wrap:wrap;gap:18px;align-items:flex-start}
.foot-in img{height:20px;width:auto;opacity:.85}
.foot-in p{margin:0;font-size:12.5px;line-height:1.7;max-width:52ch}
.foot-in .official{color:#c9c3bd}

/* ---------- 完成页 ---------- */
.done{max-width:560px;margin:0 auto;text-align:center;display:flex;flex-direction:column;gap:15px;
  padding:34px 0}
.done .tick{width:56px;height:56px;margin:0 auto;border-radius:50%;background:var(--teal-soft);
  color:var(--teal-ink);display:grid;place-items:center;font-size:27px;border:2px solid var(--teal)}
.done h1{margin:0;font-size:27px;font-weight:800;letter-spacing:-.02em}
.done p{margin:0;color:var(--charcoal-2)}
.done .recap{background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);
  padding:17px 19px;text-align:left;box-shadow:var(--shadow);display:flex;flex-direction:column;gap:7px}
.done .recap dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:6px 14px;font-size:14px}
.done .recap dt{color:var(--muted)}
.done .recap dd{margin:0;font-weight:500}

.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* ============================================================
   我的报名页 /my/:token
   ============================================================ */
.banner{display:flex;gap:14px;align-items:flex-start;background:var(--teal-soft);
  border:1px solid var(--teal);border-radius:var(--r);padding:16px 18px}
.banner-tick{flex:0 0 auto;width:32px;height:32px;border-radius:50%;background:var(--paper);
  color:var(--teal-ink);display:grid;place-items:center;font-size:17px;font-weight:700;
  border:2px solid var(--teal)}
.banner strong{display:block;font-size:16px;color:var(--teal-ink)}
.banner p{margin:2px 0 0;font-size:14px;color:var(--charcoal-2)}

.card.keep{border-color:var(--violet)}
.keep-why{margin:0;font-size:14px;color:var(--charcoal-2)}
.keep-why strong{color:var(--violet-ink)}
.linkbox{display:flex;gap:8px}
.linkbox input{flex:1;min-width:0;font-size:13px;padding:10px 12px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--canvas);
  color:var(--charcoal-2);font-family:ui-monospace,"SF Mono",Menlo,monospace}
.linkbox button{flex:0 0 auto;padding:10px 18px;border:0;border-radius:var(--r-sm);
  background:var(--violet);color:#fff;font:700 14px Poppins,sans-serif;cursor:pointer}
.linkbox button:hover{background:var(--violet-ink)}

.status-line{display:flex;gap:12px;align-items:flex-start;flex-wrap:wrap}
.status-note{flex:1;min-width:200px;font-size:14px;color:var(--charcoal-2)}
.pill{flex:0 0 auto;padding:4px 13px;border-radius:999px;font-size:13px;font-weight:700}
.pill.pending{background:#fff6e5;color:#8a5b00}
.pill.approved{background:var(--teal-soft);color:var(--teal-ink)}
.pill.rejected{background:var(--red-soft);color:#a01c1c}

/* ---------- 「你提交的资料」名片 + 标签（2026-09-13 改版） ----------
   原来这块直接套了 /admin 的 dl.recap-list，16 行平铺、空值显示「—」，
   在手机上占满一屏，把达人真正要做的事（券/小票/素材）挤到下面去了。 */
.idcard{display:flex;gap:12px;align-items:center;padding:14px;border-radius:12px;
  background:linear-gradient(135deg,var(--violet-soft),var(--paper));
  border:1px solid var(--line-2);margin:0 0 4px}
.idcard .av{width:44px;height:44px;border-radius:50%;background:var(--violet);color:#fff;
  display:grid;place-items:center;font:700 17px Poppins,sans-serif;flex:0 0 auto}
.idcard .nm{font:700 16px Poppins,sans-serif;margin:0;line-height:1.3}
.idcard .sub{margin:2px 0 0;font-size:13px;color:var(--muted)}
.kv{display:flex;justify-content:space-between;gap:12px;padding:9px 0;font-size:14px;
  border-bottom:1px solid var(--line-2)}
.kv .k{color:var(--muted);font-size:13px;flex:0 0 auto}
.kv .v{font-weight:500;text-align:right;word-break:break-all;min-width:0}
/* 主页链接强制一行：路径太长就省略号，不再把这一格撑成两行 */
.v-link{color:var(--violet-ink);text-decoration:underline;text-underline-offset:3px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;
  word-break:normal}
.recap-grp{margin:16px 0 8px}
.chips{display:flex;flex-wrap:wrap;gap:6px}
.chip{font-size:12.5px;padding:4px 10px;border-radius:999px;background:var(--canvas);
  color:#4A4A4A}
.chip.ok{background:#E4F6E9;color:#14622C}
/* 收款不全是这一块里唯一要达人动手的事（去联系工作人员），所以给红底。
   混在一排灰标签里等于没写。 */
.chip.bad{background:#FFE7E7;color:#8A1C1C}

dl.recap-list{margin:0;display:flex;flex-direction:column;gap:0}
dl.recap-list .row{display:grid;grid-template-columns:112px 1fr;gap:14px;
  padding:9px 0;border-bottom:1px solid var(--line-2);font-size:14.5px}
dl.recap-list .row:last-child{border-bottom:0}
dl.recap-list dt{color:var(--muted);font-size:13.5px}
dl.recap-list dd{margin:0;font-weight:500;word-break:break-word;min-width:0}
@media (max-width:560px){
  dl.recap-list .row{grid-template-columns:1fr;gap:2px;padding:8px 0}
}
.rules.standalone{margin-top:14px;background:var(--violet-soft);border-color:var(--violet)}
.deliverable{margin:0;font-size:14.5px;line-height:1.65}

/* ---------- 上传区 ---------- */
.dropzone{border:2px dashed var(--line);border-radius:var(--r);padding:30px 18px;
  text-align:center;cursor:pointer;background:var(--canvas);transition:.15s;
  display:flex;flex-direction:column;gap:5px;align-items:center}
.dropzone:hover,.dropzone.over{border-color:var(--violet);background:var(--violet-soft)}
.dropzone:focus-visible{outline:2px solid var(--violet);outline-offset:2px}
.dz-icon{width:40px;height:40px;border-radius:50%;background:var(--violet);color:#fff;
  display:grid;place-items:center;font-size:19px;margin-bottom:5px}
.dz-main{margin:0;font-weight:600;font-size:15.5px}
.dz-sub{margin:0;font-size:13px;color:var(--muted)}

ul.uploading{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
ul.uploading:empty{display:none}
.up-row{border:1px solid var(--line-2);border-radius:var(--r-sm);padding:11px 13px;
  display:flex;flex-direction:column;gap:7px;background:var(--paper)}
.up-row.failed{border-color:var(--red);background:var(--red-soft)}
.up-top{display:flex;align-items:center;gap:10px}
.up-name{flex:1;min-width:0;font-size:14px;font-weight:500;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.up-pct{flex:0 0 auto;font-size:13px;font-weight:700;color:var(--violet-ink);
  font-variant-numeric:tabular-nums}
.up-cancel{flex:0 0 auto;background:none;border:0;padding:0;cursor:pointer;
  font:500 13px Poppins,sans-serif;color:var(--muted);text-decoration:underline}
.up-bar{height:6px;border-radius:999px;background:var(--line-2);overflow:hidden}
.up-fill{height:100%;width:0;background:var(--violet);border-radius:999px;transition:width .2s}
.up-msg{margin:0;font-size:13px;color:#a01c1c}

.up-summary{font-size:13.5px;color:var(--charcoal-2)}
.up-summary strong{color:var(--charcoal);font-variant-numeric:tabular-nums}

ul.filelist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
ul.filelist:empty{display:none}
ul.filelist li{display:flex;align-items:center;gap:11px;padding:10px 13px;
  border:1px solid var(--line-2);border-radius:var(--r-sm);background:var(--paper)}
.f-icon{flex:0 0 auto;font-size:16px}
.f-name{flex:1;min-width:0;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.f-size{flex:0 0 auto;font-size:12.5px;color:var(--muted);font-variant-numeric:tabular-nums}
.f-del{flex:0 0 auto;background:none;border:0;padding:0;cursor:pointer;
  font:500 13px Poppins,sans-serif;color:var(--red);text-decoration:underline}
.f-del:disabled{opacity:.5;cursor:wait}
.empty-files{margin:0;font-size:13.5px;color:var(--muted);text-align:center;padding:8px 0}

/* ============================================================
   后台 /admin
   ============================================================ */
.adminbar{background:#1b1b1b;border-bottom:1px solid #2c2c2c}
.adminbar-in{max-width:1400px;margin:0 auto;padding:0 28px;display:flex;gap:4px;align-items:center;
  overflow-x:auto;scrollbar-width:none}
.adminbar-in::-webkit-scrollbar{display:none}
.adminbar-in a{padding:13px 15px;color:#b9b3ad;text-decoration:none;font-size:14.5px;
  font-weight:500;white-space:nowrap;border-bottom:2px solid transparent}
.adminbar-in a:hover{color:#F9F5F2}
.adminbar-in a.on{color:#fff;border-bottom-color:var(--violet)}
.adminbar .logout{margin-left:auto}
.adminbar .logout button{color:#8f8a85;font-size:13.5px;padding:13px 0}

main.admin{max-width:1180px;margin:0 auto;padding:24px 20px 80px;
  display:flex;flex-direction:column;gap:18px}
main.admin.narrow{max-width:460px}
.card.narrow{max-width:560px}
.crumb{margin:0;font-size:14px}
.page-h{margin:0;font-size:22px;font-weight:700;letter-spacing:-.015em}

.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px}
.stat{background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);
  padding:13px 16px;display:flex;flex-direction:column;gap:2px}
.stat .n{font-size:25px;font-weight:700;letter-spacing:-.02em;font-variant-numeric:tabular-nums;
  line-height:1.15}
.stat .k{font-size:12.5px;color:var(--muted)}

.filters{display:flex;flex-wrap:wrap;gap:11px;align-items:flex-end;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);padding:14px 16px}
.filters .filter{display:flex;flex-direction:column;gap:4px;font-size:12.5px;color:var(--muted)}
.filters .filter.grow{flex:1 1 200px;min-width:0}
.filters select,.filters input[type=search],.filters input[type=number]{
  padding:9px 11px;font-size:14.5px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--paper);color:var(--charcoal);font-family:inherit;min-width:120px}
.filters button[type=submit]{padding:10px 18px;border:0;border-radius:var(--r-sm);
  background:var(--violet);color:#fff;font:700 14.5px Poppins,sans-serif;cursor:pointer}
.filters button[type=submit]:hover{background:var(--violet-ink)}
.btn{padding:10px 18px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--paper);color:var(--charcoal);font:500 14.5px Poppins,sans-serif;
  text-decoration:none;cursor:pointer;display:inline-block}
.btn:hover{border-color:var(--violet);color:var(--violet-ink)}

.table-scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r)}
table{border-collapse:collapse;width:100%;font-size:14px}
th,td{padding:10px 12px;text-align:left;border-bottom:1px solid var(--line-2);white-space:nowrap}
th{background:var(--surface-2,#f4f5f8);font-weight:600;font-size:13px;color:var(--charcoal-2)}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--canvas)}
td.nowrap a,td.nowrap button{margin-right:10px}
td.wrap-cell{white-space:normal;max-width:260px;font-size:13px}
tr.needs-review{background:#fff6e5}
tr.needs-review:hover{background:#fdf0d8}
form.inline{display:inline}
button.link{background:none;border:0;padding:0;color:var(--violet-ink);font:500 14px Poppins,sans-serif;
  cursor:pointer;text-decoration:underline}
.chip.ok{background:var(--teal-soft);color:var(--teal-ink);border-color:var(--teal)}

.pager{display:flex;gap:16px}
.pager a{font-size:14.5px}
.actions{display:flex;gap:10px;flex-wrap:wrap}
.actions button{padding:12px 22px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:var(--paper);font:600 14.5px Poppins,sans-serif;cursor:pointer}
.actions button[value=approve]{background:#1f6b47;color:#fff;border-color:#1f6b47}
.actions button[value=reject]{background:var(--red);color:#fff;border-color:var(--red)}
.actions button:hover{filter:brightness(1.08)}

.quota-tools{display:flex;gap:11px;align-items:flex-end;flex-wrap:wrap;
  background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r);padding:14px 16px}
.quota-input{width:84px;padding:7px 9px;font-size:14px;border:1px solid var(--line);
  border-radius:6px;font-variant-numeric:tabular-nums}
/* 批量填店规那一列：店规是一整句话，输入框得占满这一格，
   窄成 quota-input 那样运营看不见自己在写什么。 */
/* ---------- 新券卡：图里只有二维码，标题和码号是真文字 ---------- */
/* 静区：图里已经留了 1.3×，这里再给一圈白，屏幕上更好扫也更好看 */
/* 基础 .voucher-square 锁了 1:1（老卡片里装的是一张方图）。新卡片里是
   标题+码+码号三层，强制正方形会把码挤小——按内容撑开。 */
.voucher-square.qr-only{aspect-ratio:auto;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:12px;padding:20px 14px;background:#fff}
.voucher-square.qr-only .voucher-img{width:min(86%,300px);height:auto;
  max-width:none;max-height:none;object-fit:contain;
  /* 二维码放大时别做插值糊边——方块边缘清晰反而更好扫 */
  image-rendering:pixelated}
.qr-title{margin:0;font:700 17px Poppins,sans-serif;color:var(--charcoal);
  letter-spacing:.01em;text-align:center}
.qr-code-line{margin:0;display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  justify-content:center}
.qr-code-label{font-size:13.5px;color:var(--muted)}
.copy-code.qr-code{font-size:19px;letter-spacing:.08em;gap:9px}
.copy-code.qr-code svg{width:19px;height:19px}

.rule-input{width:100%;min-width:260px;padding:7px 9px;font-size:14px;
  border:1px solid var(--line);border-radius:6px}
/* 批量框要长——店规是一整句，缩成一小格运营看不见自己写了什么 */
.rules-tools .filter.grow{flex:1 1 340px}
.rules-tools .filter.grow input{width:100%;padding:7px 9px;font-size:14px;
  border:1px solid var(--line);border-radius:6px}
.rules-tools .check{align-items:center;flex:0 0 auto;padding-bottom:2px}
code{font-family:ui-monospace,"SF Mono",Menlo,monospace;font-size:12.5px;
  background:var(--canvas);border:1px solid var(--line-2);border-radius:4px;padding:2px 6px}

/* 被拒后的重新报名入口。做成主按钮而不是普通链接——
   达人要一眼看到「还能再报」，否则他会去找工作人员。 */
.retry-cta{margin:14px 0 0}
.btn.primary{display:inline-block;padding:12px 22px;border:0;border-radius:var(--r-sm);
  background:var(--violet);color:#fff;font:700 15px Poppins,sans-serif;text-decoration:none}
.btn.primary:hover{background:var(--violet-ink)}

/* 找回上传入口 */
.find-hint{text-align:center;color:var(--muted);font-size:14px;margin:26px 0 0}
main.narrow{max-width:460px;margin:0 auto;padding:28px 22px 80px}
.find .field{margin:0 0 18px}
.find .hint{color:var(--muted);font-size:12.5px;margin:6px 0 0}
.fallback{color:var(--muted);font-size:13.5px;margin:26px 0 0;padding-top:18px;border-top:1px solid var(--line)}

/* 不通过的理由 —— 达人可见，跟内部备注严格区分 */
.reject-why{margin:10px 0 0;padding:11px 14px;background:rgba(255,49,49,.08);
  border-left:3px solid var(--red);border-radius:0 8px 8px 0;font-size:14.5px;line-height:1.65}
.visible-tag{font-size:11px;font-weight:700;letter-spacing:.04em;background:var(--violet);
  color:#fff;padding:2px 8px;border-radius:999px;margin-left:6px;vertical-align:middle}
.reject-reason select{width:100%;margin-bottom:8px}
.reject-reason textarea{width:100%;font-family:inherit;font-size:14.5px}

/* ---- 核销券（达人端） ---- */
.voucher-square{position:relative;aspect-ratio:1/1;border:1px solid var(--gray,#D9D9D9);
  border-radius:14px;overflow:hidden;background:#fff}
.voucher-img{width:100%;height:100%;object-fit:contain;display:block}
.voucher-mask{position:absolute;inset:0;width:100%;border:0;background:#fff;cursor:pointer;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;font:inherit}
.mask-blur{font-size:44px;letter-spacing:.1em;color:#D9D9D9;filter:blur(6px);user-select:none}
.mask-btn{background:#C933FD;color:#fff;font-weight:700;font-size:15px;padding:11px 26px;
  border-radius:999px;box-shadow:0 6px 20px rgba(201,51,253,.30)}
.mask-why{font-size:12.5px;color:#9A9A9A}
.voucher-where{margin:6px 0 0;font-size:13.5px;color:#6B6B6B}
.voucher-code{margin:6px 0 0;font-size:14px;color:#6B6B6B;
  display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* 券图里 TikTok 那个「Code xxx ⧉」是画上去的、点不动。这一行是真能点的，
   所以要长得像能点：下划线 + 手型，旁边明说「点一下复制」。 */
/* 券码 = 数字 + 复制图标，整块是一个按钮（点哪儿都行，手机上好按）。
   下划线只画在数字上：整块带下划线会把图标也划一道。 */
.copy-code{display:inline-flex;align-items:center;gap:7px;
  font:600 15px Poppins,sans-serif;font-variant-numeric:tabular-nums;
  letter-spacing:.06em;color:var(--charcoal);background:none;border:0;
  padding:2px 0;cursor:pointer}
.copy-code .code-num{text-decoration:underline;text-underline-offset:3px}
.copy-code svg{flex:0 0 auto}
.copy-code .ico-done{display:none}
.copy-code.copied{color:var(--violet-ink)}
.copy-code.copied .ico-copy{display:none}
.copy-code.copied .ico-done{display:inline}
.voucher-tip{margin:10px 0 0;font-size:12.5px;color:#9A9A9A}

/* ---- 小票 ---- */
.receipt-why{margin:0 0 12px;font-size:14.5px;line-height:1.7}
.receipt-done{display:flex;align-items:center;gap:10px;margin:0}
.ok-chip{background:#30F8DF;color:#0A0A0A;font-weight:700;font-size:13px;
  padding:4px 13px;border-radius:999px}
button.wide{width:100%;margin-top:12px}

/* ---- 待买券工作台（后台） ---- */
main.wide{max-width:1180px}
.voucher-queue td{vertical-align:top}
.urg{width:22px}
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;background:#D9D9D9}
.dot.today,.dot.past{background:#FF3131}
.dot.soon{background:#F9E349}
tr.past{background:rgba(255,49,49,.05)}
.copy-wechat{font:inherit;font-size:13.5px;background:none;border:1px dashed #D9D9D9;
  border-radius:7px;padding:4px 10px;cursor:pointer;font-variant-numeric:tabular-nums}
.copy-wechat:hover{border-color:#C933FD;color:#C933FD}
.copy-wechat.copied{border-color:#30F8DF;background:rgba(48,248,223,.18)}
.cold{background:#F9E349;color:#0A0A0A;font-size:11px;font-weight:700;padding:1px 7px;
  border-radius:999px;margin-left:6px}
.no-link{color:#9A9A9A}
.vform{display:flex;flex-direction:column;gap:7px;min-width:230px}
.vcode{width:100%}
.vpreview{font-size:12.5px;color:#6B6B6B;min-height:18px}
.vpreview.bad{color:#FF3131}
/* 图能用但有问题（比如源图太小、存下来会糊）——琥珀色，别混在「正常」里 */
.vpreview.warn{color:#8A6410}
.vthumb{width:84px;height:84px;object-fit:contain;border:1px solid #D9D9D9;border-radius:8px;display:block}
.vwarn{display:block;color:#8A6410;background:rgba(249,227,73,.25);padding:5px 8px;
  border-radius:6px;margin-top:5px;line-height:1.5}
td.when small{display:block;color:#9A9A9A;font-size:12px}

/* 小票上传口：跟素材上传口做成上下并列的一对，视觉上一眼看出是两个入口 */
.receipt-dz{cursor:default}
.receipt-dz:hover{border-color:var(--line);background:transparent}
.receipt-dz input[type=file]{margin:14px auto 0;display:block;max-width:100%;font-size:13.5px}
.receipt-dz button{margin-top:14px}

/* 手机号：区域码下拉 + 号码，同一行 */
.phone-row{display:flex;gap:8px}
.phone-row select{flex:0 0 auto;width:auto;min-width:104px}
.phone-row input{flex:1 1 auto;min-width:0}

/* ---------- 后台宽表页（待买券 / 待催小票 / 签约达人）----------
   这几页原来用裸 <h1> 和 <p class="lede">，全站都没有对应规则，
   于是标题吃浏览器默认 32px + 0.67em 上下 margin，再叠上
   main.admin 的 flex gap:18px，间距是双份的。
   垂直间距统一交给 flex gap 管，元素自己的 margin 一律归零。 */
main.admin > h1{
  margin:0;font-size:22px;font-weight:700;letter-spacing:-.015em;color:var(--charcoal);
}
main.admin > .lede{
  margin:-8px 0 0;font-size:14px;line-height:1.75;color:var(--muted);max-width:76ch;
}
main.admin > .empty{
  margin:0;font-size:14.5px;color:var(--muted);
  padding:22px;border:1px dashed var(--line);border-radius:var(--r);text-align:center;
}
main.admin code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;
  background:var(--canvas);border:1px solid var(--line);border-radius:6px;padding:1px 5px;
}

/* ---------- 后台表格 ----------
   全站表格统一用 .table-scroll：它自带纸底、边框、圆角，跟 .card 同宽同外观，
   两者上下排在一起是齐的。（admin-voucher 原来用的 .tw 全站没有任何规则，
   所以待买券那两个表格是裸在页面背景上的，已统一。） */
.table-scroll table{margin:0}

/* 通栏卡片里的提交按钮不该拉满一整行 —— 1180px 宽的紫色长条很难看。
   窄卡片（.card.narrow / main.admin.narrow）里仍然是满宽，那里满宽是对的。 */
main.admin .card:not(.narrow) > .body > form > .submit{
  width:auto;min-width:300px;align-self:flex-start;padding:14px 26px;font-size:15.5px;
}

/* ==========================================================================
   后台 = 电脑网页版（老板 2026-09-07：「后段是电脑网页版，你应该按照网页版的
   规格来做这件事」）

   达人端是手机优先：46px 高的输入框、满宽紫色按钮、单列表单 —— 那是给拇指用的。
   后台是运营坐在电脑前用鼠标键盘，规格不一样：容器更宽、行更密、表单多列、
   按钮按内容宽。以下规则全部限定在 main.admin 内，达人端一行不受影响。
   ========================================================================== */
main.admin{max-width:1400px;padding:22px 28px 72px;gap:16px}

/* 控件密度：46px 高 → 36px，字号 15.5 → 14 */
main.admin input[type=text],main.admin input[type=tel],main.admin input[type=url],
main.admin input[type=password],main.admin input[type=date],main.admin input[type=time],
main.admin input[type=number],main.admin select,main.admin textarea{
  padding:8px 11px;font-size:14px;border-radius:8px;
}
main.admin .field{gap:5px}
main.admin .field > label{font-size:13px}
main.admin .field .hint{font-size:12px;margin:1px 0 0}
main.admin .card > header{padding:16px 20px 0}
main.admin .card > header h2{font-size:17px}
main.admin .card > header p{font-size:13px}
main.admin .card > .body{padding:15px 20px 20px;gap:14px}
main.admin .grid{gap:14px 18px}

/* 桌面上一行放得下三个短字段；.field.wide 仍然独占一行 */
@media (min-width:1100px){
  main.admin .grid{grid-template-columns:repeat(3,1fr)}
}

/* ---- .edit / .row / .fl：后台编辑表单的栅格 ----
   这三个 class 之前全站没有任何规则（跟 .tw 一样），所以报名详情页和
   签约达人页的编辑表单是没有排版的，label 和下拉直接堆在一起。 */
main.admin form.edit{display:flex;flex-direction:column;gap:14px}
main.admin .row{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:14px 18px;
}
main.admin .fl{display:flex;flex-direction:column;gap:5px;min-width:0;
  font-size:13px;font-weight:600;color:var(--charcoal)}
main.admin .fl select,main.admin .fl input{font-weight:400}
main.admin .note-box{display:flex;flex-direction:column;gap:5px}
main.admin .note-box .q{font-size:13px;font-weight:600;margin:0}
main.admin .note-box .opt{font-weight:400;color:var(--muted);margin-left:6px}

/* 通栏卡片里的提交按钮不该拉满一整行 —— 1400px 宽的紫色长条很难看 */
main.admin .card:not(.narrow) > .body > form > .submit,
main.admin .card:not(.narrow) > .body > .submit{
  width:auto;min-width:280px;align-self:flex-start;padding:12px 24px;font-size:15px;
}
main.admin .btn{padding:9px 18px;font-size:14px}

/* 表格：桌面上行高可以更紧，一屏多看几行 */
main.admin th,main.admin td{padding:9px 12px}
main.admin table{font-size:13.5px}

/* ---------- 后台宽表：长文本夹行 + 操作列吸右 ----------
   两个毛病都是 2026-09-07 老板截图里那张「商家与分店」暴露的：
   ① 店规是自由文本，撑成四五行，整张表行高被它带跑
   ② 列多的时候最右边的「编辑/上架」被裁在视口外，要横向拖才点得到 */
.clamp2{
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;line-height:1.5;
}
main.admin td.wrap-cell{max-width:300px;vertical-align:middle}

/* 操作列永远停在右边，不用拖横条 */
main.admin table th:last-child,
main.admin table td:last-child{
  position:sticky;right:0;z-index:1;
  background:var(--paper);
  box-shadow:-10px 0 10px -10px rgba(10,10,10,.22);
}
main.admin table th:last-child{background:var(--surface-2,#f4f5f8)}
/* 吸住的格子有自己的背景，不跟着行走的话 hover 和「待补地址」的米黄底会断层 */
main.admin tbody tr:hover td:last-child{background:var(--canvas)}
main.admin tr.needs-review td:last-child{background:#fff6e5}
main.admin tr.needs-review:hover td:last-child{background:#fdf0d8}
