/**
 * MythosX 下载站的站点样式（download.mythosx.org）。
 *
 * 业务定位：下载站是独立域名，不能跨站引官网的样式，所以 mx/ 下放了一份官网底座的拷贝
 * （mx.css 令牌、顶栏、页脚、按钮、.page-head），这份文件只写下载站特有的版式：
 * 面包屑、目录说明（header / readme）、条目列表、骨架行、非正常态、密码对话框。
 * 类名和 ID 由 download.js 读取或生成，改名要两边一起改。
 *
 * 结构由后端决定（Owner 11-02）：逐级浏览，名字原样、顺序照接口。这里只管质感，
 * 不做任何按目录名、按名字形态、按层级区别对待的版式（名字里的数字、括号都和其它字同色同字重）。
 *
 * 取舍：
 *   - 暗色单主题；强调色只给焦点框（11-11 去油：悬停中的条目名、箭头和「最新」标记不再用暖金，
 *     Owner 11-10 定「暖金只出现在指示线、焦点环」，下载站没有选中态，所以只剩焦点框）；
 *   - 去油（Owner 11-10「油腻不高级」，规范同教程页 controls-v2）：组件上不用阴影、渐变、填底悬停、悬停位移、胶囊；
 *     质感只靠发丝细线、字色层级和对齐。悬停反馈 = 线和字各提一级。外壳（mx/ 下的顶栏、菜单、页脚）是官网底座拷贝，
 *     不在这里覆盖：11-11 已整份同步官网去油定稿（site 提交 2fd0bd9）；
 *   - 全站悬停规范（四站一致，11-11 主线定）：可点的文字平时 --text-2，悬停提到 --text，加 1px、不透明度 .5、
 *     离字 4px 的下划线；不加底色、不位移、不用暖金。2px 暖金指示线只用于「选中、当前」，下载站没有这种状态；
 *   - 页面层背景光（页头光晕、页脚字标渐隐，在外壳里）保留：Owner 11-11「背景光还是有的好，你砍了反而没质感」；
 *   - 文件行的下载按钮用描边按钮：一屏十几个下载按钮全是实心块就没有主次了；
 *   - 切换只有透明度和 6px 位移的减速淡入，没有回弹；骨架行是静止的灰块，不做呼吸闪烁；
 *   - 列宽固定，名称列吃剩余宽度；名字一个字不省略，放不下就折行（宽屏窄屏同一策略，和面包屑一致）；
 *   - 面包屑不截断任何一级：放不下就折行。
 */

/* 下载站的按钮比官网首屏的小一号：它们在列表行里，和行高对齐 */
/* 悬停不填底（去油）：描边按钮只把线提一级。不写底色：同步后的外壳 .btn-line:hover 也不再填底；
   这里若写底色，会以同优先级、更靠后的位置压掉外壳 .btn-solid:hover 的 #fff */
.btn { height: 40px; padding: 0 18px; border: 1px solid var(--line-2); font-size: 14px; color: var(--text); }
.btn:hover { border-color: rgba(var(--ink-rgb), .36); }
.btn[disabled] { opacity: .5; cursor: not-allowed; }
/* 主按钮：实心浅底、深色字，悬停换 #fff，和教程页 controls-v2 的主按钮一致（规范允许的唯一填底悬停） */
.btn-primary { border-color: transparent; background: var(--text); color: #101012; }
.btn-primary:hover { border-color: transparent; background: #fff; }
.btn-ghost { border-color: transparent; color: var(--text-2); }
.btn-ghost:hover { border-color: transparent; color: var(--text); }
/* 行内的下载按钮：定宽，「准备中…」和「下载」来回切换时行不跳；悬停时图标不再下移（去油：悬停不做位移） */
.btn-sm { width: 108px; height: 36px; padding: 0 12px; font-size: 13.5px; }
.btn-sm svg { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

/* 首屏 ------------------------------------------------------------------- */
/* 比官网教程页收紧：没有导语，标题下面紧跟目录，第一屏就能看到条目 */
.dl-main .page-head { padding: calc(var(--bar-h) + clamp(40px, 5.2vw, 96px)) 0 clamp(28px, 3vw, 48px); }
.dl-main .page-title { margin: 14px 0 0; }
/* 回官网的入口：按全站悬停规范，--text-2 → --text 加 .5 下划线 */
.dl-eyebrow a { color: var(--text-2); transition: color .2s var(--ease), text-decoration-color .2s var(--ease); }
.dl-eyebrow a:hover { color: var(--text); text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: rgba(var(--ink-rgb), .5); text-underline-offset: 4px; }

/* 目录区 ----------------------------------------------------------------- */
.dl-body { padding-bottom: clamp(80px, 8vw, 128px); scroll-margin-top: calc(var(--bar-h) + 16px); }
/* 首次打开时先隐藏，字体到了、面包屑画好才揭开（见 download.js load）；只占位不显示，揭开时版面不动 */
.dl-body.is-pending { visibility: hidden; }
/* 目录是异步读的：内容舞台先占住大半屏，数据出来时页脚不会在视口里被推下去 */
/* flow-root：里面第一块的上外边距不穿出舞台（否则 header 隐藏与否、列表换成空目录态时，整个舞台会上下跳 20px） */
.dl-stage { display: flow-root; min-height: 64vh; }

/* 面包屑和读取提示同一行；提示出现和消失都不改版面 */
.crumbs-row { position: relative; display: flex; align-items: center; min-height: 52px; padding: 10px 0; border-bottom: 1px solid var(--line-2); }
/* 每一级目录名原样、不截断：一行放不下就折到下一行（窄屏常见），单个名字比一行还长时在名字里面折。
   面包屑在请求发出前就画好（download.js load），折行发生在首帧之前或紧跟点击，不算布局跳动。
   负外边距让第一级的字和标题左边对齐（内边距保留：它决定字的位置和「/」两侧留白，去掉悬停底色后也不能动） */
.crumbs { display: flex; flex: 1 1 auto; flex-wrap: wrap; min-width: 0; align-items: center; margin: 0 -10px; font: 500 13.5px/22px var(--sans); }
/* 一级 = 目录名 + 它后面的「/」，折行时一起走，「/」紧跟在名字最后一个字后面、永远在行尾。
   名字是行内元素：长名字自己折成几行时，焦点框按行分段（box-decoration-break），不会糊成一整块。
   悬停不填底（去油），按全站悬停规范：--text-2 → --text 加 .5 下划线 */
.crumb-item { display: block; min-width: 0; max-width: 100%; padding: 5px 0; overflow-wrap: anywhere; }
.crumb { display: inline; padding: 5px 10px; border-radius: 6px; -webkit-box-decoration-break: clone; box-decoration-break: clone; color: var(--text-2); transition: color .2s var(--ease), text-decoration-color .2s var(--ease); }
a.crumb:hover { color: var(--text); text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: rgba(var(--ink-rgb), .5); text-underline-offset: 4px; }
a.crumb:focus-visible { outline-offset: -2px; }
.crumb[aria-current="page"] { color: var(--text); }
/* 「/」两侧留白接近对称：左边 = 名字的 10px 内边距 - 2px，右边 = 下一级的 10px 内边距。
   右侧不能用负外边距：Chrome 算这一级的固有宽度时会扣掉它，排版时却不扣，结果短名字（「全部文件 /」）被挤成两行 */
.crumb-sep { margin-left: -2px; color: var(--text-3); user-select: none; }
/* 本目录的条目数和文件总大小：从接口数据算出来的附属信息，排在面包屑这一行的右端，不写任何描述 */
/* 贴着面包屑第一行的文字基线（.crumb-item 上内边距 5px），面包屑折成几行它都留在第一行 */
.dl-count { flex: none; align-self: flex-start; margin: 5px 0 0 auto; padding-left: 24px; font: 400 12px/22px var(--mono); font-variant-numeric: tabular-nums; color: var(--text-3); white-space: nowrap; transition: opacity .2s var(--ease); }
.dl-count:empty { display: none; }
/* 读取提示出现时让出位置（提示是绝对定位叠在同一处） */
.dl-progress.is-on ~ .dl-count { opacity: 0; }
/* 读取提示浮在这一行右端，不占面包屑的宽度（否则看不见的提示也会把面包屑挤得提前折行）；
   底下垫一层实色页面底，万一压到很长的面包屑也读得清。
   11-11 去油：原来是向左渐隐的渐变，改成实色加 16px 留白——提示只在读取的一瞬出现、压到面包屑更少见，
   实色切边的代价小于为它留一处渐变（全站组件层渐变计数要为 0） */
.dl-progress { position: absolute; right: 0; top: 50%; transform: translateY(-50%); display: inline-flex; align-items: center; gap: 10px; padding-left: 16px; background: var(--bg); font-size: 13px; color: var(--text-3); opacity: 0; transition: opacity .2s var(--ease); pointer-events: none; }
.dl-progress.is-on { opacity: 1; }

/* 目录说明（OpenList 的 header / readme）：一块安静的说明区，左侧一条 1px 细线，和列表同宽，正文限行宽 */
/* header 在列表上方、readme 在列表下方，同一种样子 */
/* 11-11 去油：按 controls-v2 的「提示块」写法，去掉渐变底和圆角框，只留左侧 1px 细线；
   线细了 1px，左内边距补 1px，正文位置不变 */
.readme { margin-top: 28px; padding: 20px 24px 20px 23px; border-left: 1px solid var(--line-2); }
.readme > * { max-width: 72ch; }

/* 安全 Markdown 子集：标题、段落、列表、链接、粗体、行内代码，其余一律按原文转义 */
.md { font-size: 14.5px; line-height: 1.8; color: var(--text-2); overflow-wrap: anywhere; }
.md > * + * { margin-top: 10px; }
.md .md-h { font-size: 15px; font-weight: 500; color: var(--text); }
.md .md-h + * { margin-top: 4px; }
.md ul, .md ol { display: grid; gap: 6px; }
.md li { position: relative; padding-left: 18px; }
.md ul > li::before { content: ""; position: absolute; left: 2px; top: .9em; width: 7px; height: 1px; background: var(--text-3); }
.md ol { counter-reset: md; }
.md ol > li { counter-increment: md; padding-left: 28px; }
.md ol > li::before { content: counter(md, decimal-leading-zero); position: absolute; left: 0; font: 400 12px/1.8 var(--mono); color: var(--text-3); }
.md strong { font-weight: 500; color: var(--text); }
/* 行内代码：只留细线框，不填底（去油） */
.md code { padding: 1px 6px; border: 1px solid var(--line); border-radius: 4px; font: 400 12.5px/1.5 var(--mono); color: var(--text); }
/* 说明正文里的链接：正文本身是 --text-2，链接要和正文分得开，所以平时就是 --text 加一条发丝下划线（规范的有意例外）；
   悬停按全站规范把下划线提到 .5，线宽 1px、离字 4px；不用暖金 */
.md a { color: var(--text); text-decoration: underline; text-decoration-thickness: 1px; text-decoration-color: var(--line-2); text-underline-offset: 4px; transition: text-decoration-color .2s var(--ease); }
.md a:hover { text-decoration-color: rgba(var(--ink-rgb), .5); }

/* 条目列表 --------------------------------------------------------------- */
.listing { margin-top: 12px; }
.readme:not([hidden]) + .listing { margin-top: 20px; }
.listing:not([hidden]) + .readme { margin-top: 32px; }
.listing-head,
.row { display: grid; grid-template-columns: minmax(0, 1fr) 96px 156px 108px; align-items: center; gap: 24px; }
.listing-head { padding: 14px 0 10px; border-bottom: 1px solid var(--line); font: 500 12px/1.4 var(--mono); letter-spacing: .04em; color: var(--text-3); }
.listing-head .col-size { text-align: right; }

/* 一行：图标块、名字（含「最新」）、大小、日期、操作。
   11-11 去油：去掉悬停时向两侧长出的浅底块；悬停反馈改成图标描边、大小日期、箭头各提一级 */
.row { position: relative; min-height: 68px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.row > * { position: relative; }
.name { display: flex; align-items: center; gap: 14px; min-width: 0; color: var(--text); }
/* 名字一栏竖排：名字行在上，取直链失败的提示接在下面 */
.name-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* 名字原样显示全（Owner：后端有什么就显示什么）：宽屏也不省略，放不下就折行，和面包屑同一策略；
   「最新」是行内块，紧跟名字最后一个字，名字折行时它跟着落在最后一行。
   字号行高要写在 .name-line 这个块上：块里每一行的行盒至少有块自己的「支柱」高，
   只写在行内的 .name-text 上会继承正文 16px/28px，折行名字行距变成 28px，窄屏首行也对不准图标中线 */
.name-line { display: block; min-width: 0; font-size: 15px; line-height: 1.5; }
.name-text { overflow-wrap: anywhere; transition: color .2s var(--ease); }
/* 文件夹整行是链接：伪元素把点击区铺满整行，键盘焦点框也画在整行上 */
.name-link { display: flex; align-items: center; gap: 14px; min-width: 0; position: static; }
.row.is-dir > .name { position: static; }
.name-link::after { content: ""; position: absolute; inset: 0 -14px; z-index: 1; border-radius: 10px; }
.name-link:focus-visible { outline: none; }
.name-link:focus-visible::after { outline: 2px solid var(--accent); outline-offset: -2px; }
/* 文件夹行悬停：名字按全站悬停规范加 .5 下划线。名字平时保持 --text：它是列表的主信息，和不可点的文件名同色，
   不按「可点文字 --text-2」降一级，否则文件夹和文件名字一明一暗 */
.name-text { text-decoration-thickness: 1px; text-underline-offset: 4px; }
.row:hover .name-link .name-text { text-decoration: underline; text-decoration-color: rgba(var(--ink-rgb), .5); }
/* 取直链失败：只在这一行下面说一句，用状态色里的「不可用」红 */
.row-msg { font-size: 13px; line-height: 1.5; color: var(--down); }

/* 图标块：32px 细线方框，文件夹的图标色亮一级，一眼分出能进去的和能下载的。
   11-11 去油：去掉方块底色（原来文件 #0f0f12、文件夹 #141417，悬停再提亮），只靠线和图标色 */
.ico { flex: none; display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid var(--line); border-radius: 8px; color: var(--text-3); transition: border-color .2s var(--ease), color .2s var(--ease); }
.ico svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ico.is-dir { color: var(--text-2); }
.row:hover .ico { border-color: var(--line-2); color: var(--text); }

.size,
.time { font: 400 13px/1.4 var(--mono); font-variant-numeric: tabular-nums; color: var(--text-3); white-space: nowrap; }
.size { text-align: right; }
.row:hover .size, .row:hover .time { color: var(--text-2); }
.meta { display: contents; }
.act { display: flex; justify-content: flex-end; }
/* 文件夹的操作位：一个右箭头，跟着整行悬停右移。
   箭头笔画在 24 格图标里右侧留白 6px（16px 显示时），负外边距把可见笔画的右缘对齐到下载按钮的右边框：
   文件夹和文件混排时，操作列右边缘是同一条线 */
/* 11-11 去油：箭头悬停只提字色，不再变暖金、不再右移 */
.go { display: inline-flex; align-items: center; justify-content: flex-end; width: 108px; margin-right: -6px; color: var(--text-3); transition: color .2s var(--ease); }
.go svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.row:hover .go { color: var(--text); }

/* 「最新」：同一目录里修改时间唯一最晚的那个文件。
   11-11 去油：去掉暖金胶囊（边框、浅底、暖金字），按 controls-v2「推荐」的写法：名字后面一枚等宽 11px 的 --text-3 小字。
   高度仍是 20px 的行内块，名字行的行高和折行不变 */
.tag-new { display: inline-flex; margin-left: 10px; vertical-align: 1px; white-space: nowrap; align-items: center; height: 20px; font: 500 11px/1 var(--mono); letter-spacing: .02em; color: var(--text-3); }

/* 骨架行：首次读取时占位，和真实行同一网格同一高度；静止的灰块，不呼吸不闪。
   图标位和真实行一样只有细线框（去油后真实图标块没有底色，骨架跟着去掉，数据到了不换质感） */
.skel { display: block; height: 10px; border-radius: 4px; background: rgba(var(--ink-rgb), .07); }
.is-skel .size-skel { width: 52px; justify-self: end; }
.is-skel .time-skel { width: 124px; }

/* 换目录时新内容的淡入：只有透明度和 6px 位移，减速曲线，不回弹 */
@keyframes dl-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.view.is-in, .state.is-in { animation: dl-in .32s var(--ease) both; }

/* 非正常态：空目录 / 出错，同一时刻只显示一个 ------------------------------ */
.state { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 96px 16px; font-size: 14px; line-height: 1.7; text-align: center; color: var(--text-2); }
.state-ico { width: 44px; height: 44px; margin-bottom: 12px; padding: 11px; border: 1px solid var(--line-2); border-radius: 12px; fill: none; stroke: var(--text-2); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.state strong { font: 500 20px/1.4 var(--sans); color: var(--text); }
.state #errorDetail { max-width: 46em; overflow-wrap: anywhere; }
/* 后端原文：一行等宽小字，排查用，不和说明抢 */
.state-raw { max-width: min(46em, 100%); margin-top: 2px; padding: 3px 10px; border: 1px solid var(--line); border-radius: 6px; font: 400 12px/1.6 var(--mono); color: var(--text-3); overflow-wrap: anywhere; }
.state .btn { margin-top: 16px; }
.spinner { width: 14px; height: 14px; border: 1.5px solid var(--line-2); border-top-color: var(--text-2); border-radius: 50%; animation: dl-spin .8s linear infinite; }
@keyframes dl-spin { to { transform: rotate(360deg); } }

/* 密码对话框 ------------------------------------------------------------- */
/* 对话框：浮层要有一块面（--surface-2）和细线边，11-11 去油去掉下方的投影——遮罩已经把背景压暗，边线足够分层 */
.dialog { width: min(440px, calc(100vw - 32px)); padding: 28px; border: 1px solid var(--line-2); border-radius: 12px; background: var(--surface-2); color: var(--text); }.dialog::backdrop { background: rgba(6, 6, 7, .72); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.dialog[open] { animation: dl-in .24s var(--ease) both; }
.dialog-mark { display: grid; place-items: center; width: 40px; height: 40px; margin-bottom: 18px; border: 1px solid var(--line-2); border-radius: 12px; color: var(--text-2); }
.dialog-mark svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.dialog h2 { margin: 0 0 6px; font: 500 20px/1.4 var(--sans); }
.dialog-scope { margin-bottom: 22px; font: 400 13px/1.6 var(--mono); color: var(--text-3); overflow-wrap: anywhere; }
.field { display: grid; gap: 10px; }
.field span { font: 500 12px/1.4 var(--mono); letter-spacing: .04em; color: var(--text-3); }
.field input { width: 100%; height: 44px; padding: 0 14px; border: 1px solid var(--line-2); border-radius: 8px; background: var(--surface); color: var(--text); font: 400 15px/1.2 var(--sans); transition: border-color .2s var(--ease); }
.field input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-color: transparent; }
.field input[aria-invalid="true"] { border-color: rgba(222, 107, 94, .6); }
.field input[aria-invalid="true"]:focus-visible { outline-color: rgba(222, 107, 94, .7); }
/* 输错提示用状态色里的「不可用」红：状态色只进状态提示，这里正是一条状态提示 */
.field-error { margin-top: 10px; font-size: 13px; line-height: 20px; color: var(--down); }
/* 提示行常驻占位，只切可见性：输错时对话框不长高、不在屏幕中间跳一下 */
.field-error[hidden] { display: block !important; visibility: hidden; }
.dialog-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.dialog-actions .btn { min-width: 88px; }

/* 窄屏：条目改两行，名字占满（折行显示全名），大小和日期在下，操作在右 ------------- */
@media (max-width: 720px) {
  .listing-head { display: none; }
  .row { grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name act" "meta act"; gap: 4px 14px; min-height: 0; padding: 14px 0; }
  .name { grid-area: name; align-items: flex-start; }
  .name-link { align-items: flex-start; }
  .name-line { padding-top: 5px; }
  .meta { grid-area: meta; display: flex; gap: 14px; padding-left: 46px; }
  /* 文件夹没有大小，窄屏这一格整个不出现，日期贴着名字左边对齐 */
  .row.is-dir .size { display: none; }
  .act { grid-area: act; }
  /* 大小定宽 8 个等宽字（「999.9 MB」放得下）：日期在每个文件行里落在同一条竖线上。
     原来大小按内容宽，「51.0 MB」和「1.2 MB」后面的日期左边差 8px（11-11 终审量到） */
  .size { text-align: left; min-width: 8ch; }
  .go { width: auto; }
  .name-link::after { inset: 0 -8px; }
  /* 窄屏下载按钮只留图标：名字和日期要的是宽度；按钮的 aria-label 写着「下载 + 文件名」，读屏不受影响。
     「准备中」时按钮变灰（disabled），不再靠换字提示 */
  .btn-sm { width: 40px; height: 40px; padding: 0; }
  .btn-sm span { display: none; }
  .btn-sm svg { width: 16px; height: 16px; }
  .readme { padding: 16px 16px 16px 19px; }   /* 左侧细线 1px，左内边距补 1px，正文位置不变 */
  .is-skel .size-skel { width: 44px; justify-self: auto; }
  .is-skel .time-skel { width: 96px; }
  .state { padding: 72px 8px; }
  /* 窄屏读取提示只留转圈，不压住面包屑的字 */
  .dl-progress > :not(.spinner) { display: none; }
  /* 窄屏面包屑要整行宽度折行，条目数让位 */
  .dl-count { display: none; }
  .dialog { padding: 24px 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; }
  .view.is-in, .state.is-in, .dialog[open] { animation: none; }
}
