/* =========================================================
 * 快捷轮盘（radial menu）
 *
 * 长按屏幕任意位置超过设置项 radialHoldMs 后呼出，以按下点为中心：
 *   上 / 右 / 下 / 左 四个方向各装一个动作（内容来自设置项 radialUp/Right/Down/Left）
 *   中心 = 取消：松手时停在中心即「无动作」
 * 结构与交互都在 style/input.js（那个文件负责创建 DOM、判定方向、派发动作），
 * 本文件只管外观。
 *
 * 坐标是**屏幕坐标**（元素挂在 body 上，不随 #stage 缩放），所以尺寸单位用 `vh` 这类视口单位，
 * 与舞台里的设计像素（calc(var(--design-w) * N / 1920)）不是一套 —— 这是有意的：
 * 轮盘要贴着手指/光标，而光标位置是屏幕坐标。整圈只钉一个不变量：外直径 = 画面高度的 30%。
 * ⚠️ 「画面高度」取的是**视口**（vh）。窗口正好 16:9 时它与舞台高完全相等；只有窗口比 16:9
 *    更窄更高（舞台按宽缩放、上下留黑边）时，30vh 会比舞台高的 30% 略大一点。
 *
 * ---- 视觉语言：关于页的「纸 + 细线 + 投影」，颜色用自己的莫兰迪调色板 ----
 * （2026-09-30 照搬关于页三要素；2026-10-01 颜色改为不跟随主题的莫兰迪）
 * 版式三要素仍是关于页那套（.about-panel + .about-meta）：
 *     半透明白纸（gameMenu.panelColor = rgba(255,255,255,0.85)）
 *   + 1px 细线（版本胶囊的描边）
 *   + 一层柔和大投影（0 12px 32px rgba(0,0,0,0.18)）
 * 但**颜色不跟随主题 accent**：工程常是单色主题（本工程 colors.accent = #000000），
 * 跟着走时轮盘的选中格 / 细线 / 文字全是黑白灰，观感「死板肃杀」（2026-10-01 用户反馈）。
 * 轮盘是游戏感的小覆盖层，刻意用自己的一套低饱和度（莫兰迪）色：
 *     选中 = 灰玫瑰、细线 = 雾霾蓝、文字 = 深灰蓝、柔光 = 玫瑰。
 * 调色板全部是**字面值**（见下面取色段）：不用 color-mix、不用 @supports，
 * 也不读任何主题变量 —— 唯一的例外是置灰文字取 --color-insensitive。
 * 想让轮盘跟随主题：把 --radial-line / --radial-ink / --radial-ink-hot /
 * --radial-face-hot 换成 var(--color-accent) 一系即可（2026-09-30 之前的做法，
 * 当时还要为 color-mix 写 @supports 兜底 —— 字面调色板把这些复杂度全免了）。
 *
 * 选中态 = 那一格的纸**染成灰玫瑰**（--radial-face-hot）、文字换成**玫瑰棕并加粗**，
 *          再加一点同色柔光；未选中就是安静的白纸 —— 对比只发生在「被选中的那一格」上。
 *          仍然**不做「整块填成饱和色」**：实色块在暗场景（如 images/bg/roof.png 下半部的
 *          屋顶）上会变成一整片色、轮廓直接消失，只剩文字在飘；且本引擎表达「选中 / 当前」
 *          从来只用变色(+加粗)—— .paper-btn.is-selected / .is-current /
 *          .page-jumper .pj-num.is-current / .checkbox.is-checked 全是如此，
 *          轮盘不该自己发明一种「选中」的写法。
 *          想换回实色块：只改 --radial-face-hot 一处，并把 --radial-ink-hot 一起改浅
 *          （否则深底深字读不出来）。
 *
 * ---- 形态：四个 1/4 圆环 ----
 * 每个方向 = 一个 2×r-out 见方的元素，border-radius: 50% 把它变成圆，
 * 再只给一条边涂色：圆角 50% 的方框，四条边框正好各占 90°，
 * 相邻两条边沿对角线（45°）交接，与 input.js「|dx| >= |dy| 分左右、否则分上下」
 * 的判定分界完全重合。
 * 边框的宽度（--radial-thick）就是环的厚度 —— 外边即外半径、内边即内半径，
 * 于是圆心附近是空的，不会顶到中心的取消键。
 * 每个 1/4 环再用 conic-gradient 当面罩把两端各切掉 --radial-gap 度，
 * 四个环之间留出细缝；否则四块同色填充会连成一整圈，看不出是四个。
 *
 * 半径只在 --radial-d / --radial-r-out / --radial-r-in 这几处定义，input.js 呼出时**量元素**
 * 把它们拿回去（判定半径 = 内半径、贴边内移 = 外半径 + 余量），不再两边各写一个数 ——
 * 过去正是两边各写一个数，才出现过「看着够到圆环了却没选中」。
 *
 * ---- `var()` 的兜底字面量必须等于模板 theme.json 的默认值 ----
 * 本文件现在只读一个主题变量：置灰文字的 var(--color-insensitive, #888888)。
 * 兜底字面量必须与模板 theme.json 的 colors.insensitive 一致。写错不会报错、也不会在
 * 正常主题下显形（--color-insensitive 由构建期恒定写入，兜底分支根本不触发），
 * 只会在极端情况下悄悄偏一点色（历史上就发生过 #3B5998 被写成 #3B5988，长期没人发现）。
 * 改主题默认色时，这处兜底要跟着改（本仓库没有断言守这层对应关系）。
 * ========================================================= */

.radial {
    /* ---- 几何：外直径 = 画面高度的 30%（只有这一个尺寸是不变量，其余都从它派生） ----
     * 用 vh 而不是写死 px：轮盘是挂在 body 上的屏幕坐标元素，换窗口大小 / 换分辨率时
     * 整圈等比缩放，判定几何（input.js 量元素得到）也就永远与视觉一致。
     * 比例链：环的内半径 = 外半径 × 0.55（环厚 = 剩下的 0.45）、
     * 中心圆直径 = 外半径 × 0.6（于是中心与环内缘的净空隙 = 外半径 × 0.25）、
     * 标签字号随外直径走（小窗口有 11px 下限，保证还看得清）。 */
    --radial-d: 30vh;                                      /* 整个圆环的外直径（= 画面高度的 30%） */
    --radial-r-out: calc(var(--radial-d) / 2);             /* 外半径 */
    --radial-r-in: calc(var(--radial-r-out) * 0.55);       /* 内半径；同时就是方向判定半径 */
    --radial-thick: calc(var(--radial-r-out) - var(--radial-r-in));
    --radial-r-mid: calc((var(--radial-r-out) + var(--radial-r-in)) / 2);
    --radial-center-d: calc(var(--radial-r-out) * 0.6);    /* 中心「取消」圆的直径 */

    --radial-gap: 2deg;             /* 相邻两个 1/4 环之间的半缝宽（角度，不随尺寸变） */
    --radial-turn: calc(var(--radial-gap) - 45deg);        /* 第一个 1/4 环的起始角 */
    --radial-sweep: calc(90deg - var(--radial-gap) * 2);   /* 每块实际涂色 / 描边的角度 */

    /* ---- 取色：莫兰迪调色板（字面值，不读主题变量；理由见文件头） ----
     * 面的白与「关于」页那张纸**同值**（那边是 rgba(255,255,255,0.85) 的 gameMenu.panelColor），
     * 于是两者放在一起是一家人。其余是轮盘自己的低饱和度色：
     *   灰玫瑰（选中格的染色 / 柔光 / 中心描边的热态）、雾霾蓝（细线 / 文字的冷灰调）。
     * 想整体换色相：改这 8 行就够了，不用动下面的规则。 */
    --radial-face: rgba(255, 255, 255, 0.85);              /* 未选中：半透明白纸 */
    --radial-face-center: rgba(255, 255, 255, 0.94);       /* 中心格再实一点：它是轮盘的中枢 */
    --radial-face-hot: rgba(226, 200, 198, 0.97);          /* 选中：染了灰玫瑰的纸 */
    --radial-ink: #5D6B77;                                 /* 文字：深灰蓝（雾霾蓝加深，比纯黑柔） */
    --radial-ink-hot: #96625E;                             /* 选中格文字：玫瑰棕 */
    --radial-line: #93A8BB;                                /* 两圈细线：雾霾蓝 */
    --radial-rose-deep: #B08480;                           /* 中心描边选中态（玫瑰） */
    --sector: var(--radial-face);                          /* 四个方向格实际涂在边上的颜色 */

    position: fixed;
    left: 0;
    top: 0;
    /* 盒子本身是 2×r-out 见方，用负 margin 把它的正中对到 JS 设的 left/top（= 呼出点）上。
     * 之所以让盒子有尺寸、而不是 0×0：投影（filter）需要一个正经的滤镜区域。 */
    width: calc(var(--radial-r-out) * 2);
    height: calc(var(--radial-r-out) * 2);
    margin: calc(var(--radial-r-out) * -1) 0 0 calc(var(--radial-r-out) * -1);
    /* 整圈共用**一层**投影：drop-shadow 跟着 alpha 轮廓走，所以挖空的圆心、
     * 环之间的缝都不会被涂黑。参数取自关于页那张纸（0 12px 32px / 0.18），
     * 只是更收一些、更淡一些 —— 轮盘比一整页纸小得多，同样的模糊量会显得糊，
     * 莫兰迪的「轻松」也要求影子别太重。
     * ⚠️ 「偏移 + 模糊」就是投影比元素往外多占多少（这里约 8 + 22 = 30px）。
     *    input.js 的 RADIAL_MARGIN_SLACK 要按它取，否则贴到屏幕底部按下时
     *    投影会被视口边缘切掉一条，看着像环缺了个角。改这里要一起改那个常量。 */
    filter: drop-shadow(0 8px 22px rgba(31, 41, 51, 0.16));
    z-index: 900;
    pointer-events: none;           /* 轮盘绝不抢点击：松手事件仍由 input.js 处理 */
    opacity: 0;
    transition: opacity 0.16s ease-out;
    color: var(--radial-ink);
    font-family: var(--font-interface, system-ui, sans-serif);
    /* 字号随轮盘尺寸走：两三个汉字的宽度要压得进环的厚度（0.45 × 外半径），
     * 所以不能写死 px，否则小窗口会挤爆、大窗口又偏小。 */
    font-size: clamp(11px, calc(var(--radial-d) * 0.05), 22px);
    font-weight: 500;
    line-height: 1.15;
    letter-spacing: 0.04em;         /* 两三个汉字的标签，松一点点比挤在一起干净 */
    text-align: center;
}
.radial.is-open { opacity: 1; }

/* 四个 1/4 圆环：同一个方框，靠 --radial-rot 决定这一块落在哪个 90° 上，
 * 再给对应的那条边涂色 ——「涂哪条边」和 --radial-rot 必须成对，
 * 配错就会出现「高亮的是右边、判定的却是上边」。 */
.radial__item {
    position: absolute;
    left: 50%;
    top: 50%;
    width: calc(var(--radial-r-out) * 2);
    height: calc(var(--radial-r-out) * 2);
    margin: calc(var(--radial-r-out) * -1) 0 0 calc(var(--radial-r-out) * -1);
    box-sizing: border-box;
    border-radius: 50%;
    border: var(--radial-thick) solid transparent;
    /* 三个都会变：方向格换的是 border-color，中心格换的是 background-color，
     * 文字色两边都换。时长给短一点，松手即走，不能拖 */
    transition: border-color 0.14s ease-out, color 0.14s ease-out, background-color 0.14s ease-out;
    /* 把这一块 90° 的环切成 90 - 2×gap 度，两端留缝 */
    -webkit-mask-image: conic-gradient(from calc(var(--radial-turn) + var(--radial-rot, 0deg)),
                                       #000 0 var(--radial-sweep),
                                       transparent var(--radial-sweep));
    mask-image: conic-gradient(from calc(var(--radial-turn) + var(--radial-rot, 0deg)),
                               #000 0 var(--radial-sweep),
                               transparent var(--radial-sweep));
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
}
.radial__item--up    { --radial-rot: 0deg;   border-top-color: var(--sector); }
.radial__item--right { --radial-rot: 90deg;  border-right-color: var(--sector); }
.radial__item--down  { --radial-rot: 180deg; border-bottom-color: var(--sector); }
.radial__item--left  { --radial-rot: 270deg; border-left-color: var(--sector); }

/* 环的内缘 / 外缘各描一圈 1px 细线：四个 1/4 环之间留了缝，只靠填充色看不出
 * 这是一个被分成四段的整环。摆在环体之后，细线压在填充的边界上，轮廓更利落。
 * 细线同样按那四条缝断开（repeating-conic-gradient，周期 90°、起点与环体一致）——
 * 描边不断开的话，四个同色环会被一个完整的圆箍框起来，读起来还是一个整环。
 * 颜色 = --radial-line（雾霾蓝）；**浓度**（外深内浅）交给各自的 opacity。
 * 莫兰迪蓝比原来的黑浅得多，opacity 比上一版（0.55 / 0.24）略提，线才立得住。 */
.radial__edge {
    position: absolute;
    left: 50%;
    top: 50%;
    box-sizing: border-box;
    border: 1px solid var(--radial-line);
    border-radius: 50%;
    -webkit-mask-image: repeating-conic-gradient(from var(--radial-turn),
                                                 #000 0 var(--radial-sweep),
                                                 transparent var(--radial-sweep) 90deg);
    mask-image: repeating-conic-gradient(from var(--radial-turn),
                                         #000 0 var(--radial-sweep),
                                         transparent var(--radial-sweep) 90deg);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-size: 100% 100%;
    mask-size: 100% 100%;
}
.radial__edge--out {
    opacity: 0.75;                  /* 外缘细线：略深，把轮廓勾住 */
    width: calc(var(--radial-r-out) * 2);
    height: calc(var(--radial-r-out) * 2);
    margin: calc(var(--radial-r-out) * -1) 0 0 calc(var(--radial-r-out) * -1);
}
.radial__edge--in {
    opacity: 0.35;                   /* 内缘细线：更浅，做出一点层次 */
    width: calc(var(--radial-r-in) * 2);
    height: calc(var(--radial-r-in) * 2);
    margin: calc(var(--radial-r-in) * -1) 0 0 calc(var(--radial-r-in) * -1);
}

/* 中心「取消」：独立的一个圆，与环的内缘之间留出「外半径 × 0.25」的空隙
 * （--radial-r-in − --radial-center-d / 2），别把取消键怼到环上。
 * 描边用**实线**而不是虚线：虚线是线框图的语言，和关于页那圈 1px 实线胶囊不是一套。
 * 底色比环体再实一点，读作「轮盘的中枢」；不带自己的投影（整圈那层已经覆盖到它了）。 */
.radial__item--center {
    /* 中心比环段再实一点（0.85 → 0.94）：轮盘的中枢要能压住背后的画面。
     * 底色同样走 --sector 而不是写死白 —— 选中时 is-hot 会把 --sector 换成染色的纸，
     * 写死的话中心会在染色的底上留一个白圈（中心格的「涂色」是 background、不是 border，
     * 四个方向格则是 border，两者都要能被同一个变量带着走）。 */
    --sector: var(--radial-face-center);
    left: 50%;
    top: 50%;
    width: var(--radial-center-d);
    height: var(--radial-center-d);
    margin: calc(var(--radial-center-d) / -2) 0 0 calc(var(--radial-center-d) / -2);
    border: 1px solid rgba(147, 168, 187, 0.75);
    border-radius: 50%;
    background-color: var(--sector);
    /* 中心比环段稍大一点：它是「取消」，要最显眼（同样随外直径缩放，带可读下限） */
    font-size: clamp(12px, calc(var(--radial-d) * 0.058), 24px);
    -webkit-mask: none;
    mask: none;
}

/* 选中：那一格的纸染成灰玫瑰（--sector 被换成 --radial-face-hot），
 * 文字换成玫瑰棕并**加粗**，再加一点同色柔光。
 * 字重是「变化的那一档」（与引擎里 .paper-btn.is-current / .pj-num.is-current
 * 的「变色 + 加粗」同一招）；色相换成莫兰迪的灰玫瑰，避免单色主题下的黑白灰观感。
 * 为什么不做整块饱和实色，见文件头「选中态」一段。
 * 柔光只是「我选中了」的一点回应，做得很浅；不想要的话删掉这行 filter 即可。 */
.radial__item.is-hot {
    --sector: var(--radial-face-hot);
    color: var(--radial-ink-hot);
    font-weight: 700;
    filter: drop-shadow(0 0 8px rgba(176, 132, 128, 0.4));
}
/* 中心格的选中：底走 --sector（已在 is-hot 里换成染色的纸），描边则换成**玫瑰色** ——
 * 描边若还留 75% 的雾霾蓝，粉底压一道蓝边，颜色会打架。 */
.radial__item--center.is-hot {
    border-color: var(--radial-rose-deep);
}

/* 当前不可用的动作（如不在剧情中时的「快存」）：整体压淡 + 文字转灰。
 * 不用「只降低不透明度」一种手段 —— 面本来就是半透明白，再压一档就彻底看不见了；
 * 文字转灰能让「这一格有东西、但现在不能用」仍然可读。
 * 指向它时不再染色（本来就不能用），只把纸压到最实，给一点「我在这」的回应。 */
.radial__item.is-disabled { opacity: 0.45; }
.radial__item.is-disabled .radial__label { color: var(--color-insensitive, #888888); }
.radial__item.is-disabled.is-hot { --sector: rgba(255, 255, 255, 0.99); }

.radial__label {
    position: absolute;
    left: 50%;
    top: 50%;
    display: block;
    /* 文字不能横跨到环外：左右两格的文字宽度方向就是半径方向，上限即环的厚度；
     * 上下两格是切向，可以宽一些（见下面的覆写）。 */
    max-width: var(--radial-thick);
    overflow-wrap: anywhere;
    transform: translate(-50%, -50%);
}
/* 中心格不受「环厚」那条限制：它的可用宽度就是中心圆本身 */
.radial__item--center .radial__label { max-width: var(--radial-center-d); }
.radial__item--up .radial__label,
.radial__item--down .radial__label {
    max-width: calc(var(--radial-r-mid) * 1.2);
}
/* 贴到各自弧段的中线半径（(外半径 + 内半径) / 2）上 */
.radial__item--up .radial__label    { transform: translate(-50%, -50%) translateY(calc(var(--radial-r-mid) * -1)); }
.radial__item--down .radial__label  { transform: translate(-50%, -50%) translateY(var(--radial-r-mid)); }
.radial__item--left .radial__label  { transform: translate(-50%, -50%) translateX(calc(var(--radial-r-mid) * -1)); }
.radial__item--right .radial__label { transform: translate(-50%, -50%) translateX(var(--radial-r-mid)); }

/* 捕获按键期间（设置页「自定义」正在等玩家按键）：光标提示一下，
 * 并通过 input.js 在 body 上挂的类控制，本文件不参与逻辑。 */
body.is-capturing-binding { cursor: crosshair; }
