/* ==========================================================================
   登录页专用样式
   ==========================================================================

   为什么单独一份，而不是继续写在 rageframe.css 里
   ---------------------------------------------------------------------------
   登录页是「外向门面」：它出现的时候，用户既没有身份、也看不到任何一个后台功能，
   观感目标是「像一个产品」，而不是「像后台框架里的某一屏」。这跟后台内部页的取舍
   本来就不同 —— 内部页要克制、要贴住 Tabler 的既有语言；登录页可以厚一点。

   所以它单独成文件、由登录视图单独引入：后台其余页面**零加载、零波及**。

   引入链路（改动时三处一起看）
   ---------------------------------------------------------------------------
       resources/views/auth/login.blade.php   顶部 @push('styles')
         → layouts/plain.blade.php            @include('layouts._head')
           → layouts/_head.blade.php          末尾 @stack('styles')

   ⚠️ **顺序是本文件成立的前提**：`@stack('styles')` 排在 rageframe.css 与 theme.css
      之后，所以这里同权重即胜出 —— 下面改写「plain 布局的页面底色」靠的就是它。
      若哪天把栈挪到前面，页面底会被 rageframe.css 压回去（卡片部分不受影响）。

   两条硬纪律
   ---------------------------------------------------------------------------
   ① 一切选择器都锚在 `.rf-auth-card` 上（自带类或 :has()）。
      layouts/plain.blade.php 是登录页与七张错误页**共用**的布局：不锚定就等于
      顺手把 401/403/404/419/429/500/503 的观感一起改掉。页面底色因此写成
      `.rf-plain-body:has(.rf-auth-card)`，而不是裸的 `.rf-plain-body`。

   ② 配色一律引令牌（--rf-* / --tblr-*），不写死色值。
      明暗两套皮与「主题面板换主色」因此自动跟随。本文件里唯一的字面色是白色
      （#fff / rgba(255,255,255,…)）—— 那是品牌面板**内部**的前景与高光，
      属于这块主色渐变自己的构成，不随主题浮动（面板本身就取主色打底）。

   版式
   ---------------------------------------------------------------------------
   两栏并排（≥768px）：左品牌面板 + 右表单；手机端折叠成「横幅 + 表单」。
   ========================================================================== */

/* ── 页面底：四层叠出来 ────────────────────────────────────────────────────
   plain 布局原本只有「一层线性渐变」（rageframe.css 的 .rf-plain-body），平推一张
   纯色大底确实单调。这里在它上面补三层：

     · 两团主色雾（radial）—— 给大面积底色一个重心，视线有落点；
     · 点阵（单点 radial + background-size 平铺）—— 给空白区一点肌理，
       纯色区不再「空得发糊」。

   点阵的色取自 --rf-ink 的 alpha，这是这份规则能一份两用的关键：浅色皮的 --rf-ink
   是深墨、深色皮是浅墨，所以浅底上自动是深点、深底上自动是亮点，不必写两套。

   ⚠️ 层序就是书写顺序（**先写的在上层**）：雾 → 点阵。底色是纯色 --rf-page
      （2026-10-16 全局去掉页面渐变底），点阵直接平铺在纯色上。 */
.rf-plain-body:has(.rf-auth-card) {
    background-color: var(--rf-page);
    background-image:
        radial-gradient(58% 46% at 6% 2%, color-mix(in oklab, var(--rf-accent) 26%, transparent) 0%, transparent 68%),
        radial-gradient(52% 44% at 98% 100%, color-mix(in oklab, var(--rf-accent) 20%, transparent) 0%, transparent 68%),
        radial-gradient(circle at center, color-mix(in oklab, var(--rf-ink) 13%, transparent) 0 1px, transparent 1px);
    background-size: auto, auto, 24px 24px;
    background-repeat: no-repeat, no-repeat, repeat;
}

/* ── 卡宽 ──────────────────────────────────────────────────────────────────
   .rf-plain 的 480px 是给错误卡定的，登录卡要并排放下品牌面板，借 :has() 从子元素
   反推放宽 —— 错误页不含这张卡，宽度不受影响（:has 的浏览器门槛低于本项目已在用的
   color-mix，不再兜底）。 */
.rf-plain:has(.rf-auth-card) {
    max-width: 736px;
}

/* ── 卡片本体 ──────────────────────────────────────────────────────────────
   display:grid 让「品牌面板 / 表单」两栏在同一个卡片盒里；overflow:hidden 把面板的
   渐变裁进卡片圆角 —— 不裁的话渐变矩形会顶着圆角直愣愣地探出去。 */
.rf-auth-card {
    /* 错误提示槽的高度：一行提示（19px 文字）+ .invalid-feedback 自带的 4px 上间距
       + 1px 余量。字段行拿它当第三轨的下限，见下面的 .rf-auth-field。 */
    --rf-auth-msg-h: 24px;

    display: grid;
    grid-template-columns: 1fr;
    overflow: hidden;
    border: var(--bs-border-width) solid var(--rf-line);
    /* 比后台卡片再圆一档（--rf-r-lg = 12px）：这是全站最「产品化」的一张卡，
       不该跟表格里的卡片一个刻度。方角带圆角是本项目一贯的卡片 / 图标口径。 */
    border-radius: var(--rf-r-lg);
    background: var(--rf-surface);
    /* 用弹层那一档阴影（--rf-shadow-pop）：卡片现在是浮在带肌理的底上，
       普通档太轻，会显得「贴」在背景里、不像独立的一块。 */
    box-shadow: var(--rf-shadow-pop);
}

/* ≥768px 起两栏：品牌面板定宽、表单占余下全部。minmax(0,…) 是给 grid 子项封顶的
   惯用写法，防长文案把列撑开。 */
@media (min-width: 768px) {
    .rf-auth-card {
        grid-template-columns: minmax(0, 336px) minmax(0, 1fr);
    }
}

/* ── 品牌面板 ──────────────────────────────────────────────────────────────
   主色渐变打底，两团 radial 白光压在角落做出「柔」的感觉；::before / ::after 是两
   处纯装饰形：左上一个大柔光球、右下那枚半透明圆环 —— 破一破直边，也让整块面板
   不至于是一片平推的色。 */
.rf-auth-side {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 32px;
    padding: 36px;
    overflow: hidden;
    color: #fff;
    background:
        radial-gradient(80% 60% at 100% 0%, rgba(255, 255, 255, .18), transparent 60%),
        radial-gradient(70% 55% at 0% 100%, rgba(255, 255, 255, .10), transparent 55%),
        linear-gradient(155deg,
            color-mix(in oklab, var(--rf-accent) 78%, #fff) 0%,
            var(--rf-accent) 45%,
            var(--rf-accent-active) 100%);
}

/* 左上的柔光球：压在面板内侧、越出边界一点（配合 overflow:hidden 变成一段光晕弧）。
   它与上面那两团 radial 白光分工不同 —— 那两团是贴在角落的「平光」，这一个是
   有确定形状与位置的「光源」，叠起来才不是一层均匀的膜。 */
.rf-auth-side::before {
    content: '';
    position: absolute;
    top: -96px;
    inset-inline-start: -64px;
    width: 224px;
    height: 224px;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, .22), transparent 70%);
    pointer-events: none;
}

/* 右下角的半透明圆环 —— 面板上唯一的「线」。 */
.rf-auth-side::after {
    content: '';
    position: absolute;
    inset-inline-end: -56px;
    bottom: -56px;
    width: 176px;
    height: 176px;
    border: 24px solid rgba(255, 255, 255, .08);
    border-radius: 50%;
    pointer-events: none;
}

/* 面板里的内容都抬到两个装饰形之上（z-index:1）。 */
.rf-auth-side-brand {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 14px;
}

/* 登录页的 logo 比侧栏品牌区大一档（那里 36px）：整张面板它是唯一的锚。
   圆角 25% 与全站 logo / 图标同一套刻度（方角带圆角）。 */
.rf-auth-side-logo {
    flex: none;
    width: 48px;
    height: 48px;
    border-radius: 25%;
    box-shadow: 0 2px 8px rgba(0, 0, 0, .18);
}

.rf-auth-side-name {
    font-size: var(--rf-fs-h2);
    font-weight: 600;
    line-height: 1.2;
}

.rf-auth-side-tag {
    margin-top: 2px;
    font-size: var(--rf-fs-xs);
    opacity: .75;
}

.rf-auth-side-list {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: var(--rf-fs-sm);
    opacity: .92;
}

.rf-auth-side-list li {
    display: flex;
    align-items: center;
    gap: 10px;
}

/* 图标兜在半透明白底的小圆角方块里 —— 与「图标必成组」的后台图标纪律一致。 */
.rf-auth-side-list i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 24px;
    height: 24px;
    font-size: 13px;
    background: rgba(255, 255, 255, .14);
    border-radius: 25%;
}

/* 手机端品牌面板收成一条横幅：卖点列表是桌面版的「填充物」，横幅里挤着只会显乱，
   整块让给表单。 */
@media (max-width: 767.98px) {
    .rf-auth-side {
        gap: 0;
        padding: 24px;
    }

    .rf-auth-side-list {
        display: none;
    }
}

/* ── 表单列 ────────────────────────────────────────────────────────────────
   垂直居中，左右内边距与品牌面板同一档（两条基准线对得上）。 */
.rf-auth-main {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 36px;
}

.rf-auth-title {
    margin: 0;
    /* 与侧栏品牌名同一套处理：靠字号不靠字重（细体在大字号下更干净） */
    font-size: var(--rf-fs-h1);
    font-weight: 400;
    line-height: 1.2;
    color: var(--rf-ink);
}

.rf-auth-sub {
    margin: 6px 0 28px;
    font-size: var(--rf-fs-sm);
    color: var(--rf-muted);
}

/* ── 字段行：给错误提示预留固定的一槽 ──────────────────────────────────────
   提示块只能是 `.input-group` 的**紧邻下一个兄弟**（form-validate.js 的 feedbackOf()
   就按这个位置找；服务端 @error 块也写在那儿，见 components/ui/input-addon.blade.php）
   —— 所以它只能在行内、在输入框正下方，没有别的落点。

   让它「出现时才占高度」会把整张卡撑高。而卡片是垂直居中的（.rf-plain-body 的
   place-items:center），撑高多少就整体往上跳一半 —— 用户看到的是「点一下登录，
   整个页面跳了一下」。所以高度必须**预留**而不是**追加**。

   做法是把这一行改成三轨 grid：标签 / 输入框 / 提示槽。第三轨用
   minmax(<一行>, auto) 钉住下限：

     · 提示没出现            → 轨道照样占位，就是留白；
     · 提示出现（服务端/脚本）→ 填进已有轨道，行高一点不变；
     · 提示被收起（脚本撤错时给 .d-none，display:none 会让 grid 项退出布局）
                              → 轨道是**显式写出来的**，不跟着子元素塌，行高仍不变；
     · 极窄屏下折成两行       → auto 兜住，只是变高，不会盖住下一行。

   两个方向都不位移，卡片高度恒定，垂直居中于是也稳。行距就由这一槽给
   （所以视图里不再挂 mb-3）—— 24px 略松于原来的 16px，正好是提示行的高度。

   ⚠️ 别退回到「给 .invalid-feedback 写 min-height」：脚本撤错时会加 .d-none
      （display:none !important），高度照样塌回去，反向位移一样晃；而且提示块
      只在出错时才存在，首次出错仍会撑高一次。 */
.rf-auth-card .rf-auth-field {
    display: grid;
    grid-template-rows: auto auto minmax(var(--rf-auth-msg-h), auto);
}

/* ── 输入框：图标与输入线合成一个整块 ──────────────────────────────────────
   Tabler 的 `.input-group-text` 自带一块 --rf-surface-2 浅灰底 + 描边，与白底输入框
   并排就是「两个格子粘在一起」；再配上一枚图标，灰格子会显得又重又脏。

   这里把「一个输入框」的观感整体收到外层 .input-group 上：底色、圆角、描边、焦点环
   全归它；两个子元素退成透明无边框 —— 于是画面里只剩「一枚图标 + 一条输入线」，
   读起来是一个完整的输入框，而不是拼起来的两个。

   ⚠️ 描边用 box-shadow 的 1px 环，不用 border：真 border 会把组撑高 2px
      （42 → 44），与下方 btn-lg 的 42px 对不齐。环不吃布局。
   ⚠️ 环色取 --rf-line，与这张卡自己的描边同一档：输入框嵌在卡里，环比卡边深
      一档就会显得突兀。 */
.rf-auth-card .input-group {
    flex-wrap: nowrap;
    overflow: hidden; /* 兜住自动填充那层方角底色（见下面 :autofill） */
    border: 0;
    border-radius: var(--rf-r-sm);
    background-color: var(--rf-field-bg);
    box-shadow: 0 0 0 1px var(--rf-line);
    transition: box-shadow var(--rf-dur) var(--rf-ease-curve);
}

.rf-auth-card .input-group:focus-within {
    box-shadow: 0 0 0 1px var(--tblr-primary), var(--rf-field-glow);
}

/* 校验失败的红环红晕挂在整组上：子元素已经不画边框了，红要有个落点。
   顺着子元素的 .is-invalid 反推 —— 服务端 @error 与前端脚本加的都是这个类。 */
.rf-auth-card .input-group:has(> .form-control.is-invalid) {
    box-shadow: 0 0 0 1px var(--rf-danger), var(--rf-field-glow-danger);
}

.rf-auth-card .input-group:has(> .form-control.is-invalid) > .input-group-text {
    color: var(--rf-danger);
}

/* 图标槽：定宽 + 水平居中，两个字段的文字起点因此严格对齐
   （Tabler 的默认内距是「图标多宽就缩多少」，起点会跟着图标宽度浮）。
   槽给到 48px：图标居中落在 ~24px 处、文字从 48px 起步 —— 光标与文字
   跟图标之间留出 16px、跟输入框左缘留出 16px+，挤在左边的感觉就没了。 */
.rf-auth-card .input-group > .input-group-text {
    flex: none;
    justify-content: center;
    width: 48px;
    min-height: var(--rf-ctl-h-lg);
    padding: 0;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    color: var(--rf-faint);
    font-size: 15px;
    transition: color var(--rf-dur) var(--rf-ease-curve);
}

/* 聚焦时图标跟着亮起来。 */
.rf-auth-card .input-group:focus-within > .input-group-text {
    color: var(--tblr-primary);
}

/* 输入框退成「一条不带框的输入线」：高度仍走 lg 档（与下方 btn-lg 同高，
   登录框是这一页的主体，用默认档在这么大的卡里显得单薄），
   但边框 / 底色 / 焦点环全部让给外层组。

   ⚠️ 左内距不能给 0：给 0 的话文字与光标紧贴图标槽右缘起步 —— 槽是「图标的地盘」，
      文字要从自己的地盘起步才有呼吸感。12px 让文字落在距组左缘 60px 处，
      与图标之间留出一整段空当（这轮从 47px 挪到 60px，上一轮只挪 7px、肉眼看不出）。 */
.rf-auth-card .input-group > .form-control {
    min-height: var(--rf-ctl-h-lg);
    padding-block: var(--rf-ctl-py-lg);
    padding-inline: 12px 14px;
    border: 0;
    border-radius: 0;
    background-color: transparent;
    box-shadow: none;
    /* 文本框 :focus 时浏览器自带一圈 2px 的直角焦点描边（UA 默认，项目样式表
       没有任何规则声明过 outline）。聚焦态的环与光晕已经归外层组了，内层再画
       一圈就是「圆角外环里套直角内线」的双环 —— 在这里关掉。 */
    outline: 0;
}

/* 自动填充：Chrome 会在这条输入线上刷一层浅黄底，那层底是画在 .form-control 上的、
   方角，比外层组的圆角方。用一层同色内阴影盖掉它，只留文字色跟着主题走
   （登录页最先遇到的往往就是自动填充，不处理会当场露馅）。 */
.rf-auth-card .input-group > .form-control:-webkit-autofill {
    -webkit-text-fill-color: var(--rf-ink);
    -webkit-box-shadow: inset 0 0 0 100px var(--rf-field-bg);
}
