/* =========================================================
   晋升权限（js/rank.js）
   ---------------------------------------------------------
   整块以「纸」为主题：一张旧档案纸，纸上贴着工位卡、
   印着刻度、写着申请单、盖着章。没有金属反光，没有塑料，
   没有发光——所有层次靠纸的明度、纤维的颗粒和墨的深浅拉开。

   四层结构：
     L0 台面：纸放在黑桌面上，投影 + 纸边一暗一亮，交代厚度
     L1 纸基：暖白底 + 三层噪声（颗粒 / 纤维 / 云斑）
     L2 墨层：字与线统一走墨色，细线用半透明模拟印刷
     L3 装配：卡套 / 折角 / 订书钉 / 回形针，每一件都有厚度和投影

   噪声全部用 SVG data-URI 一次性贴图，soft-light 叠加：
   不运行时滤镜、不重绘、不吃帧率，离线可用。
   ========================================================= */

/* ================= 纸张本体 ================= */
/* 两张面板共用：主档案纸 + 底下垫着的两张 */
.rank-paper {
  position: relative;
  border: 0;
  border-radius: 1px;
  background-color: #cfc8b4;
  background-image:
    /* 顶部受光：靠上略亮，像灯从桌面上方打下来 */
    radial-gradient(120% 74% at 50% -14%, rgba(255, 252, 240, 0.3), transparent 62%),
    /* 右下背光：手压过的地方稍暗 */
    radial-gradient(86% 60% at 100% 104%, rgba(96, 84, 62, 0.1), transparent 66%),
    /* 纸基：暖白，明度不高但够干净，暗部只到边缘 */
    linear-gradient(170deg, #d6cfbb 0%, #cec7b2 46%, #c1b9a3 100%);
  box-shadow:
    /* 纸边厚度：顶面受光，底面压暗一线 */
    inset 0 1px 0 rgba(255, 253, 245, 0.5),
    inset 0 0 0 1px rgba(255, 253, 245, 0.18),
    inset 0 -2px 3px -2px rgba(88, 76, 54, 0.38),
    /* 底边那一道切口的暗线 */
    0 1px 0 rgba(118, 104, 80, 0.5),
    /* 桌面投影：近处实、远处散 */
    0 14px 26px -14px rgba(0, 0, 0, 0.92),
    0 36px 58px -36px rgba(0, 0, 0, 0.82);
  color: #241f18;
  isolation: isolate;
}

/* 纸的骨与筋：颗粒 + 横向长纤维 + 大尺度云斑。
   soft-light 叠加：噪声中心值 0.5 时完全中性，只出细节不改明度。 */
.rank-paper::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.85;
  mix-blend-mode: soft-light;
  background-image:
    /* 颗粒：纸的骨，最细那一层 */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.62' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E"),
    /* 纤维：拉长的方向性噪声，纸的筋 */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='f'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='320' height='320' filter='url(%23f)'/%3E%3C/svg%3E"),
    /* 云斑：手工纸的不匀，只在暗部隐约可见 */
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='420' height='420'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.011' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='420' height='420' filter='url(%23m)'/%3E%3C/svg%3E");
  background-size: 180px 180px, 320px 320px, 420px 420px;
  background-repeat: repeat;
}

/* 纸的边：内圈压一道极淡的痕，让纸面有「被压过」的边界 */
.rank-paper::after {
  content: "";
  position: absolute;
  inset: 2px;
  z-index: 0;
  pointer-events: none;
  box-shadow:
    inset 0 0 0 1px rgba(120, 106, 82, 0.07),
    inset 0 0 22px rgba(120, 106, 82, 0.05);
}

/* 主面板：自己不画纸，只是一块能放 3D 的台面——纸在里面的两张面上 */
#rank-box.rank-panel {
  padding: 0;
  border: none;
  background: none;
  perspective: 1500px;
  perspective-origin: 50% 42%;
}

/* ================= 装订：订书钉 + 回形针 =================
   两件金属压在纸边上，钉子穿过纸（腿在后面）、夹子挂在纸外。
   它们的唯一作用是给纸一个「实物尺寸」的参照。 */
.rank-side > .rank-staple {
  position: absolute;
  top: -3px;
  left: 26px;
  z-index: 4;
  width: 22px;
  height: 5px;
  border-radius: 1px;
  background: linear-gradient(180deg, #b9bcc0 0%, #92969a 34%, #6f7478 64%, #a6aaae 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.55),
    inset 0 -1px 0 rgba(40, 44, 48, 0.45),
    0 1px 1px rgba(0, 0, 0, 0.5),
    0 1px 0 rgba(255, 253, 245, 0.35);
  transform: rotate(-2.5deg);
  pointer-events: none;
}

/* 两条腿：穿过纸面，扎进纸里就断了 */
.rank-staple::before,
.rank-staple::after {
  content: "";
  position: absolute;
  bottom: -5px;
  width: 2px;
  height: 7px;
  background: linear-gradient(180deg, rgba(48, 44, 36, 0.6) 0%, rgba(48, 44, 36, 0) 92%);
}

.rank-staple::before { left: 3px; }
.rank-staple::after { right: 3px; }

/* 回形针：挂在纸的上边沿，一半在纸外，一半压着纸 */
.rank-side > .rank-clip {
  position: absolute;
  top: -13px;
  right: 15px;
  z-index: 4;
  width: 22px;
  height: 46px;
  pointer-events: none;
  transform: rotate(7deg);
  filter:
    drop-shadow(0 1px 1px rgba(0, 0, 0, 0.45))
    drop-shadow(0 3px 5px rgba(0, 0, 0, 0.3));
}

.rank-clip svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* ================= 翻页：一张纸，正反两面 ================= */
/* 正面在文档流里定高度，背面绝对定位叠满同一块地方 */
.rank-stage {
  position: relative;
  transform-style: preserve-3d;
  transition: transform 0.72s cubic-bezier(0.36, 0.02, 0.18, 1);
}

#rank-box.flipped .rank-stage {
  transform: rotateY(-180deg);
}

.rank-side {
  position: relative;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

/* 背面：先自己转 180°，整叠翻过去之后才是正的。
   同一张纸，受光少一点，偏冷偏灰，纤维还在。 */
.rank-side-b {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding-bottom: 26px;
  transform: rotateY(180deg);
  background-color: #c9c2ad;
  background-image:
    radial-gradient(120% 74% at 50% 116%, rgba(255, 252, 240, 0.2), transparent 62%),
    radial-gradient(80% 56% at 0% 0%, rgba(96, 84, 62, 0.12), transparent 66%),
    linear-gradient(200deg, #d0c9b4 0%, #c7c0ab 52%, #b9b19b 100%);
}

/* 翻过去之后，正面那张纸不能再吃点击（提交键会被背面压住） */
#rank-box.flipped .rank-side-a,
#rank-box:not(.flipped) .rank-side-b {
  pointer-events: none;
}

/* 纸张里的内容一律压在纤维层之上 */
.rank-side > * {
  position: relative;
  z-index: 1;
}

/* 折角直接压在提交键的右下角上，不特意让位——纸盖住纸，才像同一张 */
#rank-box:not(.locked) .rank-side-a {
  padding-bottom: 0;
}

/* ================= 折角 =================
   一摞纸，顶页的右下角向内折过去：
     · 左上那个三角是翻上来的纸背，压在纸面上，边上带一圈投影
     · 右下那个三角是折走后露出来的底页，被顶页的折边压出一道影
   两个三角拼成一块 46px 的方，中间那道斜线就是折缝。
   点它整张纸翻过去。 */
.rank-ear {
  position: absolute;
  right: 0;
  bottom: 0;
  z-index: 5;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

/* 未接入：还没这张纸，折角也就没有 */
#rank-box.locked .rank-ear {
  display: none;
}

/* 露出来的底页：不是死平色——它是另一张纸，
   更暗一档，带自己的颗粒，靠折缝那侧被压出阴影。 */
.rank-ear .re-under {
  position: absolute;
  inset: 0;
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
  background-color: #aaa28c;
  background-image:
    linear-gradient(135deg, rgba(40, 32, 18, 0.42) 0%, rgba(40, 32, 18, 0.1) 34%, rgba(40, 32, 18, 0) 64%),
    linear-gradient(180deg, #b1a993 0%, #9e9680 100%);
}

/* 翻上来的那一块：纸背朝上，比纸面亮一档。
   投影必须留在这一层——和 clip-path 放同一个元素上的话，
   投影会被一起裁掉，只剩一个干净的三角。 */
.rank-ear .re-fold {
  position: absolute;
  inset: 0;
  filter:
    drop-shadow(-1px -1px 2px rgba(26, 18, 6, 0.34))
    drop-shadow(-4px -4px 7px rgba(26, 18, 6, 0.16));
  transition: filter 0.18s ease;
}

/* 纸背本体：
   · 折痕贴着斜边压深一线，再靠里一条极窄的高光（纸被折断后露白）
   · 从折缝往角尖由亮转暗，说明折起来的那块是背光的
   · 纸背比正面亮，但也要有自己的纤维，否则是一块塑料 */
.rank-ear .re-fold > i {
  position: absolute;
  inset: 0;
  display: block;
  clip-path: polygon(0 0, 100% 0, 0 100%);
  background-color: #e2dbc8;
  background-image:
    /* 折缝：深一线 */
    linear-gradient(45deg, rgba(44, 34, 17, 0.5) 0, rgba(44, 34, 17, 0.22) 1px, rgba(44, 34, 17, 0) 2px),
    /* 折缝内侧的露白：纸折断处纤维翻开 */
    linear-gradient(45deg, rgba(255, 253, 244, 0) 2px, rgba(255, 253, 244, 0.55) 3px, rgba(255, 253, 244, 0) 5px),
    /* 纸背：靠折缝受光，往角尖略暗 */
    linear-gradient(45deg, #e6dfcc 0%, #ddd6c2 42%, #cfc7b1 100%);
  box-shadow: inset 1px 1px 0 rgba(255, 253, 243, 0.5);
}

/* 折角上的字：写在露出来的底页上，贴着折缝，沿斜边读 */
.rank-ear .re-label {
  position: absolute;
  left: 23px;
  top: 23px;
  width: 78px;
  height: 12px;
  margin: -6px 0 0 -39px;
  font-size: 7.5px;
  line-height: 12px;
  letter-spacing: 0.4px;
  text-align: center;
  color: #2e281c;
  text-shadow: 0 1px 0 rgba(255, 252, 240, 0.22);
  pointer-events: none;
  transform: translate(7px, 7px) rotate(-45deg);
}

/* 按下：折角往里压 */
.rank-ear:active .re-fold > i {
  transform: translate(1px, 1px);
}

.rank-ear:focus-visible {
  outline: 1px solid #8c2f30;
  outline-offset: -6px;
}

/* ================= 顶栏：表头 ================= */
.rank-plate {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 13px 14px 7px;
  border-bottom: 3px double rgba(36, 31, 24, 0.78);
  font-size: 10px;
  letter-spacing: 2px;
}

/* 标题：像铅字压进纸里，不是发光的 UI 字 */
.rank-plate-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 3px;
  color: #241f18;
  text-shadow: 0 0.5px 0 rgba(255, 252, 240, 0.55);
}

.rank-plate-title::before {
  display: none;
}

.rank-plate-meta {
  display: none;
  margin-left: auto;
  font-family: monospace;
  font-size: 9.5px;
  letter-spacing: 0.5px;
  color: #8c2f30;
}

/* 未接入：退回淡墨 */
#rank-box.locked .rank-plate-meta {
  color: #6f6857;
}

/* ================= 工位卡 ================= */
.rank-badge {
  margin: 12px 14px 0;
}

/* 纸套：比档案纸亮一档，卡插在里面。
   套子要有厚度——外沿一道亮边，内沿一道暗槽，卡才不会像贴上去的。 */
.rb-sleeve {
  position: relative;
  padding: 3px;
  border-radius: 2px;
  background: linear-gradient(180deg, #ded7c3 0%, #d3ccb7 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.8),
    inset 0 -1px 0 rgba(120, 106, 82, 0.22),
    0 1px 0 rgba(70, 58, 38, 0.26),
    0 3px 6px -3px rgba(60, 50, 35, 0.45),
    0 0 0 1px rgba(96, 84, 62, 0.2);
  overflow: hidden;
}

/* 卡面反光：一道极淡的斜光，不做出塑料感 */
.rb-gloss {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  background: linear-gradient(
    104deg,
    rgba(255, 255, 255, 0) 26%,
    rgba(255, 255, 255, 0.16) 38%,
    rgba(255, 255, 255, 0.02) 48%,
    rgba(255, 255, 255, 0) 60%
  );
}

/* 卡面：插在套子里，所以四周压一圈内阴影——卡是被套住的，不是浮着的 */
.rb-card {
  position: relative;
  border-radius: 1px;
  overflow: hidden;
  background-color: #d0c9b4;
  background-image: linear-gradient(168deg, #d5ceb9 0%, #cbc4ae 56%, #bfb7a1 100%);
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.34),
    inset 0 2px 4px -2px rgba(60, 50, 35, 0.3),
    inset 0 -1px 2px -1px rgba(60, 50, 35, 0.2);
}

/* 卡纸纤维：比档案纸更细的一层颗粒 */
.rb-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0.7;
  mix-blend-mode: soft-light;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='c'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.7' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23c)'/%3E%3C/svg%3E");
  background-size: 160px 160px;
}

/* 部门色条：印刷的红，不是发光的红 */
.rb-strip {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 4px 9px;
  background: linear-gradient(180deg, #7d2324 0%, #5d1a1b 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.12),
    inset 0 -1px 0 rgba(0, 0, 0, 0.28);
  font-size: 8.5px;
  letter-spacing: 1.6px;
  color: #ece2d8;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.35);
}

.rb-strip-lv {
  font-family: monospace;
  letter-spacing: 0.6px;
  color: rgba(236, 226, 216, 0.76);
}

.rb-main {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 9px 6px;
}

/* 照片框：空着，只盖一个编号。框是压进卡里的凹槽 */
.rb-photo {
  flex: none;
  width: 42px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(180deg, #b8b1a0 0%, #a29b8a 100%);
  box-shadow:
    inset 0 2px 4px rgba(50, 42, 28, 0.38),
    inset 0 -1px 0 rgba(255, 253, 245, 0.4),
    0 0 0 1px rgba(45, 40, 30, 0.24),
    0 1px 0 rgba(255, 255, 255, 0.5);
}

.rb-no {
  font-family: monospace;
  font-size: 26px;
  font-weight: 700;
  line-height: 1;
  color: #322f27;
  opacity: 0.82;
  text-shadow: 0 0.5px 0 rgba(255, 252, 240, 0.4);
}

.rb-id {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.rb-name {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 3px;
  line-height: 1.25;
  color: #221e18;
  white-space: nowrap;
  text-shadow: 0 0.5px 0 rgba(255, 252, 240, 0.5);
}

.rb-sub {
  margin-top: 3px;
  font-family: monospace;
  font-size: 8px;
  letter-spacing: 1.2px;
  color: #625c4d;
}

/* 卡底：条码 + 编号 */
.rb-foot {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 8px;
  padding: 0 9px 8px;
}

.rb-bars {
  display: block;
  width: 92px;
  height: 15px;
  opacity: 0.66;
  background-image: repeating-linear-gradient(
    90deg,
    #241f18 0 1px,
    transparent 1px 3px,
    #241f18 3px 5px,
    transparent 5px 6px,
    #241f18 6px 7px,
    transparent 7px 10px,
    #241f18 10px 12px,
    transparent 12px 13px
  );
}

.rb-serial {
  font-family: monospace;
  font-size: 7.5px;
  letter-spacing: 0.8px;
  color: #5f5949;
  white-space: nowrap;
}

/* 空白卡：未接入时整张卡退成灰模，条码断开 */
.rank-badge.blank .rb-card {
  filter: grayscale(0.92) brightness(0.96);
}

.rank-badge.blank .rb-strip {
  background: linear-gradient(180deg, #6a6862 0%, #565450 100%);
}

.rank-badge.blank .rb-bars {
  opacity: 0.16;
  background-image: repeating-linear-gradient(
    90deg,
    #241f18 0 1px,
    transparent 1px 10px
  );
}

.rank-badge.blank .rb-no {
  opacity: 0.3;
}

.rank-badge.blank .rb-name {
  letter-spacing: 5px;
  color: #514c3d;
}

/* ================= 阶位刻度尺 ================= */
.rank-scale {
  margin: 14px 14px 0;
}

.rs-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 4px;
  font-family: monospace;
  font-size: 8px;
  letter-spacing: 1.2px;
  color: #5f5949;
}

.rs-count {
  color: #3f3a2e;
  letter-spacing: 0.5px;
}

/* 一根印上去的细线 + 一排印刷刻度。
   刻度是竖的一小竖，不是 UI 圆点——纸上不会长圆点。 */
.rs-track {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 12px;
  padding: 0 2px;
}

.rs-track::before {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  top: 50%;
  height: 1px;
  background: rgba(36, 31, 24, 0.24);
}

.rs-track i {
  position: relative;
  display: block;
  width: 1px;
  height: 5px;
  border-radius: 0;
  background: rgba(36, 31, 24, 0.2);
  transition: background 0.35s ease, box-shadow 0.35s ease, height 0.35s ease;
}

.rs-track i.on {
  background: rgba(36, 31, 24, 0.72);
}

.rs-track i.cur {
  height: 9px;
  background: #8c2f30;
  box-shadow: 0 0 0 2px rgba(140, 47, 48, 0.14);
}

/* ================= 晋升申请单 ================= */
.rank-doc {
  position: relative;
  margin: 14px 14px 0;
  padding-top: 10px;
  border-top: 1px dashed rgba(36, 31, 24, 0.28);
}

.rd-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  padding-bottom: 5px;
  margin-bottom: 7px;
  border-bottom: 1px solid rgba(36, 31, 24, 0.72);
}

.rd-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 1px;
  color: #241f18;
  text-shadow: 0 0.5px 0 rgba(255, 252, 240, 0.5);
}

.rd-cost {
  font-family: monospace;
  font-size: 11px;
  letter-spacing: 0.3px;
  color: #8c2f30;
  white-space: nowrap;
}

.rd-desc {
  font-family: monospace;
  font-size: 9.5px;
  line-height: 1.6;
  color: #5f5949;
  margin-bottom: 8px;
}

/* 授予栏：荧光笔划过的那一条 */
.rd-grant {
  font-size: 10px;
  line-height: 1.55;
  color: #3f3620;
  padding: 4px 8px 4px 9px;
  margin-bottom: 9px;
  border-left: 3px solid #a8802f;
  background: linear-gradient(
    90deg,
    rgba(196, 154, 52, 0.2) 0%,
    rgba(196, 154, 52, 0.14) 72%,
    rgba(196, 154, 52, 0.05) 100%
  );
  box-shadow: inset 0 0 0 1px rgba(168, 128, 47, 0.1);
}

.rd-grant:empty {
  display: none;
}

.rp-tag {
  display: inline-block;
  font-size: 8.5px;
  letter-spacing: 1px;
  color: #8c2f30;
  border: 1px solid rgba(140, 47, 48, 0.42);
  padding: 0 4px;
  margin-right: 6px;
  vertical-align: 1px;
}

/* ================= 核对项 ================= */
/* 底部留白是给印章的签署区，不是失误 */
.rank-req {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 6px;
  padding-bottom: 22px;
}

.rq {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  font-family: monospace;
  font-size: 10px;
  line-height: 1.5;
}

/* 带数字进度的行，在行底压一条 1px 细线，不占高度 */
.rq[data-p]::after {
  content: "";
  position: absolute;
  left: 18px;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: linear-gradient(
    90deg,
    rgba(61, 107, 78, 0.55) var(--p, 0%),
    rgba(36, 31, 24, 0.1) var(--p, 0%)
  );
}

.rq.no[data-p]::after {
  background: linear-gradient(
    90deg,
    rgba(140, 47, 48, 0.5) var(--p, 0%),
    rgba(36, 31, 24, 0.09) var(--p, 0%)
  );
}

/* 勾选框：墨线方格，达成才落笔 */
.rq-mark {
  flex: none;
  width: 11px;
  height: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 8px;
  line-height: 1;
  color: transparent;
  box-shadow: inset 0 0 0 1px rgba(36, 31, 24, 0.42);
}

.rq.ok .rq-mark {
  color: #3d6b4e;
  box-shadow: inset 0 0 0 1px rgba(61, 107, 78, 0.5);
}

.rq.no .rq-mark {
  color: #8c2f30;
  box-shadow: inset 0 0 0 1px rgba(140, 47, 48, 0.38);
}

.rq-t {
  flex: 1;
  min-width: 0;
  color: #5f5949;
}

.rq-v {
  flex: none;
  color: #5f5949;
  white-space: nowrap;
}

.rq.ok .rq-t { color: #38332a; }
.rq.ok .rq-v { color: #3d6b4e; }
.rq.no .rq-v { color: #8c2f30; }

/* ================= 状态印章 =================
   章是这张纸上最有分量的东西：压得深、边缘吃墨不匀、略微歪。
   所以它必须压在所有装饰之上，不能被折角切掉。 */
.rd-stamp {
  position: absolute;
  right: 2px;
  bottom: 0;
  z-index: 2;
  padding: 2px 8px 2px 9px;
  font-family: monospace;
  font-size: 9px;
  letter-spacing: 2px;
  line-height: 1.5;
  color: #6f6857;
  border: 1.5px solid #6f6857;
  border-radius: 1px;
  transform: rotate(-6deg);
  pointer-events: none;
  opacity: 0.72;
  /* 吃墨不匀：边框用两层半透明叠出毛边 */
  box-shadow:
    0 0 0 0.5px rgba(111, 104, 87, 0.35),
    inset 0 0 0 0.5px rgba(111, 104, 87, 0.3);
  transition: color 0.2s ease, border-color 0.2s ease, opacity 0.2s ease;
}

/* 可提交：一枚红章，吃墨重 */
.rd-stamp.ok {
  color: #8c2f30;
  border-color: #8c2f30;
  opacity: 0.9;
  text-shadow: 0 0 1px rgba(140, 47, 48, 0.4);
  box-shadow:
    0 0 0 0.5px rgba(140, 47, 48, 0.34),
    inset 0 0 0 0.5px rgba(140, 47, 48, 0.3),
    inset 0 0 6px rgba(140, 47, 48, 0.12);
}

.rd-stamp.no {
  color: #6f6857;
  border-color: #6f6857;
}

.rd-stamp.max {
  color: #625c4d;
  border-color: #625c4d;
}

/* 盖章：只在状态翻成「可提交」时弹一次 */
.rd-stamp.hit {
  animation: stampHit 0.42s cubic-bezier(0.2, 1.5, 0.4, 1);
}

@keyframes stampHit {
  0% { transform: rotate(-6deg) scale(1.9); opacity: 0; }
  55% { opacity: 1; }
  100% { transform: rotate(-6deg) scale(1); opacity: 0.9; }
}

/* ================= 提交键 =================
   纸上的按钮不该是一块黑塑料。这里做成「墨滚过的实心块」：
   四边压深、顶面留一点纸白，像油墨压在纸上。
   不可提交时不是变透明，而是只剩一道没上墨的框——表格还没盖章。 */
.rank-go {
  width: calc(100% - 28px);
  margin: 10px 14px 14px;
  padding: 10px 12px;
  border: 1px solid #241f18;
  border-radius: 1px;
  background: #241f18;
  background-image: linear-gradient(180deg, rgba(255, 253, 245, 0.06) 0%, rgba(0, 0, 0, 0.18) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 253, 245, 0.14),
    inset 0 -1px 0 rgba(0, 0, 0, 0.4),
    2px 2px 0 rgba(36, 31, 24, 0.14);
  font-size: 11.5px;
  letter-spacing: 1.5px;
  transition: transform 0.07s ease, box-shadow 0.1s ease, background 0.2s ease, color 0.2s ease;
}

.rank-go:active:not(:disabled) {
  transform: translate(1px, 1px);
  background: #322c24;
  box-shadow:
    inset 0 1px 0 rgba(255, 253, 245, 0.1),
    inset 0 2px 4px rgba(0, 0, 0, 0.35);
}

/* 未上墨：只剩框，字是淡墨 */
.rank-go:disabled {
  background: rgba(36, 31, 24, 0.05);
  background-image: none;
  border-color: rgba(36, 31, 24, 0.35);
  box-shadow: inset 0 0 0 1px rgba(255, 253, 245, 0.16);
  cursor: not-allowed;
}

#rank-go-label {
  color: #e6dfcc;
}

#rank-go-state {
  color: rgba(230, 223, 204, 0.55);
  letter-spacing: 0.3px;
}

.rank-go:disabled #rank-go-label {
  color: rgba(36, 31, 24, 0.55);
}

.rank-go:disabled #rank-go-state {
  color: rgba(36, 31, 24, 0.38);
}

/* ================= 权限册（纸的背面） =================
   清单从背面顶栏下面开始排，长了自己滚，不外溢到折角上。 */
.rank-perk-list {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding: 2px 14px 0;
  overflow-y: auto;
  scrollbar-width: none;
}

.rank-perk-list::-webkit-scrollbar {
  display: none;
}

.rp-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-family: monospace;
  font-size: 10px;
  line-height: 1.45;
  border-bottom: 1px dashed rgba(36, 31, 24, 0.2);
}

.rp-row:last-child {
  border-bottom: none;
}

/* 阶位标：墨框小方块 */
.rp-lv {
  flex: none;
  width: 18px;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 9px;
  font-weight: 700;
  color: #8c2f30;
  border: 1px solid rgba(140, 47, 48, 0.35);
  background: rgba(140, 47, 48, 0.05);
}

.rp-row .rp-txt {
  flex: 1;
  min-width: 0;
  color: #3f3a2e;
}

.rp-empty {
  padding-top: 6px;
  font-family: monospace;
  font-size: 10px;
  line-height: 1.6;
  color: #5f5949;
}
