* {
  box-sizing: border-box;
}

html {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
}

body {
  height: 100%;
  width: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 0;
  box-sizing: border-box;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 14px;
}

body > header {
  flex: 0 0 auto;
}

/* —— 顶栏 header / nav / dropdown（对齐）—— */

header {
  box-sizing: border-box;
  display: block;
  height: 30px;
  border-bottom: #81c5ba solid 1px;
  font-size: 16px;
  width: 100%;
  padding: 5px;
}

header nav {
  display: inline-block;
  margin: auto;
}

header nav > a {
  display: inline-block;
  margin: 0 5px;
}

dropdown {
  display: block;
  position: absolute;
  top: 25px;
  background-color: #fff;
  border: 1px solid #ccc;
  padding: 10px 0;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  z-index: 1000;
}

dropdown a {
  display: block;
  padding: 5px 10px;
  margin: 0;
  text-decoration: none;
  color: #333;
  transition: background-color 0.2s ease;
  min-width: 100px;
}

dropdown a:hover {
  background-color: #f0f0f0;
}

.click {
  cursor: pointer;
}

.click:hover {
  color: blue;
  text-decoration: underline;
}

/* 框架默认 · tag 行内标签（roles 等） */
tag {
  display: inline-block;
  font-size: 12px;
  border: orange solid 1px;
  border-radius: 5px;
  padding: 3px;
  margin: 0 2px;
  background-color: white;
  color: black;
}

/* 标签栏 / 标签页（multiview · tab 与 multipage · tabbar/tab 统一） */
tab,
multipage-tabbar {
  flex: 0 0 auto;
  display: block;
  border-bottom: 1px solid #81c5ba;
  background-color: #f5f5f5;
  overflow-x: auto;
  overflow-y: hidden;
  white-space: nowrap;
  padding: 5px 5px 0 5px;
  position: relative;
  z-index: 1;
  box-sizing: border-box;
}

multipage-tab,
tab a,
tab-nav {
  display: inline-block;
  vertical-align: top;
  padding: 4px 8px;
  border: 1px solid #ccc;
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  margin-right: 4px;
  background-color: #fff;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  color: inherit;
  font-size: 12px;
  line-height: 1.25;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  position: relative;
  transition: background-color 0.2s;
  box-sizing: border-box;
}

multipage-tab:hover,
tab a:hover,
tab-nav:hover {
  background-color: #f0f0f0;
}

multipage-tab.active,
tab a.active,
tab-nav.active {
  background-color: #81c5ba;
  color: #fff;
  border-color: #81c5ba;
}

aside {
  display: flex;
  flex-direction: column;
  flex: 0 0 240px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  box-sizing: border-box;
  float: none;
  clear: none;
  position: static;
  width: auto;
}

aside scrollbox {
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
}

aside menu li {
  cursor: pointer;
  user-select: none;
}

aside menu a {
  display: block;
  cursor: pointer;
  user-select: none;
}

main {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  margin: 0;
  width: auto;
  overflow: hidden;
  box-sizing: border-box;
}

sidebar {
  display: flex;
  flex-direction: column;
  flex: 0 0 400px;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
  box-sizing: border-box;
}

input,
button,
select,
textarea {
  font: inherit;
}

/* button（对齐） */
button {
  height: 26px;
  border: solid 1px #81c5ba;
  border-radius: 13px;
  margin: 0 3px;
  outline: none;
  padding: 0 13px;
  vertical-align: middle;
  white-space: nowrap;
  width: auto;
  cursor: pointer;
  background: #fff;
}

button:hover {
  background-color: #81c5ba;
  color: #fff;
}

/* ajax：异步片段语义节点；不参与布局（对齐） */
ajax {
  display: contents;
}

route {
  display: contents;
}

/* 路由内容宿主（route_template 挂在 <route> 内的唯一结构子元素），布局上透明 */
route-body {
  display: contents;
}

notfound {
  display: block;
  padding: 0.75rem 0;
}

notfound h2 {
  margin: 0 0 0.5rem;
  font-size: 1.125rem;
  color: #b42318;
}

notfound p {
  margin: 0.25rem 0;
  color: #555;
  font-size: 0.9rem;
}

breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  flex: 0 0 auto;
  min-height: 28px;
  margin: 4px 0 10px;
  font-size: 14px;
  line-height: 24px;
}

breadcrumb a {
  position: relative;
  text-decoration: none;
  color: #0066cc;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

breadcrumb a:hover:not(.active) {
  text-decoration: underline;
  color: #004499;
}

breadcrumb a.active {
  color: #333;
  font-weight: 600;
  cursor: default;
  text-decoration: none;
}

breadcrumb a:not(:first-child)::before {
  content: "/";
  margin: 0 8px;
  color: #999;
  font-weight: normal;
  text-decoration: none;
  display: inline-block;
  cursor: default;
}

loading {
  display: block;
  color: #666;
}

/* —— 表单 / jsonschema（对齐 thin.css）—— */

label {
  box-sizing: border-box;
  display: inline-block;
  width: 90px;
  color: #81c5ba;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}

/* 必填字段 label 星号（对齐 jsonschema · label.required） */
f1 > label.required::after,
f2 > label.required::after,
f3 > label.required::after,
f0 > label.required::after,
field > label.required::after {
  content: "*";
  color: #e53935;
  margin-left: 2px;
}

formview {
  position: relative;
  display: block;
  overflow: auto;
  width: 100%;
  min-height: 0;
  box-sizing: border-box;
  flex: 1 1 auto;
}

/* field 宽列：f1/f2/f3/field 为 inline-block；f0 整行 block */
f1,
f2,
f3,
field {
  box-sizing: border-box;
  display: inline-block;
  padding: 2px 3px;
  min-height: 22px;
  line-height: 18px;
  vertical-align: top;
}

f0 {
  box-sizing: border-box;
  display: block;
  width: 100%;
  max-width: 100%;
  padding: 2px 3px;
  line-height: 18px;
}

f1 > label,
f2 > label,
f3 > label,
field > label {
  vertical-align: bottom;
  line-height: 18px;
}

/* 多行控件：label 顶对齐（单行 input/select 仍底对齐） */
f1:has(> textarea) > label,
f2:has(> textarea) > label,
f3:has(> textarea) > label,
field:has(> textarea) > label,
f1:has(> files) > label,
f2:has(> files) > label,
f3:has(> files) > label,
field:has(> files) > label {
  vertical-align: top;
}

f1,
field {
  width: 280px;
}

f2 {
  width: 560px;
}

f3 {
  width: 840px;
}

f1 > input:not([type="checkbox"]),
f2 > input:not([type="checkbox"]),
f3 > input:not([type="checkbox"]),
field > input:not([type="checkbox"]) {
  width: calc(100% - 96px);
  border: none;
  border-bottom: solid 1px #ccc;
  outline: none;
  margin: 0;
  height: 18px;
  line-height: 18px;
  vertical-align: bottom;
  box-sizing: border-box;
  padding: 0;
}

f0 > input:not([type="checkbox"]),
f0 > textarea,
f0 > select {
  display: block;
  width: 100%;
  box-sizing: border-box;
  border: none;
  border-bottom: solid 1px #ccc;
  outline: none;
  margin: 0;
}

f0 > textarea {
  min-height: 60px;
  resize: vertical;
}

f1 > select,
f2 > select,
f3 > select,
field > select {
  width: calc(100% - 90px);
  border: none;
  border-bottom: solid 1px #ccc;
  outline: none;
  margin: 0;
  height: 18px;
  line-height: 18px;
  vertical-align: bottom;
  box-sizing: border-box;
  padding: 0;
}

f1 > textarea,
f2 > textarea,
f3 > textarea,
field > textarea {
  width: calc(100% - 96px);
  border: none;
  border-bottom: solid 1px #ccc;
  outline: none;
  margin: 0;
  box-sizing: border-box;
  vertical-align: top;
  min-height: 60px;
  resize: vertical;
}

f1 > span,
f2 > span,
f3 > span,
field > span {
  display: inline-block;
  width: calc(100% - 96px);
  vertical-align: bottom;
  line-height: 18px;
  word-break: break-word;
}

/* 自定义控件 div（函数形 field 等）：与 span 同行，勿占满行折行 */
f1 > div,
f2 > div,
f3 > div,
field > div {
  display: inline-block;
  width: auto;
  max-width: calc(100% - 96px);
  vertical-align: bottom;
  line-height: 18px;
  box-sizing: border-box;
}

f0 > span {
  display: block;
  width: 100%;
  word-break: break-word;
}

f1 > files,
f2 > files,
f3 > files,
field > files {
  display: inline-block;
  width: calc(100% - 90px);
  vertical-align: top;
}

f0 > files {
  display: block;
  width: 100%;
}

fieldset {
  box-sizing: border-box;
  border: solid 1px #e8e8e8;
  border-radius: 5px;
  margin-bottom: 3px;
  max-width: 100%;
  overflow: auto;
  min-width: 0;
}

toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  align-self: flex-start;
  box-sizing: border-box;
}

input:not([type="checkbox"]),
select,
textarea {
  border: #ccc 1px solid;
  font-family: Consolas, "Courier New", monospace;
}

field > input:not([type="checkbox"]),
f0 > input:not([type="checkbox"]),
f1 > input:not([type="checkbox"]),
f2 > input:not([type="checkbox"]),
f3 > input:not([type="checkbox"]),
field > select,
f0 > select,
f1 > select,
f2 > select,
f3 > select,
field > textarea,
f0 > textarea,
f1 > textarea,
f2 > textarea,
f3 > textarea {
  border: none;
  border-bottom: solid 1px #ccc;
}

textarea {
  min-height: 4rem;
}

/* 约束校验失败标红（与 thin.validate 一致；对齐 · 用 :invalid，勿仅 :user-invalid） */
input:invalid:not([type="checkbox"]),
textarea:invalid {
  border-color: red;
}

select:invalid {
  border-color: red;
  outline: 1px solid red;
  outline-offset: -1px;
}

field > select:invalid,
f0 > select:invalid,
f1 > select:invalid,
f2 > select:invalid,
f3 > select:invalid {
  outline: none;
  border-bottom-color: red;
}

field > input:invalid:not([type="checkbox"]),
f0 > input:invalid:not([type="checkbox"]),
f1 > input:invalid:not([type="checkbox"]),
f2 > input:invalid:not([type="checkbox"]),
f3 > input:invalid:not([type="checkbox"]),
field > textarea:invalid,
f0 > textarea:invalid,
f1 > textarea:invalid,
f2 > textarea:invalid,
f3 > textarea:invalid {
  border-bottom-color: red;
}

gridview td input:invalid:not([type="checkbox"]),
gridview td textarea:invalid,
gridview td select:invalid {
  border-color: red;
}

jsonschema {
  display: block;
  padding: 10px;
}

jsonschema h2 {
  margin: 0.25em 0;
  font-size: 1.1em;
  font-weight: bold;
}

jsonschema p {
  margin: 0 0 0.75em;
  color: #555;
}

lazyloadlist {
  position: relative;
  display: block;
  overflow: auto;
  width: 100%;
  min-height: 0;
  box-sizing: border-box;
  flex: 1 1 auto;
  font-size: 12px;
}

datalistview {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  box-sizing: border-box;
  font-size: 12px;
}

datalistview > h2,
datalistview > button {
  flex: 0 0 auto;
}

gridview {
  position: relative;
  display: block;
  overflow: auto;
  width: 100%;
  min-height: 0;
  box-sizing: border-box;
  font-size: 12px;
}

datalistview > gridview {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

/* ISS-657：dialog 内宽表横条须钉在可视底边（勿先竖滚到底）
   链：formview（滚动叶）→ jsonschema → fieldset → gridview → table。
   fieldset 默认 overflow:auto；若只放 gridview，横条会挪到 fieldset 底边，行多仍躲藏。
   故 dialog 内嵌套链一律 visible，横竖滚交给外层 formview（或 dialog 直挂的 jsonschema 叶）。
   勿写裸 `dialog jsonschema { overflow:visible }`——无 formview 时 jsonschema 仍是滚动叶。
   列表页、dialog 根级 gridview、datalistview > gridview 不受影响。 */
dialog formview gridview,
dialog jsonschema gridview,
dialog formview fieldset,
dialog jsonschema fieldset,
dialog formview jsonschema {
  overflow: visible;
}

/* pager：整组靠左 — prev · 页码 · next */
pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  width: 100%;
  box-sizing: border-box;
}

pager > button {
  margin: 0;
}

pager > span {
  white-space: nowrap;
  line-height: 26px;
  color: #555;
}

datalistview > pager,
ajax > pager {
  flex: 0 0 auto;
}

th {
  border-bottom: solid 1px;
}

lazyload > tr:hover,
lazyload > tr:nth-child(odd):hover,
tbody > tr:nth-child(odd):hover,
tbody > tr:hover {
  background-color: #ccc;
}

lazyload > tr:nth-child(even),
tbody > tr:nth-child(even) {
  background-color: antiquewhite;
}

tbody a {
  display: inline-block;
}

lazyloadlist table,
fieldset table,
gridview table {
  width: max-content;
  border-spacing: 0;
}

lazyloadlist td,
lazyloadlist th,
gridview td,
gridview th {
  word-break: break-word;
  white-space: pre-wrap;
  margin: 1px;
  padding: 4px;
}

td field {
  width: 160px;
}

td field > label {
  width: 50px;
  vertical-align: text-bottom;
}

td field:has(> textarea) > label,
td field:has(> files) > label {
  vertical-align: top;
}

td field > input:not([type="checkbox"]),
td field > select,
td field > textarea {
  width: calc(100% - 54px);
  border: none;
  border-bottom: solid 1px #ccc;
}

td {
  padding: 4px 5px;
}

td > input:not([type="checkbox"]),
td > select,
td > multiselect {
  width: 100%;
}

td > textarea {
  width: calc(100% - 4px);
}

td button {
  height: 16px;
  border: solid 1px #81c5ba;
  font-size: 12px;
  border-radius: 8px;
  margin: 0;
  outline: none;
  padding: 0 11px;
  vertical-align: middle;
}

lazyloadlist thead,
gridview thead {
  position: sticky;
  top: 0;
  background-color: white;
  z-index: 2;
}

/* 筛选器行下边框 */
lazyloadlist thead tr:last-child td,
gridview thead tr:last-child td {
  border-bottom: #ccc 1px solid;
}

lazyloadlist tfoot,
gridview tfoot {
  position: sticky;
  background-color: white;
  bottom: 0;
  z-index: 2;
}

lazyloadlist tfoot tr:first-child td,
gridview tfoot tr:first-child td {
  border-top: black 1px solid;
}

lazyloadlist th,
gridview th {
  position: sticky;
  top: 0;
}

td.right,
th.right {
  text-align: right;
}

/* 固定列（左 sticky · fixed-N 由 JS 注入 left；右 sticky · fixright） */
lazyloadlist th.fixed,
lazyloadlist td.fixed,
gridview th.fixed,
gridview td.fixed,
gridview col.fixed {
  position: sticky;
  left: 0;
  background-color: #fff;
  opacity: 0.9;
  z-index: 1;
}

gridview th.fixedright,
gridview td.fixedright,
lazyloadlist th.fixright,
lazyloadlist td.fixright,
gridview th.fixright,
gridview td.fixright {
  position: sticky;
  right: 0;
  background-color: #fff;
  z-index: 1;
}

/* 航次 booking · 快照差异 / 删除行（对齐 v2.css · V1 voyage booking） */
gridview td.bkupdated,
lazyloadlist td.bkupdated {
  background-color: rgb(101, 215, 253);
  color: black;
}

gridview tr.deleted,
lazyloadlist tr.deleted {
  background-color: red;
}

gridview td.warning,
lazyloadlist td.warning {
  background-color: red;
  color: white;
}

gridview td.updated,
lazyloadlist td.updated {
  background-color: yellow;
}

td.editable:hover {
  background-color: white;
}

td.editable span {
  display: block;
  width: 100%;
  min-height: 16px;
}

gridview tr.unmatched,
lazyloadlist tr.unmatched {
  background-color: yellow;
}

gridview tr.unmatched:nth-child(odd),
lazyloadlist tr.unmatched:nth-child(odd) {
  background-color: yellowgreen;
}

gridview tr.unmatched:hover,
lazyloadlist tr.unmatched:hover {
  background-color: #ccc;
}

gridview td input,
gridview td select,
gridview td textarea,
gridview td multiselect {
  box-sizing: border-box;
  min-width: 0;
}

multiselect {
  display: block;
  box-sizing: border-box;
  -webkit-user-select: none;
  user-select: none;
  border: 1px solid #ccc;
  font-family: Consolas, "Courier New", monospace;
  padding: 1px 2px;
  min-height: 18px;
  line-height: 18px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
  background-color: transparent;
}

multiselect[data-placeholder]::before {
  content: attr(data-placeholder);
  color: #999;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* multiselect 选项面板：fixed 锚在控件下方（top/left 由 JS 写入）
 * 选项区单独滚动；底栏 cancel/select 固定可见 */
popdialog.multiselect-popover {
  display: flex;
  flex-direction: column;
  position: fixed;
  z-index: 1000;
  max-width: min(24rem, calc(100vw - 1rem));
  padding: 0.35rem 0.5rem;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  box-sizing: border-box;
  max-height: min(16rem, 40vh);
  overflow: hidden;
}

dialog > popdialog.multiselect-popover {
  /* 与 input-ajax-suggest 同：dialog 内 formview/scrollbox 会挡住点选，须抬到 body 同级层 */
  z-index: 10050;
}

popdialog.multiselect-popover > foreach-host,
popdialog.multiselect-popover > ul {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  margin: 0;
  padding: 0;
  list-style: none;
}

popdialog.multiselect-popover li,
popdialog.multiselect-popover foreach-item {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0;
  white-space: nowrap;
}

popdialog.multiselect-popover foreach-item > li {
  width: 100%;
  padding: 0;
}

popdialog.multiselect-popover > footer,
popdialog.multiselect-popover > div {
  flex: 0 0 auto;
  display: flex;
  gap: 0.35rem;
  justify-content: flex-end;
  margin-top: 0.35rem;
  padding-top: 0.35rem;
  border-top: 1px solid #eee;
  background: #fff;
}

/* input ajax 建议列表（自绘，非原生 datalist） */
popdialog.input-ajax-suggest {
  display: block;
  position: fixed;
  inset: auto;
  margin: 0;
  z-index: 10050;
  max-width: min(34rem, calc(100vw - 1rem));
  padding: 0.2rem 0;
  border: 1px solid #ccc;
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  box-sizing: border-box;
  max-height: min(16rem, 40vh);
  overflow: auto;
  font-size: 0.75rem;
}

dialog > popdialog.input-ajax-suggest {
  /* 与 body 同级层一致；勿用 z-index:1，否则 formview/scrollbox 会挡住点选 */
  z-index: 10050;
}

popdialog.input-ajax-suggest ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

popdialog.input-ajax-suggest li {
  padding: 0.22rem 0.5rem;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

popdialog.input-ajax-suggest li.suggest-row {
  display: grid;
  grid-template-columns: 5.25rem minmax(0, 1fr) 4rem;
  gap: 0.5rem;
  align-items: center;
  white-space: normal;
}

popdialog.input-ajax-suggest li.suggest-row span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

popdialog.input-ajax-suggest li.suggest-row span:first-child {
  font-family: Consolas, "Courier New", monospace;
}

popdialog.input-ajax-suggest li:hover {
  background: #e8f4fc;
}

lazyloadlist input,
gridview input,
lazyloadlist multiselect,
gridview multiselect {
  border: 1px solid #ccc;
  background-color: transparent;
}

/* 表头筛选用 multiselect：受列宽约束，选中加多不撑开列 */
lazyloadlist thead multiselect,
gridview thead multiselect {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

lazyloadlist input:hover,
gridview input:hover,
lazyloadlist multiselect:hover,
gridview multiselect:hover {
  background-color: white;
}

gridview td input[type="checkbox"] {
  width: auto;
}

gridview td toolbar,
gridview td button {
  width: auto;
  margin-right: 0.25rem;
}

select {
  font: inherit;
}

/* thin.pop 弹出窗体（兼容） */
popheader {
  display: block;
  background-color: #81c5ba;
  color: #fff;
  padding: 3px 10px;
  position: relative;
  font-size: 14px;
  font-weight: bold;
}

popdialog {
  display: block;
  position: absolute;
  border-radius: 4px;
  background: #fff;
  box-shadow: 1px 1px 5px 5px rgba(0, 0, 0, 0.1);
  max-height: calc(100% - 10px);
  max-width: calc(100% - 10px);
  overflow: hidden;
}

closeicon {
  position: absolute;
  right: 10px;
  top: 0;
  cursor: pointer;
  color: #000;
  text-shadow: 0 1px 0 #fff;
  opacity: 0.5;
}

popmask {
  display: grid;
  place-items: center;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.2);
  overflow: hidden;
}

popbody {
  display: block;
  padding: 5px 10px;
  position: relative;
  height: calc(100% - 30px);
  overflow: auto;
}

/* dialog / multiview */
dialog {
  display: flex;
  flex-direction: column;
  border: none;
  border-radius: 6px;
  padding: 0.75rem 1rem 0;
  gap: 0.5rem;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
  box-sizing: border-box;
  overflow: hidden;
  max-width: calc(100vw - 2rem);
  max-height: calc(100vh - 2rem);
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.35);
}

dialog > p {
  margin: 0;
}

dialog > input,
dialog > textarea,
dialog > select {
  width: 100%;
  box-sizing: border-box;
}

dialog formview,
dialog jsonschema,
dialog scrollbox {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

dialog > div {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: 0;
  box-sizing: border-box;
}

/* dialog 顶部标题栏（ISS-362——选项层 title；白底不染色） */
dialog > dialog-titlebar {
  display: block;
  flex: 0 0 auto;
  margin: -0.75rem -1rem 0.5rem;
  padding: 0.5rem 1rem;
  border-bottom: 1px solid #ddd;
  font-weight: 600;
  font-size: 14px;
  background: #fff;
}

dialog > stickybottom {
  flex: 0 0 auto;
  position: static;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0.25rem -1rem 0;
  padding: 0.5rem 1rem;
  border-top: 1px solid #ddd;
  background: #fff;
}

stickybottom {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* files 列表 / 上传进度弹窗 */
files {
  display: block;
  margin: 0.5rem 0;
}

dialog.thin-upload-dialog {
  min-width: 640px;
}

dialog.thin-upload-dialog table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 0.5rem;
}

dialog.thin-upload-dialog progress {
  width: 100%;
}

scrollbox {
  display: block;
  box-sizing: border-box;
  width: 100%;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow: auto;
}

lead {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  overflow: visible;
  box-sizing: border-box;
}

lead p {
  margin: 0 0 8px;
  color: #595959;
  font-size: 13px;
  line-height: 1.5;
}

multiview {
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  box-sizing: border-box;
}

multiview > tab {
  flex: 0 0 auto;
}

multiview > view {
  display: flex;
  flex-direction: column;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  box-sizing: border-box;
}

/* 逻辑挂载点：不参与 flex/列布局（子节点直挂父级） */
viewpane,
viewnotfound,
foreach-host,
foreach-item,
thin-mount,
if-host,
if-branch,
switch-host,
switch-branch,
when-host,
when-branch,
formview-fields,
formview-toolbar,
jsonschema-fields,
dialog-buttons {
  display: contents;
}

table lazyload {
  display: table-row-group;
}

table lazyloadtrigger {
  display: table-row;
}

table lazyloadtrigger > message {
  display: table-cell;
  position: absolute;
}

/* formlist（对齐） */
fieldset.formlist {
  border: 1px solid #e8e8e8;
  padding: 0.75em 1em 1em;
  margin: 0 0 1em;
}

formlist-item {
  display: flex;
  align-items: flex-start;
  gap: 0.5em;
  margin-bottom: 0.5em;
}

formlist-item[draggable="true"] {
  cursor: grab;
}

formlist-item[draggable="true"]:active {
  cursor: grabbing;
}

formlist-item fieldset.formlist-item {
  flex: 1;
  min-width: 0;
}

formlist-actions {
  flex-shrink: 0;
}

formlist-add {
  display: block;
  margin-top: 0.5em;
}

/* formlist 内 field 可换行占满行宽 */
fieldset.formlist field {
  width: 280px;
}

/* multipage 多标签工作台（flex 列吃高，对齐 V2 · vibe-coding-ui §2.0） */
multipage {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  height: auto;
  width: 100%;
  box-sizing: border-box;
  position: relative;
}

/* multipage-tab / tab a 共用规则见文首「标签栏 / 标签页」 */

multipage-tab .tab-title {
  display: inline-block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 12px;
  max-width: 110px;
  vertical-align: middle;
}

multipage-tab .tab-close {
  display: inline-block;
  vertical-align: middle;
  margin-left: 6px;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
  width: 14px;
  height: 14px;
  text-align: center;
  opacity: 0.6;
  transition: opacity 0.2s;
}

multipage-tab .tab-close:hover {
  opacity: 1;
}

multipage-tab.active .tab-close {
  color: #fff;
}

multipage-content {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  position: relative;
  height: auto;
}

multipage-home {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  box-sizing: border-box;
}

multipage-home[hidden] {
  display: none;
}

multipage-notfound {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: auto;
  box-sizing: border-box;
  padding: 1rem 1.25rem;
}

multipage-notfound[hidden] {
  display: none;
}

multipage-page {
  display: none;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
  height: auto;
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
}

multipage-page.active {
  display: flex;
}

/* explorer 资源管理器（对齐） */
right {
  display: block;
  position: relative;
  float: right;
}

right a,
left a {
  padding-left: 5px;
  padding-right: 5px;
}

explorer {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  box-sizing: border-box;
  max-width: 840px;
}

explorer breadcrumb {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  flex: 0 0 auto;
  min-height: 28px;
  margin: 4px 0 10px;
  font-size: 14px;
  line-height: 24px;
}

explorer breadcrumb a {
  position: relative;
  text-decoration: none;
  color: #0066cc;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
}

explorer breadcrumb a:hover:not(.active) {
  text-decoration: underline;
  color: #004499;
}

explorer breadcrumb a.active {
  color: #333;
  font-weight: 600;
  cursor: default;
  text-decoration: none;
}

explorer breadcrumb a:not(:first-child)::before {
  content: "/";
  margin: 0 8px;
  color: #999;
  font-weight: normal;
  text-decoration: none;
  display: inline-block;
  cursor: default;
}

explorer listpane {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

explorer lazyloadlist thead th {
  color: #333;
  font-weight: 600;
  cursor: default;
  text-decoration: none;
  user-select: none;
}

explorer lazyloadlist tbody tr {
  transition: background-color 0.15s ease;
}

explorer lazyloadlist tbody tr:hover {
  background-color: #f0f7ff;
}

explorer lazyloadlist td.explorer-name-link {
  color: #0066cc;
  cursor: pointer;
  font-weight: 500;
  text-decoration: none;
}

explorer lazyloadlist tbody tr:hover td.explorer-name-link,
explorer lazyloadlist td.explorer-name-link:hover {
  text-decoration: underline;
  color: #004499;
}

explorer lazyloadlist td.explorer-type-cell {
  cursor: pointer;
  user-select: none;
}

explorer item {
  display: block;
  height: 22px;
}

explorer item > i {
  display: inline-block;
  width: 30px;
  text-align: center;
  color: #81c5ba;
}

explorer > item > span {
  display: inline-block;
  width: 100%;
}

/* 冒烟页 · 内容区内边距（index main 与 #app 挂载点） */
main#app,
body > main {
  padding: 1rem;
  box-sizing: border-box;
}

/* 冒烟目录：main 作滚动叶（body 仍 overflow:hidden 应用壳） */
body.smoke-catalog > main {
  overflow: auto;
  flex: 1 1 auto;
  min-height: 0;
}

body.smoke-catalog main ul {
  columns: 2;
  column-gap: 2rem;
  margin: 0.25rem 0 1rem;
  padding-left: 1.25rem;
}

body.smoke-catalog main ul li {
  break-inside: avoid;
  margin: 0.15rem 0;
}

@media (min-width: 1100px) {
  body.smoke-catalog main ul {
    columns: 3;
  }
}

/* 冒烟页 · dialog_test */
main#app button {
  margin: 0.35rem 0.5rem 0.35rem 0;
}

/* 冒烟页 · route_test（body.layout-route 由脚本添加） */
body.layout-route {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  margin: 0;
}

body.layout-route > nav {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 0.5rem 1rem;
  background: #eef5f3;
  border-bottom: 1px solid #81c5ba;
}

body.layout-route > route#main {
  flex: 1 1 auto;
  min-height: 0;
  display: block;
  padding: 1rem 1.25rem;
  overflow: auto;
}

body.layout-route > route#main > route-body > view,
body.layout-route > route#main > route-body > multiview {
  display: flex;
  flex-direction: column;
  min-height: 12rem;
}

/* 冒烟页 · lazyloadlist_test / lazyloadlist_crud_test */
main.layout-lazylist,
main.layout-lazylist-crud {
  max-width: none;
  height: 100%;
}

lazyloadlist.scroll-demo {
  flex: 1 1 auto;
  min-height: 14rem;
  max-height: 20rem;
}

lazyloadlist.crud-demo {
  flex: 1 1 auto;
  min-height: 14rem;
  max-height: 22rem;
}

/* 冒烟页 · multiselect_test */
main.layout-ms {
  max-width: none;
  height: 100%;
}

lazyloadlist.ms-demo {
  flex: 1 1 auto;
  min-height: 12rem;
  max-height: 18rem;
}

/* 冒烟页 · input_ajax_test */
.demo-port {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 24rem;
}

.demo-port input[name="port"] {
  width: 100%;
  box-sizing: border-box;
  padding: 0.35rem 0.5rem;
}

.picked {
  margin-top: 0.75rem;
  font-family: Consolas, "Courier New", monospace;
  color: #333;
}

.hint {
  color: #666;
  font-size: 0.9rem;
  max-width: 36rem;
}

/* 冒烟页 · multipage_test */
body.smoke-multipage {
  margin: 0;
  padding: 1rem 1.25rem;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

body.smoke-multipage .test-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1rem 0;
  flex: 0 0 auto;
}

body.smoke-multipage .test-links a {
  padding: 0.35rem 0.75rem;
  background: #81c5ba;
  color: #fff;
  text-decoration: none;
  border-radius: 4px;
  font-size: 0.9rem;
}

body.smoke-multipage .test-links a.invalid {
  background: #c88;
}

body.smoke-multipage .test-links a:hover {
  background: #6ba899;
}

body.smoke-multipage .test-links a.invalid:hover {
  background: #a66;
}

body.smoke-multipage #app {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid #ccc;
  box-sizing: border-box;
}

body.smoke-multipage .page-body {
  padding: 1rem;
}

body.smoke-multipage .home-body {
  padding: 1.5rem;
  color: #555;
}
