/*@import '/_content/Microsoft.FluentUI.AspNetCore.Components/css/reboot.css';*/

/* DataGrid 定义选中行高光 */
.highlighted {
    background-color: var(--highlight-bg);
    color: #343434;
}

/* MainLayout 定义Content样式（原类选择器：content） */
.body-content {
    align-self: stretch;
    height: calc(100dvh - 80px) !important;
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
}

/* EditPanelLayout 定义主布局样式*/
.panel-content {
    height: calc(100dvh - 142px) !important;
    display: flex;
}

.panel-tab-content {
    padding: 10px 20px;
    height: calc(100dvh - 186px);
    overflow: auto;
}

/* 重写样式 */
/* Tab 重写内容区域Padding */
.fluent-tab-panel {
    padding: 0 !important;
}

/* DataGrid 重写标题背景色 */
.fluent-data-grid tr[row-type=sticky-header] > th {
    background-color: var(--colorNeutralBackground1) !important;
}

/* RadioGroup 重写边距 */
fluent-radio-group {
    margin: 0!important
}

.fluent-paginator {
    margin: 0 !important;
    padding: 0 !important;
}

body {
    --body-font: "Segoe UI Variable", "Segoe UI", sans-serif;
    font-family: var(--body-font);
    font-size: var(--type-ramp-base-font-size);
    line-height: var(--type-ramp-base-line-height);
    margin: 0;
}

.navmenu-icon {
  display: none;
}

.main {
  min-height: calc(100dvh - 80px);
  color: var(--neutral-foreground-rest);
  align-items: stretch !important;
}

.nav {
  align-self: stretch;
  height: calc(100dvh - 80px) !important;
  display: flex;
}

.content {
  padding: 0.5rem 1.5rem;
  align-self: stretch !important;
  width: 100%;
}

.manage {
  width: 100dvw;
}

.fluent-layout-item[area="footer"] {
  background: var(--neutral-layer-4);
  color: var(--neutral-foreground-rest);
  align-items: center;
  padding: 10px 10px;
}

  .fluent-layout-item[area="footer"] fluent-link {
    color: var(--neutral-foreground-rest);
    text-decoration: none;
  }

    .fluent-layout-item[area="footer"] fluent-link:focus {
      outline: 1px dashed;
      outline-offset: 3px;
    }

    .fluent-layout-item[area="footer"] fluent-link:hover {
      text-decoration: underline;
    }


.alert {
  border: 1px dashed var(--accent-fill-rest);
  padding: 5px;
}


#blazor-error-ui {
  background: lightyellow;
  bottom: 0;
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
  display: none;
  left: 0;
  padding: 0.6rem 1.25rem 0.7rem 1.25rem;
  position: fixed;
  width: 100%;
  z-index: 1000;
  margin: 20px 0;
}

  #blazor-error-ui .dismiss {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
  }

.blazor-error-boundary {
  background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
  padding: 1rem 1rem 1rem 3.7rem;
  color: white;
}

  .blazor-error-boundary::before {
    content: "An error has occurred. "
  }

.loading-progress {
  position: relative;
  display: block;
  width: 8rem;
  height: 8rem;
  margin: 20vh auto 1rem auto;
}

  .loading-progress circle {
    fill: none;
    stroke: #e0e0e0;
    stroke-width: 0.6rem;
    transform-origin: 50% 50%;
    transform: rotate(-90deg);
  }

    .loading-progress circle:last-child {
      stroke: #1b6ec2;
      stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
      transition: stroke-dasharray 0.05s ease-in-out;
    }

.loading-progress-text {
  position: absolute;
  text-align: center;
  font-weight: bold;
  inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
}

  .loading-progress-text:after {
    content: var(--blazor-load-percentage-text, "Loading");
  }

code {
  color: #c02d76;
}

@media (max-width: 600px) {
  .header-gutters {
    margin: 0.5rem 3rem 0.5rem 1.5rem !important;
  }

  [dir="rtl"] .header-gutters {
    margin: 0.5rem 1.5rem 0.5rem 3rem !important;
  }

  .main {
    flex-direction: column !important;
    row-gap: 0 !important;
  }

  nav.sitenav {
    width: 100%;
    height: 100%;
  }

  #main-menu {
    width: 100% !important;
  }

    #main-menu > div:first-child:is(.expander) {
      display: none;
    }

  .navmenu {
    width: 100%;
  }

  #navmenu-toggle {
    appearance: none;
  }

    #navmenu-toggle ~ nav {
      display: none;
    }

    #navmenu-toggle:checked ~ nav {
      display: block;
    }

  .navmenu-icon {
    cursor: pointer;
    z-index: 10;
    display: block;
    position: absolute;
    top: 15px;
    left: unset;
    right: 20px;
    width: 20px;
    height: 20px;
    border: none;
  }

  [dir="rtl"] .navmenu-icon {
    left: 20px;
    right: unset;
  }
}

/* ============ 横向标签带：MenuBar 顶部菜单条 与 MainLayout 底部页签条 共用 ============ */
/* 活动态下划线一律画在【外层元素】上：FluentButton 是 Web Component，
   内部 shadow DOM 固化了字体/颜色，从外部改不动，指示器只能落在宿主或外层 div 上。 */
.tab-strip {
  display: flex;
  align-items: stretch;
  gap: 2px;
  flex: 0 0 auto;
}

/* 单个标签 */
.tab-strip-item {
  display: flex;
  align-items: center;
  border-bottom: 2px solid transparent;
}

.tab-strip-item.is-active {
  border-bottom-color: var(--colorBrandBackground);
}

.tab-strip-btn {
  white-space: nowrap;
  font-size: var(--fontSizeBase300);
  min-width: 0;
}

/* 活动标签加粗 + 品牌色（best-effort：若 shadow DOM 内部固化了字体，则仅剩上方下划线生效） */
.tab-strip-item.is-active .tab-strip-btn {
  font-weight: var(--fontWeightSemibold);
  color: var(--colorBrandForeground1);
}

/* ==================== MenuBar 专属：容器装饰 ==================== */
.menu-bar {
  padding: 0 6px;
  background-color: var(--colorNeutralBackground2);
  overflow-x: auto;
  overflow-y: hidden;
}

/* ==================== 排产看板（ScheduleBoardView）：横向并排的中心列（左日期轴 / 右工单块） ==================== */
/* 版面：各工作中心横向并排成列（列宽固定，不铺满整宽）；列内左 = 只读日期轴、右 = 工单块堆叠。
   两栏共用同一 scale 与同一纵向起点，块首尾相接且无间隙 ⇒ 块边界与左侧刻度严格对齐。 */
.sb-board {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 22px;
  padding: 6px 4px 14px;
  overflow-x: auto;

  /* 看板专属高亮色 —— ⚠️ 刻意【不】复用 DataGrid 的 --highlight-bg：那个变量的语义是「表格选中行」，
     与看板块命中是两码事，耦合在一起会导致以后想单独调看板配色却动到表格。
     变量挂在本容器上（只作用于看板子树，不污染 :root），要调色只改这三个值即可。 */
  --sb-match-background: #fff2b8;
  --sb-match-foreground: #1f1f1f;
  --sb-match-border: #d9a400;
}

/* 一个工作中心 = 一列：列宽固定（左轴 78 + 右块 168），不随容器拉伸 */
.sb-column {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  gap: 4px;
  width: 246px;
}

/* 「未分配」列：没有产能轴，宽度收缩为块宽，用虚线隔开 */
.sb-column-unassigned {
  width: auto;
  margin-left: 14px;
  padding-left: 14px;
  border-left: 1px dashed var(--colorNeutralStroke1);
}

.sb-column-head {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.sb-column-title,
.sb-column-meta {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.sb-column-title {
  font-weight: 600;
}

.sb-column-meta {
  font-size: 12px;
  color: var(--colorNeutralForeground3);
}

/* 列体：高度由组件内联下发（= max(总产能, 排产总量) × scale + 列尾投放带） */
.sb-column-body {
  display: flex;
  align-items: stretch;
  position: relative;
}

/* 左栏：日期轴。刻度用 top 像素定位 —— 定位点就是该日的起点，与右侧块的分界线落在同一条 y 上。
   刻度读数 = 日期文字的【顶边】；日界线另由 .sb-tick::before 的 1px 顶线画出（两者同在 y=0，严格重合）。 */
.sb-axis {
  position: relative;
  flex: 0 0 78px;
  width: 78px;
}

.sb-tick {
  position: absolute;
  left: 0;
  width: 100%;
}

/* 日界线：1px 顶线，落在 .sb-tick 的定位点上（= 该日起点，与右侧块的分界同一 y）。
   ⚠️ 必须用【绝对定位伪元素】而不是 border-top —— 伪元素脱离文档流、不占高度、不挤压日期文字，
   加线前后文字位置零偏移；改用 border-top 会让盒子整体下移 1px，标签顶边就不再等于日界。
   画在所有刻度格上（含因过密而未显示文字的格）：线表达「日界」本身，与文字是否画得下无关。
   颜色 = .sb-block 的边框色（BrandStroke1）：线与块的顶边接成同一条，视觉上把「轴」和「块」串起来。 */
.sb-tick::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 1px;
  background-color: var(--colorBrandStroke1);
}

.sb-tick-date,
.sb-tick-cap {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  line-height: 16px;
}

.sb-tick-date {
  color: var(--colorNeutralForeground1);
}

.sb-tick-cap {
  color: var(--colorNeutralForeground3);
}

/* 右栏：工单块堆叠。块高由组件内联下发（= 排产数量 × scale），块间无间隙以保住刻度对齐 */
.sb-blocks {
  display: flex;
  flex-direction: column;
  flex: 0 0 168px;
  width: 168px;
}

/* 工单块：块内只放 销售订单号 / 工单明细号 / 数量 / 交期 四行。
   ⚠️ 块高严格 = 排产数量 × scale（组件内联下发，不设 min-height，否则块与刻度错位），
   故行数超出块高时由 overflow:hidden 从【末行】开始裁 —— 查看全部信息请用悬停提示。 */
.sb-block {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: 100%;
  overflow: hidden;
  padding: 5px 8px;
  border: 1px solid var(--colorBrandStroke1);
  border-radius: 4px;
  background-color: var(--colorBrandBackground2);
  cursor: grab;
}

.sb-block-unassigned {
  border-style: dashed;
  border-color: var(--colorNeutralStroke1);
  background-color: var(--colorNeutralBackground3);
}

.sb-block-inner {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.sb-block-line {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  line-height: 16px;
  color: var(--colorNeutralForeground1);
}

.sb-block-qty {
  font-weight: 600;
}

/* 命中右侧树所选订单的块：换背景 / 边框 / 文字色（比表格行高亮多一个描边，块密集堆叠时更跳得出来）。
   ⚠️ 只改颜色，不动任何尺寸（padding / min-height / border-width 都不能碰）—— 块高必须严格 = 数量 × scale，
   否则该块之后的全部块与左侧日期刻度会一起错位。
   配色变量定义在 .sb-board 上（见该规则内注释），主题无关：背景是浅黄、文字钉深色，故深浅主题都可读。 */
.sb-block.sb-match {
  background-color: var(--sb-match-background);
  border-color: var(--sb-match-border);
}

.sb-block.sb-match .sb-block-line {
  color: var(--sb-match-foreground);
}

/* 列尾投放区：纵向排在最后，flex 撑满剩余高度，承接「追加到本列末尾」 */
.sb-tail {
  box-sizing: border-box;
  flex: 1 1 auto;
  min-height: 18px;
  border-radius: 4px;
}

/* 落点预示：拖动悬停到某块 / 列尾投放区时，顶部粗线 = 「松手后插到它之前」
   （顺序由 ScheduleItemService.Reorder 决定：块拖到 B 上即插到 B 前；插到 B 后就拖到 B 的下一个块，或拖到列尾） */
.sb-block[dragged-over],
.sb-tail[dragged-over] {
  /* 覆盖 FluentUI 对 [dragged-over] 的全局默认：opacity .6 让整块发虚、blinker 闪烁干扰视线，
     且它把前景色改成 Foreground4（浅色主题下块内文字几乎看不见） */
  opacity: 1;
  animation: none;
  color: var(--colorNeutralForeground1);
}

.sb-block.sb-insert {
  box-shadow: inset 0 3px 0 var(--colorBrandStroke1);
  background-color: var(--colorBrandBackground2Hover);
}

.sb-tail.sb-insert {
  box-shadow: inset 0 3px 0 var(--colorBrandStroke1);
}

/* ====== 表单提交加载态：静态 SSR 下替代 FluentButton 的 Loading 参数 ======
   Login 等 Account 页面恒为静态 SSR（该目录 _Imports.razor 带 [ExcludeFromInteractiveRouting]），
   页面没有 Blazor 电路 ⇒ FluentButton 的 Loading / OnClick 永远不会翻转，点击后到表单 POST
   返回之前毫无反馈。改由 wwwroot/js/form-submit-loading.js 在 submit 时给被点按钮加 .btn-loading，
   这里只负责「按需把转圈显示出来」——按钮内需放 <span class="btn-spinner" aria-hidden="true"></span>，
   默认 display:none ⇒ 未提交时对现有布局零影响（display:none 的 flex 项不占位、不产生 gap）。 */
.btn-spinner {
  display: none;
  flex: none;
  align-self: center;
  vertical-align: middle;
  box-sizing: border-box;
  width: 15px;
  height: 15px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  opacity: 0.9;
  animation: btn-spinner-rotate 0.6s linear infinite;
}

fluent-button.btn-loading {
  pointer-events: none;
  opacity: 0.85;
}

fluent-button.btn-loading .btn-spinner {
  display: inline-block;
}

@keyframes btn-spinner-rotate {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

/* ==================== 电路控制台：会话监测页的整页控制台视图 ==================== */
/* 刻意不模拟真实终端配色：全部走 Fluent 主题 token ⇒ 深色主题自动反白、浅色主题白底黑字。 */
.circuit-console {
  height: 100%;
  overflow: auto;
  padding: 8px 12px;
  background-color: var(--colorNeutralBackground1);
  color: var(--colorNeutralForeground1);
  font-family: var(--fontFamilyMonospace);
  font-size: var(--fontSizeBase200);
  line-height: 1.5;
}

.circuit-console-line {
  display: flex;
  gap: 8px;
  white-space: pre-wrap;
  word-break: break-word;
}

.circuit-console-time {
  flex: none;
  color: var(--colorNeutralForeground3);
  user-select: none;
}

.circuit-console-text {
  flex: 1 1 auto;
  min-width: 0;
}

/* EF Core 的数据库日志（含真正的 SQL）单独着色 ⇒ 一眼看出每一步的读写 */
.circuit-console-line.is-db .circuit-console-text {
  color: var(--colorBrandForeground1);
}

.circuit-console-line.is-error .circuit-console-text,
.circuit-console-line.is-error .circuit-console-time {
  color: var(--colorPaletteRedForeground1);
}

.circuit-console-note {
  color: var(--colorNeutralForeground3);
  font-style: italic;
}
