/**
 * MythosX 服务状态页（status.html）样式。
 *
 * 业务定位：对外的实时服务状态页，客户遇到连不上时第一个来看的地方。页面只回答一个问题——
 * 卡密验证服务现在能不能用；其余各节都是这个结论的证据或参考，版式上必须让人一眼分清主次。
 *
 * 为什么整份重写：旧版建立在 forgex-tokens（浅色纸面 + 主题切换）上，新站是暗色单主题，
 * 令牌、字体、间距全部换成 mx/mx.css 的一套；类名和 data-state 取值一个没改，
 * 因为 status.js 按它们取值、建节点（见 status.html 顶部注释第 7 条）。
 *
 * 用色规则（Owner 11-02）：
 *   - 状态色（--ok / --warn / --down）只出现在状态点、状态标签、主状态图标和两条状态带的格子上；
 *   - 卡片边框、标题、正文一律中性色，不随状态变色；
 *   - 响应时间曲线用全站唯一强调色（它是这一节的主角，但不是状态）。
 *
 * 版式：主状态卡占满整行；其下每节左栏是序号 + 标题，右栏是内容。左栏宽 220px、列间距与教程页
 * .doc-in 相同，全站内页的正文左边缘落在同一条竖线上。窄屏（≤960）改成单栏，标题行回到内容上方。
 *
 * 不跳版（第二轮）：数据是加载后才到的，凡是「有数据才出现」的块都先按有数据时的尺寸占好位——
 * 主状态卡的可用率列、各项检查的卡片区、页头的更新时间。占位只留空，不放任何假数字。
 */

/* 骨架 ------------------------------------------------------------------- */
/* 顶部那一片很淡的暖灰光与内页 .page-head 同一个配方，状态页因此和其它内页是同一个空间 */
.st-main { position: relative; padding: calc(var(--bar-h) + clamp(48px, 6vw, 96px)) 0 clamp(80px, 8vw, 128px); }
.st-main::before { content: ""; position: absolute; inset: 0 0 auto; height: min(900px, 80vh); background: radial-gradient(70% 80% at 78% 0%, rgba(150, 140, 124, .08), transparent 70%); pointer-events: none; }
.st-shell { position: relative; }
/* 数字一律等宽对齐：时间、延迟、百分比刷新时宽度不变，不会带着整行跳 */
.st-num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* 页头：标题在左，「最后更新」在右，同一条底线 */
.st-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 16px 32px; padding-bottom: 36px; }
/* 英文标题在手机上折成两行时，balance 让两行长短接近，不会把一个词孤零零甩到第二行 */
.st-head h1 { font: 500 clamp(40px, 4.4vw, 64px) / 1.1 var(--display); letter-spacing: -.01em; color: var(--text); text-wrap: balance; }
.st-head-meta { display: inline-flex; align-items: center; gap: 10px; padding-bottom: 8px; font-size: 13px; color: var(--text-3); }
/*
 * 时间先按「22:29」五个等宽字占位：这一组整体靠右，宽度一变整组会往左挪。
 * 字右对齐（11-03）：没有数据时只有一个「—」，左对齐会让它离主状态卡右边缘空出三个字宽，
 * 右边缘就和下面的卡片对不齐了；右对齐后有数据、没数据，这一组的右边缘都落在卡片右边缘上。
 */
.st-head-meta time { min-width: 5ch; text-align: right; color: var(--text-2); }
/*
 * 数据在线的指示点：静止，不闪烁（Owner：不闪烁、不炫光）；没有数据时 status.js 把它藏起来。
 * 它只表示「数据是新的」，不表示服务状态，所以用强调色而不是绿色（11-03）：
 * 原先恒为绿色，服务异常时「最后更新」旁边仍是一个绿点，和主卡的红色结论打架。
 */
.st-live { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }

/* 主状态卡 --------------------------------------------------------------- */
/* 边框和底色保持中性：状态只由左侧图标表达，大面积染色会把全页拖成红或绿。
   去油：渐变底与顶部内高光换成中性平底（同 mx.css .card），只靠发丝细线分层 */
.st-primary { padding: clamp(24px, 3vw, 40px) clamp(22px, 3vw, 40px) 0; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); --st-color: var(--text-3); }
.st-primary[data-state="operational"] { --st-color: var(--ok); }
.st-primary[data-state="service_issue"] { --st-color: var(--down); }
.st-primary-main { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 20px clamp(20px, 2.4vw, 32px); padding-bottom: clamp(24px, 3vw, 36px); }
/* 状态切换时图标只换颜色，用同一条减速曲线过渡，不缩放、不弹 */
.st-primary-icon { display: grid; place-items: center; width: 52px; height: 52px; border: 1px solid var(--line-2); border-radius: 50%; color: var(--st-color); transition: color .4s var(--ease); }
.st-primary-icon svg { width: 26px; height: 26px; }
.st-primary-copy h2 { margin: 0; font: 500 clamp(24px, 2.4vw, 34px) / 1.25 var(--display); color: var(--text); }
.st-primary-copy p { margin-top: 6px; font-size: 15px; color: var(--text-2); }
/*
 * 中文说明只在逗号处折行：三句说明都是「短句，短句。」，手机上按字折会把「修复。」单独甩到第二行，
 * 或者把「使用」拆成两半（11-03 截图）。keep-all 让折行只落在标点后，折出来仍是两行，手机上按行数预留的 min-height 不变。
 * 只在 360px 及以上启用：最长分句 11 个字约 165px，360 宽的手机这一栏约 200px 放得下；
 * 更窄时分句放不下，强制断行会把逗号甩到行首（320 实测），那里退回默认按字折。
 */
@media (min-width: 360px) {
  /* 外部依赖的说明和脚注同理：「Cloudflare 线路正常」会被拆成「线 / 路正常」；它们折在空格或逗号处，最长一段也不超过 11 个字 */
  :root[lang="zh-CN"] .st-primary-copy p,
  :root[lang="zh-CN"] .st-dep-copy span,
  :root[lang="zh-CN"] .st-dep-note { word-break: keep-all; }
}
/*
 * 30 天可用率：全页最重要的数字，宋体大字、中性色。标签在上、数字在下，与下面一排事实的
 * 「小标签在上、值在下」同一种读法。
 * 数据不足时 status.js 给它加 hidden。这里不再整块收起，而是数字位换成一个小号「—」，
 * 和下面一排事实没有数据时的写法相同：
 *   - 收起会让数据到达时主状态卡变高、整页下移（手机上尤其明显）；
 *   - 留一块空白又是空槽位；
 *   - 「—」不是数字，不会被读成可用率；数字位里残留的旧值被 font-size:0 藏掉，不会露出来。
 */
.st-hero { display: grid; justify-items: end; gap: 6px; text-align: right; }
.st-hero[hidden] { display: grid !important; }
/* 旧值用 visibility 藏而不只靠 font-size:0：读屏软件不读 visibility:hidden 的字，不会念出过期的百分比 */
.st-hero[hidden] strong { display: flex; align-items: center; justify-content: flex-end; min-height: clamp(40px, 4.4vw, 60px); font-size: 0 !important; visibility: hidden; }
.st-hero[hidden] strong::after { content: "—"; visibility: visible; font: 400 20px/1 var(--mono); color: var(--text-3); }
.st-hero span { order: -1; font: 500 12px/1.4 var(--mono); letter-spacing: .04em; color: var(--text-3); }
.st-hero strong { font: 500 clamp(40px, 4.4vw, 60px) / 1 var(--display); font-variant-numeric: tabular-nums; color: var(--text); }
.st-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); border-top: 1px solid var(--line); }
.st-facts div { padding: 18px 0 22px; }
.st-facts div + div { padding-left: clamp(16px, 2.4vw, 32px); border-left: 1px solid var(--line); }
.st-facts dt { font: 500 12px/1.4 var(--mono); letter-spacing: .04em; color: var(--text-3); }
.st-facts dd { margin-top: 8px; font-size: 16px; line-height: 1.4; color: var(--text); }

/* 章节：左栏序号 + 标题，右栏内容 ---------------------------------------- */
.st-block { display: grid; grid-template-columns: 220px minmax(0, 1fr); column-gap: clamp(40px, 6vw, 104px); margin-top: clamp(56px, 6vw, 88px); padding-top: 28px; border-top: 1px solid var(--line); }
.st-block > * { grid-column: 2; min-width: 0; }
/* 左栏占满本节所有行，内容多少都不影响它的位置 */
.st-block > .st-rule { grid-column: 1; grid-row: 1 / span 12; align-self: start; display: grid; gap: 10px; align-content: start; }
.st-rule-index { font: 500 12px/1.4 var(--mono); letter-spacing: .06em; color: var(--text-3); }
.st-rule h3 { margin: 0; font: 500 22px/1.35 var(--display); color: var(--text); }
.st-rule-line { display: none; }   /* 旧版的渐隐发丝线；新版用整节顶线代替，宽屏不画 */
.st-rule-meta { font: 500 12px/1.5 var(--mono); color: var(--text-3); }
.st-block > :nth-child(2) { margin-top: 0; }

/* 各项检查 */
.st-probe-note { font-size: 15px; color: var(--text-2); }
/*
 * 由 status.js 填充。卡片区先按「一排两张卡」的高度占位：生产只有 api.live、api.ready 两项探针
 * （来源 ForgeX/ops/denia-status/export_snapshot.py 的 SURFACES，注释写明故意只探一个主机）。
 * 探针数变了也不会显示错，只是数据到达时可能再跳一下。卡片里的行高都写死，占位才对得上。
 */
.st-probe-list { --st-probe-card: 178px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; min-height: var(--st-probe-card); margin-top: 24px; }
.st-probe-row { display: grid; align-content: start; gap: 16px; padding: 20px 22px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
.st-probe-heading { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 26px; }
.st-probe-heading strong { min-width: 0; font-size: 15px; font-weight: 500; line-height: 1.4; color: var(--text); overflow-wrap: anywhere; }
/* 状态标签：状态色只在这里 */
.st-probe-state { flex: none; display: inline-flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; border: 1px solid var(--line-2); border-radius: 999px; font: 500 12px/1 var(--mono); color: var(--text-3); transition: color .4s var(--ease), border-color .4s var(--ease); }
.st-probe-state::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--text-3); }
.st-probe-row[data-state="operational"] .st-probe-state { color: var(--ok); border-color: rgba(99, 192, 143, .35); }
.st-probe-row[data-state="operational"] .st-probe-state::before { background: var(--ok); }
.st-probe-row[data-state="service_issue"] .st-probe-state { color: var(--down); border-color: rgba(222, 107, 94, .4); }
.st-probe-row[data-state="service_issue"] .st-probe-state::before { background: var(--down); }
.st-probe-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px 16px; }
.st-probe-facts dt { font: 500 11.5px/16px var(--mono); color: var(--text-3); }
.st-probe-facts dd { margin-top: 4px; font-size: 13.5px; line-height: 20px; color: var(--text-2); overflow-wrap: anywhere; }
/* 没有检查数据时，占位区整块显示成虚线框，和响应时间图的「数据不足」同一种空态 */
.st-probe-empty { grid-column: 1 / -1; display: grid; place-items: center; border: 1px dashed var(--line-2); border-radius: 12px; font-size: 14px; color: var(--text-3); }

/* 可用性：两条状态带 */
.st-band + .st-band { margin-top: 36px; }
.st-band-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 12px; font-size: 14px; color: var(--text-2); }
.st-band-head .st-num { font-size: 12.5px; color: var(--text-3); }
/*
 * 30 天带右上角那个可用率与主状态卡的大数字是同一个数，宽屏下两处同在一屏（Owner：一屏里不重复）。
 * 主状态卡那一处是正位，这里只隐身；status.js 照常写它、切 hidden，取值逻辑不受影响。
 */
#availabilityValue { display: none !important; }
.st-strip { display: flex; align-items: stretch; gap: 2px; height: 40px; }
.st-strip i { flex: 1 1 0; min-width: 0; border-radius: 2px; background: rgba(var(--ink-rgb), .08); transition: opacity .2s var(--ease), background-color .4s var(--ease); }
/* 正常格降一档亮度：整条带大多是正常，满亮度的绿会压过真正要看的异常格 */
.st-strip i[data-state="operational"], .st-strip i[data-state="good"] { background: rgba(99, 192, 143, .58); }
.st-strip i[data-state="down"], .st-strip i[data-state="outage"] { background: var(--down); }
.st-strip i[data-state="degraded"] { background: var(--warn); }
/* 无数据必须与「正常」明确可分：中性灰，一眼看出是缺口而不是一段可用 */
.st-strip i[data-state="unknown"] { background: rgba(var(--ink-rgb), .1); }
/* 悬停只压暗同带的其他格，不放大、不回弹 */
.st-strip:hover i { opacity: .55; }
.st-strip:hover i:hover { opacity: 1; }
/* 30 格铺满整幅时每格比高还宽，加高并留缝，读起来是竖条 */
.st-strip--days { gap: 4px; height: 52px; }
/* 没有数据时带子是空的：铺一层极淡的底，读者看得出这里本该有一条带，而不是版面空了一块 */
.st-strip:empty { border-radius: 3px; background: rgba(var(--ink-rgb), .04); }
.st-strip--days i { border-radius: 3px; }
/*
 * 轴行三格：起点 | 「数据不足」| 终点或说明。用三列网格而不是 space-between：两端文字长短不同时，
 * space-between 会把中间那格推偏（30 天带的右端是一整句说明），两条带的「数据不足」就不在同一条竖线上。
 * 位置写死在列上：「数据不足」有数据时是 hidden，不能让右端那格顺位挪进中间列。
 */
.st-axis { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: baseline; gap: 16px; margin-top: 10px; font-size: 12.5px; color: var(--text-3); }
.st-axis > :first-child { grid-column: 1; }
.st-axis > .st-insufficient { grid-column: 2; }
/* 右端那格在手机上要折行（无数据时是一整句说明）：balance 让两行等长，免得中文版把最后一个「据」字单独甩到第二行（11-03 截图） */
.st-axis > :last-child { grid-column: 3; justify-self: end; text-align: right; text-wrap: balance; }
.st-insufficient { color: var(--text-2); }
/* 图例四项与两条带的四种格子一一对应；「在线率偏低」只出现在 30 天带上，缺了它黄格无从解读 */
.st-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 24px; margin-top: 24px; font-size: 13px; color: var(--text-3); }
.st-legend span { display: inline-flex; align-items: center; gap: 8px; }
.st-legend b { font-weight: 400; }
.st-legend i { width: 8px; height: 8px; border-radius: 2px; background: rgba(var(--ink-rgb), .1); }
.st-legend i[data-state="operational"] { background: rgba(99, 192, 143, .58); }
.st-legend i[data-state="degraded"] { background: var(--warn); }
.st-legend i[data-state="down"] { background: var(--down); }

/* 响应时间图 */
.st-chart { position: relative; }
/*
 * 渐变定义在 <defs> 里，它的 currentColor 取的是 svg 自身的继承色，不是引用它的 .st-area；颜色必须设在 svg 上。
 * 宽屏下高度跟着宽度按 viewBox 的 820:200 走：画面恰好铺满整栏，网格线左右两端与上面状态带的两端对齐。
 * 固定高度时 svg 按比例缩小后左右各留一截空白，图和状态带就不在一条竖线上了。
 */
.st-chart svg { display: block; width: calc(100% * 820 / 766); height: auto; margin-left: calc(-100% * 46 / 766); aspect-ratio: 820 / 200; overflow: visible; color: var(--accent); }
/*
 * 绘图区对齐整栏（11-03）：status.js 的绘图区在 viewBox 的 46–812 之间（共 766），左边 46 是纵轴刻度。
 * 把 svg 放大到 820/766 倍、再向左移 46/766 栏宽，绘图区的左右两端就正好落在栏的左右边缘，
 * 和上面两条状态带同一条竖线；纵轴刻度悬挂进左栏与右栏之间的列间距（宽屏下至少 40px，刻度约 25px）。
 * 原先只补了右端，网格线左端比状态带缩进 55px。
 */
.st-grid line { stroke: var(--line); stroke-width: 1; }
.st-axis-text text { fill: var(--text-3); font-family: var(--mono); font-size: 10px; font-variant-numeric: tabular-nums; }
.st-area { fill: url(#stAreaFill); }
.st-lines path { fill: none; stroke: var(--accent); stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
/* 不要写 .st-points circle { fill } ：会把 10px 的透明命中区整片涂色，折线变成一串珠子 */
.st-point-hit { fill: transparent; }
/* 默认不画点：几百个点同时显示会退化成点阵，只在悬停或聚焦时长出当前点 */
.st-point-dot { fill: var(--accent); r: 0; transition: r .2s var(--ease); }
.st-point.is-active .st-point-dot { r: 3.2; }
.st-point:focus { outline: none; }
.st-point:focus-visible .st-point-dot { r: 3.6; stroke: var(--bg); stroke-width: 2; }
.st-chart-empty { position: absolute; inset: 0; display: grid; place-items: center; border: 1px dashed var(--line-2); border-radius: 12px; background: var(--bg); font-size: 14px; color: var(--text-3); }
/* 作者样式里的 display 会压过 hidden 自带的 display:none，有数据时遮罩仍会盖住图表，必须显式复位 */
.st-chart-empty[hidden] { display: none; }
.st-tip { position: absolute; z-index: 4; padding: 6px 10px; transform: translate(-50%, -128%); border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface-3); font: 400 12px/1.4 var(--mono); font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; pointer-events: none; }

/* 外部依赖 */
.st-dep { display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto; align-items: center; gap: 12px 20px; padding: 18px 22px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); }
/* 状态点对齐标题那一行，而不是两行文字的正中：点说的是「Cloudflare 网络」这一项，不是那句说明 */
/* 状态色标去油：圆点改成短细线（同 mx.css 页脚 .dot）。盒子保持 7×7、位置不变，上下各 2.5px 透明边框，
   底色只画在中间 2px 的内容区，颜色仍按状态区分；盒高不变，列表行高不变 */
.st-dot { box-sizing: border-box; align-self: start; width: 7px; height: 7px; margin-top: 10px; border-block: 2.5px solid transparent; background: var(--text-3); background-clip: content-box; transition: background-color .4s var(--ease); }
.st-dep[data-state="operational"] .st-dot { background: var(--ok); }
.st-dep[data-state="impacting"] .st-dot { background: var(--warn); }
.st-dep-copy { display: grid; gap: 2px; min-width: 0; }
.st-dep-copy strong { font-size: 15px; font-weight: 500; color: var(--text); }
.st-dep-copy span { font-size: 14px; color: var(--text-2); }
.st-dep time { font-size: 12.5px; color: var(--text-3); white-space: nowrap; }
/* 与顶栏、主按钮同一套控件：32px 高，悬停只亮边框和字，不位移 */
.st-dep-link { display: inline-flex; align-items: center; gap: 6px; height: 32px; padding: 0 12px; border: 1px solid var(--line-2); border-radius: 8px; font-size: 13px; color: var(--text-2); transition: color .2s var(--ease), border-color .2s var(--ease), background-color .2s var(--ease); }
.st-dep-link:hover { color: var(--text); border-color: rgba(var(--ink-rgb), .36); background: rgba(var(--ink-rgb), .04); }
.st-dep-note { margin-top: 12px; font-size: 13px; color: var(--text-3); }

/* 近期事件 */
/*
 * 本节顶上已经有整节的分隔线。列表再画一条上边框，就是相隔 30px 的两条平行发丝线（11-03 截图里看到的）。
 * 所以第一行和空状态都不画上边框、不留上内边距，文字顶端与左栏序号齐平；行与行之间才用分隔线，最后一行不画。
 */
.st-incident-empty { font-size: 14px; color: var(--text-3); }
.st-incident { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; gap: 16px; padding: 16px 0; border-bottom: 1px solid var(--line); }
.st-incident:first-child { padding-top: 0; }
.st-incident:last-child { padding-bottom: 0; border-bottom: 0; }
/* 点和时间都对齐事件标题那一行（14.5px 字、约 23px 行高），不对齐两行文字的正中 */
.st-incident i { width: 7px; height: 7px; margin-top: 9px; border-radius: 50%; background: var(--down); }
.st-incident[data-state="incomplete"] i { background: var(--warn); }
.st-incident[data-state="resolved"] i { background: var(--text-3); }
.st-incident-copy { display: grid; gap: 2px; min-width: 0; }
.st-incident-copy strong { font-size: 14.5px; font-weight: 500; color: var(--text); }
.st-incident-copy span { font-size: 13px; color: var(--text-3); }
/* 时间由 status.js 建节点、不带 .st-num；这里补上等宽数字，和本页其它时间同一种字 */
.st-incident time { padding-top: 2px; font-family: var(--mono); font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--text-3); white-space: nowrap; }

/* 页尾说明 */
.st-foot { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 12px 32px; margin-top: clamp(64px, 7vw, 104px); padding-top: 24px; border-top: 1px solid var(--line); font-size: 13px; color: var(--text-3); }
.st-foot p { max-width: 62ch; }
.st-foot a { color: var(--text-2); text-decoration: underline; text-decoration-color: rgba(var(--accent-rgb), .45); text-underline-offset: 3px; transition: color .2s var(--ease); }
.st-foot a:hover { color: var(--text); }

/* 窄屏 ------------------------------------------------------------------- */
@media (max-width: 960px) {
  .st-block { grid-template-columns: minmax(0, 1fr); }
  .st-block > *, .st-block > .st-rule { grid-column: 1; grid-row: auto; }
  /* 标题行横排：序号、标题、细线、补充信息在一行，细线把补充信息推到右边 */
  .st-block > .st-rule { display: flex; align-items: baseline; gap: 12px; margin-bottom: 18px; }
  .st-rule-line { display: block; flex: 1; height: 1px; align-self: center; background: var(--line); }
  /* 单栏时两张卡上下叠放：占位是两张卡加一道间距 */
  .st-probe-list { grid-template-columns: minmax(0, 1fr); min-height: calc(var(--st-probe-card) * 2 + 16px); }
  .st-primary-main { grid-template-columns: auto minmax(0, 1fr); }
  .st-hero { grid-column: 1 / -1; justify-items: start; text-align: left; padding-top: 16px; border-top: 1px solid var(--line); }
  .st-hero[hidden] strong { justify-content: flex-start; }
  .st-strip { height: 30px; }
  .st-strip--days { gap: 2px; height: 36px; }
  /* 窄屏回到 100% 宽，免得多出的那一点撑出横向滚动；高度仍按比例，图上下不留空带 */
  .st-chart svg { width: 100%; margin-left: 0; }
  .st-dep { grid-template-columns: auto minmax(0, 1fr) auto; }
  .st-dep-link { grid-column: 2 / -1; justify-self: start; }
  /* 窄屏说明折成两三行，时间跟着点一起对齐标题那一行，不浮在几行文字中间 */
  .st-dep time { align-self: start; padding-top: 2px; }
  /* svg 文字随 viewBox 缩放：820 宽的画布铺到 350px 时 10px 的轴标签只剩 4px，按容器宽度反向补偿 */
  .st-axis-text text { font-size: 15px; }
}
@media (max-width: 640px) {
  /* 手机上图只有三百来像素宽，viewBox 缩到 0.4 倍左右，轴标签按比例再放大才看得清 */
  .st-axis-text text { font-size: 22px; }
}
@media (max-width: 520px) {
  .st-head { align-items: flex-start; flex-direction: column; }
  /*
   * 手机上这一组改成靠左，锚点从右边缘换到左边缘：
   *   - 指示点挪到时间后面。没有数据时 status.js 用 visibility 藏它，仍占位，放在最前会让「最后更新」比标题缩进一格；
   *   - 时间改回左对齐，「—」紧跟标签，不在五个字宽的占位里飘到右端。
   */
  .st-live { order: 2; }
  .st-head-meta time { text-align: left; }
  /*
   * 手机上补充信息（响应时间的中位/P95、事件的统计窗口）单独占标题下面一行，和宽屏「标题下面一行小字」同一种读法。
   * 挤在同一行时英文版标题「Response time」和「Median … · P95 …」都会折成两行（11-03 截图）。
   */
  .st-block > .st-rule { flex-wrap: wrap; row-gap: 6px; }
  .st-rule h3 { white-space: nowrap; }
  .st-rule-meta { flex-basis: 100%; }
  .st-facts { grid-template-columns: minmax(0, 1fr); }
  .st-facts div, .st-facts div + div { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; padding: 14px 0; border-left: 0; }
  .st-facts div + div { border-top: 1px solid var(--line); }
  .st-facts dd { margin-top: 0; }
  /*
   * 手机上图标缩到 44px、标题 22px：十个字的结论（「卡密验证服务运行正常」）正好一行，不会把「正常」两个字甩到第二行。
   * 结论文字长短不一，数据一到卡片就会变高；按最长的情况占位——中文标题一行、说明两行，
   * 英文标题两行、说明三行——数据到达时卡片高度不变。
   */
  /*
   * 占位让文字块比实际内容高，居中对齐时图标会落到标题下方（11-03 截图）。改成顶端对齐，
   * 再给文字块 8px 上内边距：(44 − 22×1.25) / 2 ≈ 8，标题第一行的中线正好对上图标中心。
   * 占位高度跟着加 8px（border-box）。
   */
  .st-primary-main { gap: 16px; align-items: start; }
  .st-primary-icon { width: 44px; height: 44px; }
  .st-primary-icon svg { width: 22px; height: 22px; }
  .st-primary-copy h2 { font-size: 22px; }
  .st-primary-copy { padding-top: 8px; min-height: calc(8px + 22px * 1.25 + 6px + 15px * 1.75 * 2); }
  :root[lang="en-US"] .st-primary-copy { min-height: calc(8px + 22px * 1.25 * 2 + 6px + 15px * 1.75 * 3); }
  /* 事实改成两列后卡片多一行（三行事实），占位跟着加高 */
  .st-probe-list { --st-probe-card: 232px; }
  .st-probe-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/*
 * 窄屏主结论的折行占位（11-03 用 layout-shift 实测）：上面按「中文标题一行、英文标题两行」预留，
 * 在文字栏更窄时标题自己也要多折：文字栏宽 = 视口宽 − 161px，十个字的中文结论要 ≈220px，
 * 所以视口 ≤ 382px 折成两行（实测 382 折、384 不折）；英文结论 ≤ 360px 折成三行（361 起两行）。
 * 数据一到，标题多出一行就把下面的可用率和事实整体推下去（320、360 实测 CLS ≈ 0.023）。
 * 这里按「各状态在该宽度下最高的那一种」占位，与上面一样用行高算：
 *   - 中文 ≤ 384px：标题两行 + 说明两行（「卡密验证目前无法使用，我们正在修复。」两行）；
 *   - 英文 ≤ 364px：标题三行 + 说明三行（320 宽时「未知」状态是标题两行 + 说明四行，也不超过它）。
 * 断点各放宽 3 到 4px 做余量，余量里最多多留一行空白，不会跳。其它宽度仍沿用上面的占位。
 */
/*
 * 中文主结论按词折行：status.js 在「服务名」和「状态短语」之间放了一个 <wbr>（见 TITLE_BREAK_AFTER），
 * keep-all 让浏览器只在那里断，不再把「服务」拆成「服 / 务」。折出来仍是两行，上面按行数预留的高度不变。
 */
:root[lang="zh-CN"] .st-primary-copy h2 { word-break: keep-all; }
/*
 * 其余中文长句（说明、依赖、事件、脚注）同理：status.js 的 softWrapZh 在词和词之间放了 <wbr> 并给父元素加 .st-words，
 * 折行只落在词的交界处（11-03 实测 320 到 390 出现过「使 / 用」「超 / 时」「线路正 / 常」）。
 * 上面 360px 起启用的 keep-all 是靠标点折行，320 宽时分句放不下才排除；有了词间的折行机会，各宽度都可以启用。
 * break-word 兜底：万一出现比一行还长的词（长英文串），仍然折断而不是撑出横向滚动，且不影响最小内容宽度。
 */
:root[lang="zh-CN"] .st-words { word-break: keep-all; overflow-wrap: break-word; }
@media (max-width: 384px) {
  :root[lang="zh-CN"] .st-primary-copy { min-height: calc(8px + 22px * 1.25 * 2 + 6px + 15px * 1.75 * 2); }
}
@media (max-width: 364px) {
  :root[lang="en-US"] .st-primary-copy { min-height: calc(8px + 22px * 1.25 * 3 + 6px + 15px * 1.75 * 3); }
}
