/* ============================================================
   app.css —— 布局与组件
   手机优先：<768px 时导航变成底部固定标签栏。
   ============================================================ */

/* ---------- 顶栏 ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: var(--gap);
  height: var(--topbar-h);
  padding: 0 var(--gap);
  background: var(--panel);
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: .4em; font-weight: 600; white-space: nowrap; }
.brand .logo { font-size: 1.15em; }
.brand-text { font-size: 1em; }

.nav { display: flex; gap: .2em; flex: 1; }
.nav-item {
  padding: .35em .8em;
  border-radius: var(--radius);
  color: var(--fg-2);
  font-size: .95em;
  white-space: nowrap;
}
.nav-item:hover { background: var(--panel-2); color: var(--fg); text-decoration: none; }
.nav-item.active {
  background: var(--accent-bg);
  color: var(--accent);
  font-weight: 600;
}

.icon-btn {
  border: 1px solid var(--border-2);
  background: var(--panel);
  border-radius: var(--radius);
  padding: .3em .55em;
  line-height: 1.2;
  font-size: 1em;
}
.icon-btn:hover { border-color: var(--accent); }

/* ---------- 视图容器 ---------- */
.view {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: var(--gap);
}

.page-head { margin-bottom: var(--gap); }
.page-head h1 { margin-bottom: .15em; }
.page-head .sub { color: var(--fg-2); font-size: .95em; }

/* ---------- 首页仪表盘 ---------- */
.dash-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--gap);
}

.todo-list { list-style: none; padding: 0; margin: 0; }
.todo-item {
  display: flex;
  align-items: flex-start;
  gap: .6em;
  padding: .5em 0;
  border-bottom: 1px solid var(--border);
}
.todo-item:last-child { border-bottom: 0; }
.todo-item .dot {
  flex: 0 0 auto;
  width: .6em; height: .6em;
  margin-top: .5em;
  border-radius: 50%;
  background: var(--fg-3);
}
.todo-item.overdue .dot { background: var(--danger); }
.todo-item.today   .dot { background: var(--warn); }
.todo-item.soon    .dot { background: var(--accent); }
.todo-item .main { flex: 1; min-width: 0; }
.todo-item .what { font-weight: 500; }
.todo-item .meta { font-size: .85em; color: var(--fg-2); }
.todo-item .meta .overdue-text { color: var(--danger); font-weight: 600; }

.quick-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .6em;
}
.quick-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .3em;
  padding: .9em .5em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-2);
  color: var(--fg);
  text-align: center;
  font-size: .95em;
}
.quick-btn:hover { border-color: var(--accent); background: var(--accent-bg); text-decoration: none; }
.quick-btn .ico { font-size: 1.5em; line-height: 1; }

/* 备份提醒 */
.backup-banner {
  display: flex;
  align-items: center;
  gap: .7em;
  padding: .7em .9em;
  border-radius: var(--radius);
  background: var(--warn-bg);
  border: 1px solid var(--warn);
  color: var(--warn);
  margin-bottom: var(--gap);
  font-size: .95em;
}
.backup-banner .grow { flex: 1; }

/* ---------- 实验列表 ---------- */
.exp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--gap);
}
.exp-card {
  display: block;
  padding: var(--gap);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  color: var(--fg);
  box-shadow: var(--shadow);
}
.exp-card:hover { border-color: var(--accent); text-decoration: none; }
.exp-card .name { font-weight: 600; margin-bottom: .2em; }
.exp-card .desc { font-size: .9em; color: var(--fg-2); }
.exp-card .tags { margin-top: .6em; display: flex; flex-wrap: wrap; gap: .3em; }

/* ---------- 实验详情：章节 ---------- */
.sec { margin-bottom: var(--gap); }
.sec > h2 {
  display: flex;
  align-items: center;
  gap: .5em;
  padding-bottom: .3em;
  border-bottom: 2px solid var(--border);
  margin-bottom: .7em;
}
.sec > h2 .n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.6em; height: 1.6em;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: .8em;
  flex: 0 0 auto;
}

/* 步骤列表 */
ol.steps { padding-left: 1.4em; }
ol.steps > li { margin-bottom: .6em; }
ol.steps > li > .why { font-size: .88em; color: var(--fg-2); }
ol.steps > li > .careful {
  display: block;
  font-size: .88em;
  color: var(--warn);
  background: var(--warn-bg);
  border-radius: var(--radius-sm);
  padding: .3em .5em;
  margin-top: .25em;
}

/* 计算过程对账 */
.calc-steps { list-style: none; padding: 0; margin: 0; font-size: .93em; }
.calc-steps li {
  display: flex;
  gap: .6em;
  padding: .35em 0;
  border-bottom: 1px dashed var(--border);
}
.calc-steps li:last-child { border-bottom: 0; }
.calc-steps .label { flex: 0 0 40%; color: var(--fg-2); }
.calc-steps .detail { flex: 1; font-family: var(--mono); font-size: .95em; }

/* ---------- 结果横幅 ---------- */
.verdict {
  display: flex;
  align-items: center;
  gap: .6em;
  padding: .7em .9em;
  border-radius: var(--radius);
  margin: .6em 0;
  font-weight: 600;
}
.verdict-pass { background: var(--ok-bg);     color: var(--ok); }
.verdict-warn { background: var(--warn-bg);   color: var(--warn); }
.verdict-fail { background: var(--danger-bg); color: var(--danger); }

/* ---------- 日记 ---------- */
.diary-list { list-style: none; padding: 0; margin: 0; }
.diary-item {
  display: block;
  padding: .7em .9em;
  border-bottom: 1px solid var(--border);
  color: var(--fg);
}
.diary-item:hover { background: var(--panel-2); text-decoration: none; }
.diary-item .date { font-family: var(--mono); font-size: .88em; color: var(--fg-2); }
.diary-item .title { font-weight: 600; }

/* 日记条目下的操作按钮：默认只露「打开 / 导出▾ / 删除」三个，
   长图·Word·Markdown·CSV 收进「导出▾」，避免 6 个按钮挤成两三行、
   还紧挨着「删除」容易误点。 */
.diary-acts {
  margin-top: .35em;
  display: flex;
  gap: .4em;
  flex-wrap: wrap;
  align-items: flex-start;
}
.diary-more > summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
}
.diary-more > summary::-webkit-details-marker { display: none; }
.diary-more[open] > summary { border-color: var(--accent); color: var(--accent); }
.diary-more-body {
  display: flex;
  flex-wrap: wrap;
  gap: .4em;
  margin-top: .4em;
  padding: .5em;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel-2);
}

.diary-block {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: .7em;
  background: var(--panel);
}
.diary-block .blk-head {
  display: flex;
  align-items: center;
  gap: .5em;
  padding: .35em .6em;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
  font-size: .85em;
  color: var(--fg-2);
  border-radius: var(--radius) var(--radius) 0 0;
}
.diary-block .blk-body { padding: .6em .8em; }
.diary-block .blk-body:empty::after { content: "（空）"; color: var(--fg-3); }

/* ---------- 日程 / 日历 ---------- */
.cal-grid {
  display: grid;
  /* 必须是 minmax(0,1fr) 而不是 1fr：
     1fr = minmax(auto,1fr)，列的最小宽度取"内容最小宽度"，
     而事件标签 .evt 是 nowrap，长事件文字会把该列撑宽，
     7 列总宽超出卡片后被 overflow:hidden 裁掉右侧（周日整列既看不见也点不到）。 */
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.cal-head {
  background: var(--panel-2);
  text-align: center;
  font-size: .82em;
  padding: .35em 0;
  color: var(--fg-2);
  font-weight: 600;
}
.cal-cell {
  background: var(--panel);
  min-height: 76px;
  min-width: 0;                 /* 允许格子在窄列里收缩，不被内容顶宽 */
  padding: .3em .35em;
  font-size: .82em;
  display: flex;
  flex-direction: column;
  gap: .15em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color .12s ease;
}
.cal-cell:hover { background: var(--accent-bg); }
.cal-cell:active { background: var(--accent-bg); }
.cal-cell.other-month { background: var(--panel-2); color: var(--fg-3); cursor: default; }
.cal-cell.today { outline: 2px solid var(--accent); outline-offset: -2px; }
.cal-cell.selected { background: var(--accent-bg); outline: 2px solid var(--accent); outline-offset: -2px; }
.cal-cell .daynum { font-weight: 600; font-size: .95em; }
.cal-cell .evt {
  min-width: 0;                 /* 配合列的 minmax(0,1fr)：超长文字走省略号，而不是把列撑宽 */
  border-radius: 3px;
  padding: 0 .25em;
  background: var(--accent-bg);
  color: var(--accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cal-cell .evt.overdue { background: var(--danger-bg); color: var(--danger); }
.cal-cell .evt.done { background: var(--panel-2); color: var(--fg-3); text-decoration: line-through; }

/* 月历标题行右侧的导航区（上月 / 月份 / 下月 / 回本月） */
.cal-nav {
  display: flex;
  gap: .3em;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.cal-month-label { flex-shrink: 0; min-width: 7em; }

@media (max-width: 600px) {
  /* 手机：7 列在窄屏收紧间距与字号，保证整月一屏可见、每格都点得到 */
  .cal-grid { gap: 1px; }
  .cal-head { font-size: .76em; padding: .3em 0; }
  .cal-cell { min-height: 46px; padding: .2em .25em; font-size: .76em; gap: .1em; }
  .cal-cell .evt { font-size: .92em; padding: 0 .2em; }
  /* 导航整行铺开、四个控件均匀分布，按钮文字不再被挤成两行 */
  .cal-nav { flex: 1 1 100%; justify-content: space-between; gap: .25em; }
  .cal-month-label { flex: 1; min-width: 0; }
}

/* ============================================================
   试件台账：手机上把表格变成「一条一张卡片」
   为什么：这张表有 5 列（编号/强度等级/成型日期/计划龄期/操作），
   自然宽度约 600px，而手机只有 ~375px，于是最后一列（删除按钮）
   被推出屏幕，得左右滑才看得到、还容易点错。
   这里**不缩字号**（缩了更难认），改成竖排卡片：字段名靠左、值靠右，
   字反而更大。桌面端（>600px）完全不受影响，仍是普通表格。
   配套：views2.js 里 table-wrap 上的 .table-cards 与每个 td 的 data-label。
   ============================================================ */

@media (max-width: 600px) {
  .table-cards { overflow-x: visible; }

  .table-cards table.data,
  .table-cards tbody { display: block; width: 100%; }
  .table-cards thead { display: none; }
  .table-cards table.data { font-size: 1em; }

  .table-cards table.data tr {
    display: block;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--panel);
    padding: .6em .7em;
    margin-bottom: .6em;
  }
  .table-cards table.data tr:last-child { margin-bottom: 0; }

  .table-cards table.data td {
    display: flex;
    align-items: baseline;
    gap: .6em;
    width: 100%;
    box-sizing: border-box;
    border: 0;
    padding: .18em 0;
  }
  /* 字段名由 data-label 提供，不占额外 DOM */
  .table-cards table.data td::before {
    content: attr(data-label);
    flex: 0 0 4.6em;
    color: var(--fg-3);
    font-size: .88em;
  }

  /* 第一格（编号）当卡片标题：不显示字段名，加大加粗 */
  .table-cards table.data td:first-child {
    font-size: 1.1em;
    font-weight: 600;
    padding: 0 0 .35em;
  }
  .table-cards table.data td:first-child::before { content: none; }

  /* 操作格：按钮单独一行、靠右，并放大到手指好点 */
  .table-cards table.data td:last-child {
    justify-content: flex-end;
    padding: .5em 0 0;
  }
  .table-cards table.data td:last-child::before { content: none; }
  .table-cards table.data td:last-child .btn { min-height: 40px; padding: .45em 1.1em; }
}

/* ============================================================
   电通量录入：13 个电流读数框
   桌面端每个框 68px 排成一行没问题；手机上表头是 nowrap、输入框又各占 68px，
   整张表会被撑到 ~440px（屏只有 ~375px），要左右滑才看得到表头。
   这里让表头可以换行、输入框收窄、单元格内边距压小，整张表就落回屏宽内
   （每行 5 个，13 个分 3 行）。配套：views.js 里的 .flux-table/.flux-cell/.flux-in。
   ============================================================ */

.flux-cell { display: flex; gap: 2px; flex-wrap: wrap; }
.flux-in { width: 68px; }

@media (max-width: 600px) {
  /* 写成 table.data.flux-table 是为了压过 base.css 里 table.data th 的 nowrap */
  table.data.flux-table th { white-space: normal; }
  table.data.flux-table th,
  table.data.flux-table td { padding: .2em .25em; }
  .flux-in { width: 54px; }
  .flux-cell { gap: 3px; }
  /* 数字框右侧的上下小箭头在手机上点不中、还白占 ~15px，收窄后更要挤，隐藏掉 */
  .flux-in::-webkit-outer-spin-button,
  .flux-in::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
}

/* ============================================================
   块编辑器（日记用）—— 像 Obsidian 那样所见即所得
   ============================================================ */

.editor-toolbar {
  /* 不要做成 sticky（原来写的是 position:sticky; top:var(--topbar-h); z-index:20）。
     原因：sticky 元素会脱离原位置去"粘"在顶栏下面，从而盖住后面正在滚动的日记块；
     这个工具栏在手机上有 ~170px 高，一盖就是一大片，看起来像 Excel 的冻结窗格。
     改为随页面正常滚动，谁都不会被挡。 */
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .5em .6em;
  margin-bottom: .7em;
}

.editor { display: flex; flex-direction: column; gap: .6em; }

.editor-block {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
  overflow: hidden;
}
.editor-block:focus-within { border-color: var(--accent); }

.editor-block-head {
  display: flex;
  align-items: center;
  gap: .4em;
  padding: .25em .5em;
  background: var(--panel-2);
  border-bottom: 1px solid var(--border);
  font-size: .85em;
  color: var(--fg-2);
}
.editor-block-head .btn[disabled] { opacity: .3; }
.editor-block-head .blk-title { font-weight: 600; font-size: .9em; }
/* ↑↓✕ 三个按钮：原来间距只有 .2em、字号又被 head 的 .8em 带小，
   手机上只有约 21×23px 且几乎贴在一起，✕ 紧挨 ↓ 极易误删。
   这里加大间距，并在 ✕ 前再留一点空隙；尺寸由下面「手机点按目标」统一抬到 36px。 */
.editor-block-head .blk-acts { margin-left: auto; display: flex; gap: .3em; }
.editor-block-head .blk-acts .btn-del { margin-left: .3em; }

.editor-block-body { padding: .5em .6em; }
.editor-block-body textarea { min-height: 4.5em; }
.editor-block-body img { cursor: zoom-in; }

/* 只读展示（日记详情页）用的照片宽度 */
.diary-block .blk-body img { cursor: zoom-in; }

@media (max-width: 767px) {
  .editor-toolbar { padding: .4em; }
  /* 原来是 .8em：会把块标题和 ↑↓✕ 一起带小，手机上点不准，这里抬回去 */
  .editor-block-head { font-size: .95em; }
  /* 手机上把宽度档位按钮做得更好点 */
  .editor-block-body .btn-sm { padding: .45em .8em; }
}

/* ============================================================
   图片灯箱（点开看大图，可缩放拖动）
   手机上没有鼠标滚轮，所以用「点按放大 / 双指捏合」两种方式。
   ============================================================ */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(0, 0, 0, .92);
  display: flex;
  flex-direction: column;
  touch-action: none;          /* 自己处理手势，别让浏览器滚动页面 */
  overscroll-behavior: contain;
}
.lightbox-stage {
  flex: 1;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
}
.lightbox-stage:active { cursor: grabbing; }
.lightbox-stage img {
  max-width: none;
  max-height: none;
  transform-origin: center center;
  user-select: none;
  -webkit-user-drag: none;
  will-change: transform;
}
.lightbox-bar {
  display: flex;
  align-items: center;
  gap: .4em;
  padding: .5em .7em;
  background: rgba(0, 0, 0, .6);
  color: #fff;
  flex-wrap: wrap;
  font-size: .9em;
}
.lightbox-bar .grow { flex: 1; }
.lightbox-bar button {
  background: rgba(255, 255, 255, .12);
  border: 1px solid rgba(255, 255, 255, .3);
  color: #fff;
  border-radius: var(--radius-sm);
  padding: .35em .7em;
  font-size: 1em;
}
.lightbox-bar button:hover { background: rgba(255, 255, 255, .22); }
.lightbox-hint {
  text-align: center;
  color: rgba(255, 255, 255, .6);
  font-size: .8em;
  padding: 0 0 .5em;
}

@media (max-width: 767px) {
  .lightbox-bar { font-size: .85em; padding: .4em .5em; }
  .lightbox-bar button { padding: .45em .8em; }   /* 手指点得中 */
}

/* ---------- 规范速查 ---------- */
.std-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: .5em;
  align-items: center;
  margin-bottom: var(--gap);
}
.std-toolbar input[type="search"] {
  flex: 1;
  min-width: 180px;
  padding: .45em .6em;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  background: var(--panel);
}
.std-list { display: flex; flex-direction: column; gap: .6em; }
.std-row {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: .7em .9em;
  background: var(--panel);
}
.std-row .no { font-family: var(--mono); font-weight: 600; }
.std-row .nm { font-weight: 500; }
.std-row .meta { font-size: .86em; color: var(--fg-2); margin-top: .2em; }
.std-row .acts { margin-top: .5em; display: flex; flex-wrap: wrap; gap: .4em; }

/* ---------- 提示条 ---------- */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(var(--gap) + 64px);
  transform: translateX(-50%);
  z-index: 100;
  max-width: min(90vw, 460px);
  padding: .6em 1em;
  border-radius: var(--radius);
  background: var(--fg);
  color: var(--bg);
  font-size: .93em;
  box-shadow: var(--shadow);
}

.storage-warning {
  max-width: var(--maxw);
  margin: var(--gap) auto 0;
  padding: .8em 1em;
  border-radius: var(--radius);
  background: var(--danger-bg);
  border: 1px solid var(--danger);
  color: var(--danger);
  font-size: .93em;
}

/* ============================================================
   手机：导航变底部固定标签栏
   ============================================================ */
@media (max-width: 767px) {
  :root { --topbar-h: 46px; }

  .topbar {
    justify-content: space-between;
  }
  .nav {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 60;
    height: 56px;
    padding-bottom: env(safe-area-inset-bottom, 0);
    background: var(--panel);
    border-top: 1px solid var(--border);
    display: flex;
    justify-content: space-around;
    align-items: center;
    gap: 0;
  }
  .nav-item {
    flex: 1;
    text-align: center;
    padding: .5em .2em;
    font-size: .82em;
    border-radius: 0;
  }
  .view {
    padding: 10px 10px 76px;   /* 给底部标签栏留位 */
  }
  .toast { bottom: calc(72px + env(safe-area-inset-bottom, 0px)); }
  .card { padding: 12px; }
}

/* ============================================================
   手机：把点按目标统一加大
   为什么：手指触点在手机上约 8~10mm（≈40px）。原来的 .btn-sm 只有约 28px 高、
   顶栏主题按钮约 32×27px，点起来容易偏、也容易点到隔壁（尤其「删除」旁边）。
   桌面端有鼠标，保持原样。
   ============================================================ */

@media (max-width: 767px) {
  .btn { min-height: 40px; }
  .btn-sm { min-height: 36px; padding: .45em .85em; font-size: .9em; }
  .icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 40px;
  }

  /* iOS 的 Safari：输入框字号小于 16px 时，一聚焦就自动放大整页。
     这里补到 16px，填表时页面不再来回跳。复选框/单选框排除，免得被撑大。 */
  input:not([type="checkbox"]):not([type="radio"]),
  select,
  textarea { font-size: 16px; }
}

/* 打印：去掉导航和阴影 */
@media print {
  .topbar, .nav, .toast, .backup-banner { display: none !important; }
  .view { max-width: none; padding: 0; }
  .card { box-shadow: none; border-color: #999; break-inside: avoid; }
}
