/* ============================================================================
   商机详细页 v5 —— 布局自适应 / 自绘日期控件 / 节假日标注 / 移动端浮动新建入口
   ----------------------------------------------------------------------------
   单独成文件的原因：Tailwind 产物 CSS（index-ui2-*.css）只包含「按需生成」的类，
   而 .input / .btn-* 等既有规则要沿用；只有在它之后追加一份样式表，
   才能既复用旧类、又让新增的 .ns-* 规则生效。
   本文件加载在 index-ui2-*.css 之后，同名属性覆盖后者。
   ⚠️ 文件名带内容哈希，服务端据此返回 immutable 强缓存 —— 改了内容必须一起改名。
   ========================================================================= */

/* ------------------------- R8：统一列宽（@hw207） ------------------------- */
/* 背景：2026-10-14 之前的做法是按字段手工调宽（248 / 224 / auto / 368 / 296 / 264 …），
   每行末尾"看起来"是排满的，但各行第 2、3 列的起始位置互不相同
   （实测同一张卡片内：516 / 636 / 508、760 / 952 / 768），视觉上参差不齐。
   现在改为「网格 + 统一列宽」：每列固定 272px（= 1440 视口下 4 列刚好铺满卡片内宽
   1156px、且「客户单位」这类宽内容不被截断的上限），字段按 DOM 顺序从左往右依次落列；
   justify-content:start 让列紧贴左缘排列，整行填不满时，多余空白统一留在最右侧。
   历史：更早是 fr 网格，被行宽拉伸（数字框空出 200px）—— 固定列宽不会再有该问题。 */
.ns-fields {
  display: grid;
  grid-template-columns: repeat(auto-fill, 272px);
  justify-content: start; /* 列从左起排，多余空间一律留给右侧 */
  align-items: start;
  gap: 10px 20px;
  min-width: 0;
}

/* 每格占一列（272px）：网格项 width:auto 即拉伸填满所在列 */
.ns-f {
  display: flex;
  align-items: center;
  gap: 8px;
  width: auto;
  max-width: 100%;
  min-width: 0;
}

/* 公示：筹码可能换行，标签对齐首行文字 */
.ns-f-publicity { align-items: flex-start; }

/* 跨列字段（仍落在同一套列网格上） */
.ns-f-projectOverview {
  grid-column: 1 / -1; /* 项目内容：独占整行，与首列左对齐 */
  align-items: flex-start;
}
.ns-f-projectOverview > label { padding-top: .375rem; }
.ns-f-lost { grid-column: span 2; } /* 丢单：「丢单原因」+「中标方」并排，占两列 */

/* ---------------- R11：标签左对齐 + 行首对齐 + 控件收窄（@hw208） ---------------- */
/* 需求：①「项目阶段」上移一行、排在「公示」之前（字段分组见 bundle）；
   ② 金额 / 优先级 / 行业经理 / 项目阶段 四个控件适当收窄；
   ③「丢单原因 = 丢给对手」时弹出的「中标方」输入框不得换行；
   ④ 各行开头与首行「金额」对齐。
   实测（1440 视口）：各行「控件盒」本来就都在列网格上（左缘 248/540/832/1124），
   真正不齐的是「标签文字」左缘 —— 标签盒固定 92px 且文字右对齐，于是 6 字的
   「金额（万元）」起于 274，而 4 字的「客户单位 / 项目内容 / 开始时间」起于 296。
   这里把标签改为「左对齐 + 收紧到 76px」：所有标签文字左缘统一落在列左缘，
   标签盒变窄后控件获得更大可用宽度，标签与控件之间也不再留下大段空白。
   76px = 最长标签「金额（万元）/ 要求交付时间」实测 66px + 10px 余量。 */
.ns-fields .ns-f > label {
  width: 76px;
  text-align: left;
}

/* 四个控件收窄到统一 150px（原为撑满所在列 188px），让行内控件成为等宽的一组 */
.ns-f-budget > div > .input,
.ns-f-priority > div > .input,
.ns-f-owner_name > div > .input,
.ns-f-status > div > .input {
  width: 120px;
}

/* 丢单区块禁止换行：「中标方」输入框改为可伸缩（flex-basis 优先于 width:auto!important），
   在两列 564px 内始终与「丢单原因」同行。
   窄屏（≤767px）容器只有一列约 326px，物理上放不下，故回退为换行以免横向溢出。 */
.ns-f-lost > div { flex-wrap: nowrap; }
.ns-f-lost > div > select.input { flex: 0 1 auto; min-width: 0; }
.ns-f-lost > div > input.input { flex: 1 1 130px; min-width: 72px; }

/* ------------------- R12：公示移入第二行 + 单行不换行 + 标签收紧（@hw209） ------------------- */
/* 需求：①「公示=已公示」时日期框不该换行；②「公示」文字与切换按钮间距收紧；
   ③ 公示整体移到第二行「行业经理」之后；④ 四个控件再收窄。
   实测（1440 视口，改前）：公示所在列仅 272px，而内容是
   「切换组 107px + 公示日期 44px + 日期输入框 136px」+ 2×7px 间距 = 301px
   ⇒ 必然折行（实测内容 3 行：toggle top 121.5 / cal top 149.8）。
   这里让公示跨 2 列（564px）：可用 564-76(标签)-8 = 480px > 301px，单行即可放下。
   行归属由 bundle 的容器组装决定（公示已并入第二行容器，排在「行业经理」之后）。
   标签改为按内容收缩（width:auto）：`公示` 文字右缘→切换组左缘由 62px 收到 8px
   （即 .ns-f 的标准 gap）。选择器 (0,2,1) 与 .ns-fields .ns-f > label 同权重、
   靠后声明取胜，故能覆盖后者的 76px 定宽。 */
.ns-f-publicity { grid-column: span 2; }
.ns-fields .ns-f-publicity > label { width: auto; }

/* ------------------------------ R2：金额无上下箭头 ------------------------------ */
/* input[type=number] 的原生上下箭头在窄框里既挤又容易误点 */
input[type="number"] {
  -moz-appearance: textfield;
  appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  appearance: none;
  margin: 0;
}

/* --------------------------- R1：顶部商机名称编辑按钮 --------------------------- */
.ns-name-edit {
  display: inline-flex;
  flex: 0 0 auto;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid rgb(229 231 235);
  border-radius: 6px;
  background: #fff;
  color: rgb(156 163 175);
  cursor: pointer;
  transition: color .15s, background-color .15s, border-color .15s;
}
.ns-name-edit:hover {
  background: rgb(239 246 255);
  border-color: rgb(191 219 254);
  color: rgb(37 99 235);
}

.ns-name-input {
  width: auto;
  min-width: 200px;
  max-width: min(440px, 42vw);
  padding-top: .3rem;
  padding-bottom: .3rem;
  font-size: .875rem;
}

/* ------------------------- R7：日期选择弹窗向右弹出 ------------------------- */
/* 原生 input[type=date] 的日历面板由浏览器渲染，无法用 CSS 控制方向；
   这里改为自绘面板：默认贴在输入框右侧展开，右侧空间不足（手机）时
   才退回下方右对齐，避免跑出屏幕。 */
.ns-cal {
  position: relative;
  display: block;
  width: 100%;
  min-width: 0;
}
.ns-cal-inline { width: auto; }

.ns-cal-input {
  padding-right: 24px;
  cursor: pointer;
}

.ns-cal-ico {
  position: absolute;
  top: 50%;
  right: 6px;
  display: inline-flex;
  transform: translateY(-50%);
  color: rgb(156 163 175);
  cursor: pointer;
}
.ns-cal-ico:hover { color: rgb(37 99 235); }

.ns-cal-pop {
  position: absolute;
  z-index: 70;
  width: 252px;
  padding: 10px 10px 8px;
  border: 1px solid rgb(229 231 235);
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 14px 34px rgba(15, 23, 42, .16);
  text-align: left;
}
.ns-cal-pop-side { top: -4px; left: calc(100% + 10px); right: auto; }
.ns-cal-pop-below { top: calc(100% + 6px); left: auto; right: 0; }
/* 锚点贴近视口底部时向上展开：由 bundle 的 openIt 判定后挂 -above 类。
   下方不足而上方有余量时向上弹，用户不用先把页面滚到底。 */
.ns-cal-pop-above { top: auto; bottom: calc(100% + 6px); left: 0; right: auto; }

.ns-cal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}
.ns-cal-title { font-size: 12px; font-weight: 600; color: rgb(55 65 81); }
.ns-cal-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 1px solid rgb(229 231 235);
  border-radius: 6px;
  background: #fff;
  color: rgb(107 114 128);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
}
.ns-cal-nav:hover { background: rgb(243 244 246); color: rgb(37 99 235); }

.ns-cal-week,
.ns-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.ns-cal-week { margin-bottom: 2px; }
.ns-cal-week span { text-align: center; font-size: 10px; color: rgb(156 163 175); }

.ns-cal-day {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 24px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: rgb(55 65 81);
  font-size: 12px;
  cursor: pointer;
}
.ns-cal-day:hover { background: rgb(239 246 255); color: rgb(37 99 235); }
.ns-cal-day.is-today { box-shadow: inset 0 0 0 1px rgb(191 219 254); }
.ns-cal-day.is-on { background: rgb(37 99 235); color: #fff; }
.ns-cal-blank { height: 24px; }

.ns-cal-foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid rgb(243 244 246);
}
.ns-cal-act {
  padding: 2px 4px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: rgb(37 99 235);
  font-size: 11px;
  cursor: pointer;
}
.ns-cal-act:hover { background: rgb(239 246 255); }

/* ------------------- R9：日历标注法定假期与调休上班日 ------------------- */
/* 数据来自 /assets/holidays-v1.js（window.NS_HOLIDAYS，逐年更新只需换该文件）。
   口径：休 = 法定节假日放假（含春节/国庆等连休）与自然周末；班 = 调休上班日。
   日期粒度到天后，用户是按天选时机的，所以"这天到底上不上班"必须能一眼看到。 */
.ns-cal-day { position: relative; }
.ns-cal-day.is-hol { color: rgb(185 28 28); }
.ns-cal-day.is-hol:hover { background: rgb(254 226 226); color: rgb(185 28 28); }
.ns-cal-day.is-work { color: rgb(180 83 9); }
.ns-cal-day.is-work:hover { background: rgb(254 243 199); color: rgb(180 83 9); }

.ns-cal-tag {
  position: absolute;
  top: 0;
  right: 1px;
  font-size: 8px;
  font-weight: 600;
  font-style: normal;
  line-height: 1;
  pointer-events: none;
}
.ns-cal-tag-weekend { color: rgb(148 163 184); }
.ns-cal-tag-holiday { color: rgb(220 38 38); }
.ns-cal-tag-work { color: rgb(217 119 6); }

/* 选中态必须压过上面的假期配色，所以在它之后重新声明一次 */
.ns-cal-day.is-on,
.ns-cal-day.is-on:hover { background: rgb(37 99 235); color: #fff; }
.ns-cal-day.is-on .ns-cal-tag { color: rgba(255, 255, 255, 0.88); }

.ns-cal-note {
  margin-top: 5px;
  font-size: 10px;
  line-height: 1.35;
  color: rgb(107 114 128);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ns-cal-legend { margin-right: auto; font-size: 10px; color: rgb(148 163 184); }

/* --------------------------------- 窄屏 --------------------------------- */
/* 手机上没有"右侧"可用空间，统一改为每格独占一行、日历落回下方右对齐 */
@media (max-width: 767px) {
  /* 常/窄屏统一：单列铺满，一字段一行 */
  .ns-fields { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .ns-f-lost { grid-column: auto; }
  /* @hw209 单列时公示不再跨 2 列（跨列会撑出 2 倍行宽） */
  .ns-f-publicity { grid-column: auto; }
  /* @hw208 窄屏一列放不下「丢单原因 + 中标方」整行，回退为换行（避免横向溢出） */
  .ns-f-lost > div { flex-wrap: wrap; }
  .ns-f-lost > div > input.input { flex: 0 1 auto; }
  .ns-f-projectOverview { min-width: 0; }
  /* 窄屏：弹层固定 252px，而锚点常比它窄（行内日历被 flex 压到 ~160px，
   待办行前面还有「截止」标签）。此时继续右对齐会把弹层左缘顶出屏幕
   （实测 left:-57px，左侧日期与星期列被裁掉且点不到），故统一改为左对齐。
   锚点左缘 36~64px + 252px 仍在 390px 视口内。 */
  .ns-cal-pop-side,
  .ns-cal-pop-below { top: calc(100% + 6px); left: 0; right: auto; }
  .ns-cal-pop-above { bottom: calc(100% + 6px); left: 0; right: auto; }
}


/* ============================================================================
   R10 · 移动端「新建」浮动入口（商机列表页）
   ----------------------------------------------------------------------------
   背景：窄屏（<640px）工具栏里的「新建商机」只剩一个 39x28px 的绿色图标按钮，
   既低于 44px 最小触达尺寸，又贴在右上角 —— 实测 390x844 下 39x28 @ (341,118)，
   是单手最难够到的位置；列表长了还要先滚回顶部。
   改为右下角常驻浮动按钮：高 56px、带文字、位于底部分页栏（45px）之上，
   底边距含 iOS 安全区；窄屏隐藏工具栏原按钮（避免双入口，也让搜索框更宽）。
   断点与产物既有 `hidden sm:inline` 一致：<640px 浮动按钮，>=640px 工具栏按钮。
   ========================================================================= */
:root {
  --ns-fab-h: 56px;
  --ns-fab-gap: 12px;
  --ns-fab-side: 16px;
}

.ns-fab { display: none; }

@media (max-width: 639.98px) {
  /* 工具栏里的同功能按钮在窄屏收起，只留浮动入口 */
  .ns-newbar { display: none !important; }

  /* 列表底部占位：保证最后一张卡片的按钮能滚到浮动按钮上方，不被压住 */
  .ns-fab-space {
    height: calc(var(--ns-bottombar-h, 45px) + var(--ns-fab-gap) + var(--ns-fab-h) + 16px);
  }

  .ns-fab {
    position: fixed;
    z-index: 20; /* 与底部分页栏同级；抽屉遮罩 30 / 弹窗 50 / 通知 60 都能盖住它 */
    right: var(--ns-fab-side);
    bottom: calc(var(--ns-bottombar-h, 45px) + var(--ns-fab-gap) + env(safe-area-inset-bottom, 0px));
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: var(--ns-fab-h);
    padding: 0 20px 0 16px;
    border: 0;
    border-radius: 9999px;
    background: #10b981; /* 与 .btn-success 同色 */
    color: #fff;
    font-size: 15px;
    font-weight: 600;
    line-height: 1;
    /* 阴影兼顾「浮起感」与低端机合成成本（不用 filter/backdrop-filter） */
    box-shadow: 0 6px 16px rgba(16, 185, 129, 0.35), 0 2px 6px rgba(15, 23, 42, 0.18);
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    transition: transform 0.12s ease-out, background-color 0.15s;
  }

  .ns-fab-ico { width: 20px; height: 20px; flex: none; }
  .ns-fab-txt { letter-spacing: 0.02em; white-space: nowrap; }
  .ns-fab:active { background: #047857; transform: scale(0.96); }
  .ns-fab:focus-visible { outline: 3px solid #93c5fd; outline-offset: 2px; }

  /* 登录提交按钮：产物里实测只有 35px 高，低于 iOS 44px 最小触达尺寸 */
  .ns-login-submit { min-height: 48px; font-size: 15px; }
}


/* ------------------- R13：标签贴紧控件 / 字段间留白 / 控件按内容宽（@hw210） ------------------- */
/* 需求：① 每个字段「名称 ↔ 输入框/选择框」的间距尽量缩小；②「字段 ↔ 字段」之间留稍大间距；
   ③ 不要求上下各行完全对齐 —— 只要每行左侧第一个字段左对齐即可，其余字段与框体无需对齐，
      行内多余空白统一留在最右侧；④ 输入框/选择框宽度只保证内容（选项文字）完整显示，不过宽；
      ⑤ 「项目内容」框保持不变。
   实测（1440 视口，改前）：`.ns-fields` 是「固定列宽网格」（`repeat(auto-fill, 272px)`），
   标签盒恒 76px 而各标签文字只有 33~66px ⇒「标签文字右缘 → 控件左缘」在 **18~51px** 之间乱跳
   （budget 18 / priority 51 / status 40 / customerName 40 / ownerName 40 / …），
   控件又被统一钉在 120px（与"够显示就行"无关），日期框则撑满剩余宽度（188px）。
   改法：把 `.ns-fields` 从「固定列宽网格」换成「内容宽流式换行（flex + wrap）」——
   固定列宽本来就是"跨行对齐"的代价，而需求 ③ 明确不要跨行对齐，于是：
     · 标签盒 = 内容宽（`width:auto`）⇒「标签 → 控件」恒为 4px，不再随标签长短浮动；
     · 每一项按自身内容宽排列，放不下就**整项换行** ⇒ 行内多余空白全部落在最右侧；
     · 选择框 `width:auto` ⇒ 浏览器按最长选项（含「（未选择）」占位项）自适应；
       数字/文本输入框给一个"够显示"的窄宽；日期框按 `yyyy-mm-dd` 自适应。
   ⚠️ R8 的 `grid-template-columns` 与 R8/R12 的 `grid-column` 声明在 flex 下**自动失效**，
      此处保留原文仅作历史（不再参与布局）；「项目内容」的"独占整行"改由 `flex: 1 1 100%` 承担。 */

.ns-fields {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: flex-start;   /* 从左往右依次排列，多余空白统一留给最右侧 */
  gap: 12px 26px;                /* 行间距 12px / 字段间距 26px（都明显大于标签↔控件的 4px） */
  min-width: 0;
}

/* 单项：按内容宽、不收缩 —— 放不下时整项换行，而不是把控件挤变形 */
.ns-f {
  flex: 0 0 auto;
  gap: 4px;                      /* 标签 ↔ 控件：最小间距 */
  width: auto;
  max-width: 100%;
  min-width: 0;
}

/* 标签盒 = 文字宽（覆盖 R11 的 76px 定宽）⇒ 间距不再随标签长短浮动 */
.ns-fields .ns-f > label { width: auto; }

/* 项目内容：独占整行（原 grid-column:1/-1 在 flex 下失效，改由 flex-basis 承担） */
.ns-f-projectOverview { flex: 1 1 100%; width: 100%; }

/* 丢单区块：允许收缩（窄屏时让内部 flex-wrap 生效，避免横向溢出） */
.ns-f-lost { flex: 0 1 auto; max-width: 100%; }

/* 控件宽度：只保证内容完整显示，不追求铺满 */
.ns-f-budget > div > .input { width: 104px; }                        /* 数字：够显示金额即可 */
.ns-f-priority > div > .input,
.ns-f-status > div > .input,
.ns-f-owner_name > div > .input { width: auto; min-width: 104px; }   /* 下拉：按最长选项自适应 */
.ns-f-customerName .ns-unit-inp { flex: 0 0 160px; }                 /* 单位：够显示常见简称 */
.ns-f > div > .ns-cal { width: 136px; }                              /* 日期框：够显示 yyyy-mm-dd */

/* 窄屏：一字段一行（沿用 207/208 以来的移动端单列取舍），标签↔控件仍为 4px */
@media (max-width: 767px) {
  .ns-fields { gap: 12px 26px; }
  .ns-f { flex: 0 0 100%; }
  .ns-f-lost { flex: 0 1 100%; }
}

/* =====================================================================================
   R14：条件块（「丢单原因 / 中标方」「公示 / 公示日期」）与普通字段视觉统一（@hw212）
   -------------------------------------------------------------------------------------
   问题：两个条件块内部的控件用的是「更小的一档」（!py-1 / !text-xs = 10.5px），块高只有
         23~25px，而普通字段的控件高 33.5~34px、字号 12.25px；`.ns-f` 又是垂直居中/顶端
         对齐 ⇒ 条件块的标签与内联小标题整体比同一排的其它字段「高约 5px」，字号更小、
         颜色更深（gray-500 vs gray-400）。
   做法：① 两个条件块显式 `align-items:center`（原 R11 给公示写的 `flex-start` 是配合当时的
           「定宽标签 + 标签 pt-1.5」方案，标签改按内容宽后已不需要）；
         ② 分段按钮组拉到与 `.input` 同高 34px、字号与 `.input` 一致的 .875rem（12.25px）；
         ③ 其余字号/行高/内边距全部在 bundle 里改回 `.input`/标签的标准档（@hw212 的 7 处替换）。
   注：`.ns-f-lost` 本就从 `.ns-f` 继承 `align-items:center`，这里显式写出来是为了避免
       继承链被后续改动带偏；`.ns-f-publicity` 则必须显式覆盖 R11 的 `flex-start`。
   ------------------------------------------------------------------------------------- */
.ns-f-lost,
.ns-f-publicity { align-items: center; }

.ns-f-publicity > div > .inline-flex { height: 34px; }
.ns-f-publicity > div > .inline-flex > button {
  padding-top: 0;
  padding-bottom: 0;
  font-size: .875rem;
  line-height: 1.25rem;
}
