/* 外壳：顶栏、标签、页面版心 */

.app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

/* ---- 顶栏：一整层 ---- */

/* 顶栏自己就是那层壳：实底 + 一条发丝线收边，标签直接落在上面 ——
   不在栏里再浮一颗圆角胶囊（两层壳，看着就是"框里套框"）。
   品牌在左、导航居中、连接状态和账号在右。 */
.topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: grid;
  /* 两侧都是 1fr：剩余空间平分给两列，所以中间那列相对整条栏是真正居中的。 */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
  height: var(--topbar-h);
  /* 两端和下面的内容对齐：宽屏上内容收在 --measure 里，顶栏的品牌和账号也跟着收进来 */
  padding: 0 max(var(--gutter), calc((100% - var(--measure)) / 2));
  border-bottom: var(--topbar-line) solid var(--hairline);
}

/* 磨砂玻璃：内容滚到栏底下时透出一点颜色，栏和页面是一体的，不是一块盖板。
   模糊挂在伪元素上而不是 .topbar 自己身上 —— backdrop-filter 会让元素变成
   fixed 后代的定位容器，窄屏下沉到底部的标签栏（它是 .topbar 的孩子）就会
   被钉在顶栏里。 */
.topbar::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
}

/* 这两条是"真居中"的关键：1fr 的最小宽度默认是内容宽度，哪边内容宽哪边
   就多吃一口，中间那列会被推偏（实测 721px 下偏 8px，连接文案一变长还会
   再推一次）。压到 0 之后两列严格等分，导航的中心就是栏的中心。 */
.brand,
.topbar-end {
  min-width: 0;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* 留一点内边距：焦点环不再贴着字边，顺带把点击区域撑起来 */
  margin-inline-start: -6px;
  padding: 4px 6px;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  background: linear-gradient(160deg, var(--progress-from), var(--progress-to));
  color: #fff;
  box-shadow:
    inset 0 0.5px 0 rgb(255 255 255 / 0.5),
    0 1px 2px rgb(0 0 0 / 0.12),
    0 4px 10px -2px var(--accent-ring);
}

.topbar-end {
  display: flex;
  align-items: center;
  justify-self: end;
  gap: 12px;
}

/* 连接状态：一个点 + 一句话。三种状态都有文案 —— 只留一个点的话，"连着"
   这件事只在 title 里，摸不到鼠标的人就永远看不到，而且服务端还没答过话
   的时候也分不清。 */
.conn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* --text-3 在浅色顶栏上只有 3.53:1，不到 4.5:1 */
  color: var(--text-2);
  font-size: 12px;
  white-space: nowrap;
}

.conn::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--ok);
  transition: background var(--dur) ease;
}

/* 已经发了请求、还没等到第一个响应：既不能说"连上了"，也不能说"断了" */
.conn[data-state="connecting"]::before {
  background: var(--mute);
}

.conn[data-state="retrying"] {
  color: var(--warn);
}

.conn[data-state="retrying"]::before {
  background: var(--warn);
  animation: pulse 1.2s var(--ease-in-out) infinite;
}

.account {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 34px;
  padding: 0 12px 0 4px;
  border-radius: var(--r-pill);
  background: var(--fill-faint);
  font-size: 13px;
  font-weight: 500;
  transition:
    background var(--dur-fast) ease,
    transform var(--dur-spring) var(--spring);
}

.account:active {
  transform: scale(0.96);
}

.account-avatar {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--fill);
  color: var(--text-2);
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
}

.account-name {
  max-width: 12ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (hover: hover) {
  .account:hover {
    background: var(--fill);
  }
}

/* ---- 标签：栏里的一排，不是一颗胶囊 ---- */

/* 它们直接落在顶栏那一层上：没有自己的底、圆角和内边距，标签就是栏里的
   一排链接。居中交给 .topbar 两侧等分的 1fr，这里不掺和。 */
.tabs {
  display: flex;
  align-items: stretch;
  align-self: stretch;
  justify-content: center;
}

/* 滑动底板是胶囊时代的指示器，现在是"整层 + 下划线"，用不上它了。
   segmented 仍然会建这个元素（标签栏和分段控件共用一套），这里让它不显示。 */
.tabs-thumb {
  display: none;
}

.tab {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 16px;
  color: var(--text-2);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  transition: color var(--dur) ease;
}

/* 当前页：颜色提上来，加一条贴着栏底的 2px 强调线。
   指示器属于这一层，不是浮在上面的一块 —— 所以它是"线"而不是"胶囊"。 */
.tab::after {
  content: "";
  position: absolute;
  inset-inline: 16px;
  bottom: 0;
  height: 2px;
  border-radius: 1px;
  background: var(--accent);
  opacity: 0;
  transition: opacity var(--dur) ease;
}

.tab[aria-current="page"] {
  color: var(--text);
}

.tab[aria-current="page"]::after {
  opacity: 1;
}

/* 标签是满高的，焦点环往外扩会压到上一行和那条发丝线上；往里收，圈在
   标签自己里面。 */
.tab:focus-visible {
  outline-offset: -3px;
}

.tab-icon {
  display: none;
}

@media (hover: hover) {
  .tab:hover {
    color: var(--text);
  }

  /* 悬停铺满整条栏高：点击目标跟着栏走，不会只在字上 */
  .tab:hover::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--fill-faint);
  }
}

/* ---- 页面 ---- */

.view {
  flex: 1;
  width: 100%;
  max-width: calc(var(--measure) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 8px var(--gutter) 120px;
}

.page {
  animation: page-in 420ms var(--ease-out) both;
}

@keyframes page-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
}

/* 表单类的页面：一栏，居中。表格类的页面用满整个版心 */
.page-narrow {
  max-width: 760px;
  margin-inline: auto;
}

.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 16px 24px;
  padding: 20px 0 28px;
}

.page-title {
  font: 700 clamp(32px, 5.2vw, 44px) / 1.08 var(--font-display);
  letter-spacing: -0.025em;
}

/* 灰字里的黑字：一句话说清现在的情况，关键的数加重 */
.lede {
  max-width: 62ch;
  margin-top: 10px;
  color: var(--text-2);
  font-size: 17px;
  line-height: 1.45;
  letter-spacing: -0.01em;
  text-wrap: pretty;
}

.lede strong {
  color: var(--text);
  font-weight: 600;
  white-space: nowrap; /* "约 2 分钟"不要从中间断开 */
}

.lede-bad {
  color: var(--bad);
}

.lede-line {
  display: block;
}

/* 标题下面那句话里可以点的一行（"3 条任务暂停中，去恢复"） */
.lede-link {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-top: 4px;
  border-radius: 6px;
  color: var(--pause);
}

/* 单独占一行的那种（"3 条任务暂停中，去恢复"）：.lede-link 的 inline-flex 不能把
   .lede-line 的换行冲掉 */
.lede-link.lede-line {
  display: flex;
  width: fit-content;
}

.lede-link > strong {
  color: inherit;
}

/* "号都在观察区"：和观察区的标记同一个颜色 */
.lede-link-observe {
  color: var(--observe);
}

.lede-link > svg {
  transition: transform var(--dur-spring) var(--spring);
}

@media (hover: hover) {
  .lede-link:hover > svg {
    transform: translateX(3px);
  }
}

.section {
  margin-top: 40px;
}

.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.section-title {
  font: 600 22px/1.25 var(--font-display);
  letter-spacing: -0.015em;
}

.section-link {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  border-radius: 6px;
  color: var(--accent);
  font-size: 14px;
}

.section-link > svg {
  transition: transform var(--dur-spring) var(--spring);
}

@media (hover: hover) {
  .section-link:hover > svg {
    transform: translateX(3px);
  }
}

/* ---- 窄屏：标签沉到底部 ---- */

/* 为什么是 900px 而不是 720px：一条栏里同时塞品牌、七个标签、连接状态和
   账号，两侧等分之后每边大约要 175px。实测这一套在 900px 上下才开始富余
   （再窄就要靠压扁某一边来换，那正是把导航挤偏的原因）。所以这里干脆让
   导航离开这一行 —— 底部胶囊本来就是这个宽度段更合适的形态。 */
@media (max-width: 900px) {
  :root {
    --topbar-row-h: 56px;
  }

  /* 导航离开了这一行，栏里只剩两块：品牌靠左、状态和账号靠右。
     还用 1fr auto 1fr 的话，右边那块会落进中间那列 —— 在手机上看就是
     "已连接 · admin"浮在屏幕正中间。 */
  .topbar {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  /* 标签沉到屏幕底部，浮在内容上面 —— 它必须自己有底：栏里那套"直接落在
     一层上"在这里不成立，底下是滚动的页面内容。 */
  .tabs {
    position: fixed;
    z-index: 40;
    align-self: auto;
    /* 七个标签平分整条胶囊：390px 的屏上每个约 52px，"设置"不会再被切到屏幕外。
       平板上不铺满，收到 560px 居中。 */
    right: 0;
    bottom: calc(10px + env(safe-area-inset-bottom));
    left: 0;
    width: min(560px, calc(100vw - 20px));
    margin-inline: auto;
    padding: 4px;
    border-radius: var(--r-pill);
    background: var(--glass-strong);
    backdrop-filter: blur(28px) saturate(180%);
    -webkit-backdrop-filter: blur(28px) saturate(180%);
    box-shadow:
      inset 0 0.5px 0 var(--glass-rim),
      var(--shadow-float);
    overflow-x: auto;
    scrollbar-width: none;
  }

  .tabs::-webkit-scrollbar {
    display: none;
  }

  .tab {
    flex: 1 1 0;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
    min-height: 52px;
    padding: 0 2px;
    border-radius: var(--r-pill);
    font-size: 10.5px;
    transition:
      color var(--dur) ease,
      background var(--dur) ease;
  }

  /* 胶囊里的当前页：iOS 标签栏那种做法 —— 图标和字变成强调色，底下垫一块淡色，
     不再画一条贴边的下划线（悬在胶囊中间的线看着像没对齐） */
  .tab::after {
    display: none;
  }

  .tab[aria-current="page"] {
    background: var(--accent-tint);
    color: var(--accent);
  }

  @media (hover: hover) {
    .tab:hover::before {
      display: none;
    }
  }

  .tab-icon {
    display: block;
  }

  .view {
    padding-bottom: 150px;
  }
}

/* ---- 手机 ---- */

@media (max-width: 720px) {
  /* 手机上的页头照 iOS 导航栏排：标题在左，操作在右、和标题同一行。原来是
     整块 flex-wrap，按钮掉到标题下面东一个西一个。 */
  .page-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: 14px 12px;
    padding: 8px 0 20px;
  }

  .page-head > .btn,
  .head-actions > .btn {
    margin-top: 2px;
  }

  /* 主按钮在标题旁边，长文案会把标题挤窄，手机上只留动词 */
  .btn-label-long {
    display: none;
  }

  .lede {
    font-size: 16px;
  }

  .section {
    margin-top: 32px;
  }
}

/* 再窄就只剩得下标识：品牌名让位给连接状态和账号。
   手机上状态文案不再藏起来（原来是隐藏的），断线时那句"连接断开"要看得见。 */
@media (max-width: 480px) {
  .brand-text {
    display: none;
  }
}
