/* ==========================================================================
   utils.css — 内联 style 属性的替代工具类
   ==========================================================================

   这个文件为什么存在
   ------------------
   CSP 里的 `style-src-attr 'unsafe-inline'` 已经拿掉，浏览器不再放行任何
   `style=""` 属性样式（nonce/hash 按规范只对 <style> 元素和 <link> 生效，
   对属性样式无效，能放行属性样式的只有 'unsafe-inline'）。所以 app/Views
   下原本写在元素上的静态内联样式全部搬到了这里，元素改挂对应的工具类。

   改动它们等于改版式
   ------------------
   每个类里的声明与它替换掉的那条内联样式**逐字符等价**：属性顺序、单位、
   `var(--x)` 引用一律原样照搬，没有做任何「顺手优化」。所以：

   - 不要合并看起来重复的类。同一个去重值只对应一个类、不同去重值不共用类，
     是刻意的；合并会把两处版式绑死，改一处就动到另一处。
   - 不要调整声明顺序、也不要在简写与长写之间改写。`border:0` 与 `border-top:0`
     在层叠里并不等价（简写会重置全部 border-* 长写）。
   - 不要往这些类里加新声明。要加样式请去 base/components/layout.css 里对应的
     业务类上加。

   加载顺序很关键
   --------------
   本文件必须排在 base.css / components.css / layout.css **之后**
   （见 app/Views/partials/head.php）。内联样式原本压过所有类选择器，现在靠
   「同权重、后来者胜」复现这一点：utils.css 在最后，`.u-mw-280` 才能压过
   `.container { max-width: 1280px }` 这类业务规则。

   为什么不用 !important
   ---------------------
   加 !important 看似更保险，实际会把 base.css 里 `[hidden] { display:none
   !important }` 那条压掉 —— 原来的内联 `display:flex` 是被 [hidden] 压住的，
   改成 `display:flex !important` 后反而会让 hidden 失效。所以这里一律不加，
   只对确实压不过业务规则的少数几个类，用 `.u-x.u-x` 双写把权重抬到 (0,2,0)，
   去压过「类+元素」的 (0,1,1)（如 `.table td`、`.login-card h1`）。
   每处都在类上方注明了原因。
   ========================================================================== */


/* ---------- 外边距 ---------- */
.u-mt-6 { margin-top:6px; }
.u-mt-8 { margin-top:8px; }
.u-mt-12 { margin-top:12px; }
.u-mt-14 { margin-top:14px; }
.u-mt-16 { margin-top:16px; }
.u-mt-20 { margin-top:20px; }
.u-mt-24 { margin-top:24px; }
.u-mb-12 { margin-bottom:12px; }
.u-mb-16 { margin-bottom:16px; }
.u-mb-20 { margin-bottom:20px; }
.u-ml-auto { margin-left:auto; }
.u-m-0-0-12 { margin:0 0 12px; }
.u-m-12-0-24 { margin:12px 0 24px; }
/* 安装向导的两级小标题：字号与 margin 同属一条内联样式，一起搬过来 */
.u-h3-first { margin:8px 0 12px;font-size:15px; }
.u-h3-next { margin:24px 0 12px;font-size:15px; }

/* ---------- 内边距 / 边框 ---------- */
/* 弹窗页脚落在表单内部时用：去掉分隔线、只留上留白（8 处，全是 .modal-ft） */
.u-plain-block { border:0;padding:16px 0 0; }
.u-p-0-6 { padding:0 6px; }
/* 角色权限弹窗里按模块分组的 fieldset 外框 */
.u-fieldset-box { border:1px solid var(--c-border-2);border-radius:6px;padding:12px; }

/* ---------- 固定宽度（多为表头列宽） ---------- */
.u-w-70 { width:70px; }
.u-w-80 { width:80px; }
.u-w-90 { width:90px; }
.u-w-100 { width:100px; }
.u-w-110 { width:110px; }
.u-w-120 { width:120px; }
.u-w-130 { width:130px; }
.u-w-150 { width:150px; }
.u-w-160 { width:160px; }

/* ---------- 最大宽度（筛选框收窄） ---------- */
.u-mw-140 { max-width:140px; }
.u-mw-150 { max-width:150px; }
.u-mw-170 { max-width:170px; }
.u-mw-240 { max-width:240px; }
.u-mw-260 { max-width:260px; }
.u-mw-280 { max-width:280px; }
/* app.js 的 confirm 小弹窗（原来写在 .modal 元素的内联样式上） */
.u-mw-400 { max-width:400px; }

/* ---------- 最小宽度 / 最小高度 ---------- */
.u-minw-110 { min-width:110px; }
.u-minw-120 { min-width:120px; }
.u-minw-140 { min-width:140px; }
.u-minw-160 { min-width:160px; }
.u-minh-60 { min-height:60px; }
/* ---------- flex ---------- */
.u-flex-1 { flex:1; }
.u-flex-14 { flex:1.4; }
.u-jc-center { justify-content:center; }
.u-jc-end-mt-16 { justify-content:flex-end;margin-top:16px; }
.u-mt-18-jc-end { margin-top:18px;justify-content:flex-end; }
.u-row-center-12 { display:flex;align-items:center;gap:10px;margin-bottom:12px; }
.u-row-gap8-center { display:flex;gap:8px;align-items:center; }
.u-row-gap8-top-mb-8 { display:flex;gap:8px;align-items:flex-start;margin-bottom:8px; }

/* ---------- 显隐 ----------
   原来是条件渲染的 style="display:none"，配合 JS 的 el.style.display=''
   切换；改类名后 JS 侧同步换成 classList.toggle('u-hide', ...)，
   两套机制不再互相打架（见 app/Views/admin/shortcuts.php 的 syncMode）。 */
.u-hide { display:none; }

/* ---------- 文本对齐 ---------- */
/* 双写抬权重到 (0,2,0)：其中 2 处用在 <td> 上，要压过
   `.table th, .table td { text-align:left }` 的 (0,1,1)；
   另外 3 处用在 .login-card 的 <main> 上本无竞争，双写无副作用 */
.u-ta-c.u-ta-c { text-align:center; }
/* data-table 列 align:right 时用（与 u-ta-c 同样双写抬权重压过 .table td 的左对齐） */
.u-ta-r.u-ta-r { text-align:right; }

/* ---------- 颜色 ---------- */
.u-c-danger { color:var(--c-danger); }

/* ---------- 错误页大号状态码 ---------- */
/* 双写抬权重到 (0,2,0)：要压过 `.login-card h1 { font-size:26px; color:#1f2d3d }`
   的 (0,1,1)，否则字号和颜色都会被业务规则夺回去 */
.u-err-500.u-err-500 { font-size:48px;color:var(--c-danger); }
.u-err-404.u-err-404 { font-size:48px;color:var(--c-primary); }
.u-err-403.u-err-403 { font-size:48px;color:var(--c-warning); }

/* ---------- 其它单处使用的组合值 ---------- */
/* 安装向导最外层 main：压过 .container 的 max-width，并只改上下内边距
   （左右仍由 .container 的 padding:0 var(--gap) 提供，与原内联行为一致） */
.u-install-main { max-width:720px;padding-top:32px;padding-bottom:48px; }
/* 500 页的错误详情 <pre> */
.u-pre-detail { text-align:left;background:#f6f8fa;padding:12px;border-radius:6px;overflow:auto;font-size:12px; }
/* 快捷入口的图标预览缩略图 */
.u-thumb-48 { width:48px;height:48px;object-fit:cover;border:1px solid #e5e6eb;border-radius:6px; }
