/**
 * 前台样式：单机构那几页。
 * 机构详情、完整价目表、医生团队、预约表单，以及机构自己二级域名下的外壳。
 * 外壳与列表侧在 web.css 里，这一份永远跟在它后面加载（见 Views/web/parts/head.php）。
 *
 * 规矩同 web.css：颜色/字号/圆角一律走 tokens.css 的变量，别写死值。
 */

/* ---------- 详情：头图轮播 ---------- */
/**
 * 封面 + 环境图合成的一条横滑轮播（与小程序 hero 同一块内容）。
 * 没有 JS：scroll-snap 负责一屏一张，桌面上底下那排缩略图是 #shot-N 锚点。
 */
/* 底色透明（2026-09-27 用户口径：图片区域的灰色背景去掉）：这张灰底原来垫在图片缝里，
   现在图片区下面就是页面自己的底。手机端是满宽横滑，本来也没有缝要垫。 */
.shots { position: relative; background: transparent; }
/* 大图 + 压字共用的定位祖先。单独包一层是为了画廊模版桌面端——
   那套模版把 `.shots` 拆成左右两栏，压字只能盖住左边的大图，
   不能跟着整条一起变宽（见下面 .tpl-gallery 那段和 hero.php 里的说明）。
   圆角 + 裁切：窄屏没有右栏，整块图片区的圆角就由它裁出来（四个角都圆）；
   桌面端由媒体查询改成**只圆左边两个角**（右边那半边归右栏，见 .shots__thumbs）。
   `overflow: hidden` 是圆角生效的前提，也正因为它在，跳出去定位的按钮会被裁掉
   —— 所以「全部照片(N)」挂在 `.shots` 上，不在这一层（见 hero.php 的说明）。 */
.shots__stage { position: relative; border-radius: var(--mb-radius-lg); overflow: hidden; }
.shots__track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scroll-behavior: smooth; scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
/* 滚动条在这里是纯噪音：一屏一张的轮播不靠它定位 */
.shots__track::-webkit-scrollbar { display: none; }
/* 裁切对齐左上角，不是居中。
   头图框是固定的宽扁比例（240 / 380 / 460 高），而机构给的图里竖构图不少 ——
   尤其是医生照、人像照。object-fit:cover 默认取正中，竖图就是「裁头裁尾」，
   人的脸正好落在被裁掉的上半部分，看到的是胸口和衣服。
   钉在左上角 = 竖图先保住人物的头部，横图也优先保住招牌 / 左侧主体。
   只影响裁切锚点，不放大不缩小，也不会留白。

   圆角**图片自己也要带一份**（2026-09-27 用户口径：圆角必须给到图片）：
   窄屏整块图片区就是这张大图，容器 `.shots__stage` 与图片自己两头都圆，少一处就露直角；
   桌面端由媒体查询把这张图的圆角改成**只圆左边两个角**（右边两个角是两栏之间那条缝，
   按 2026-09-28 用户口径不带圆角）。
   `background: transparent` 是有意写的：盖掉浏览器给未加载图片画的那块底色。 */
.shots__img {
  flex: 0 0 100%; width: 100%; height: 240px; object-fit: cover;
  object-position: left top; border-radius: var(--mb-radius-lg);
  scroll-snap-align: start; background: transparent;
}
/**
 * 推迟加载的图（`data-defer`，用户 2026-09-28：默认只加载两张）在脚本补 src 之前
 * 要先藏住 —— 它只剩 alt 文字，露出来就是一框字。`[hidden]` 本来是浏览器自带的
 * `display:none`，但上面/下面这些**给 img 设 display 的规则**（如 `.shots-gallery__thumb img`）
 * 是作者样式，会把它盖掉，所以这里按更高的权重显式补一道；脚本把 hidden 摘掉即恢复。
 */
[data-defer][hidden] { display: none; }
/**
 * 图上压字先垫一层暗角，否则遇上浅色的院内实拍白字直接消失。
 * 压得比一般封面渐变重一档：机构给的照片常在角上烧了韩文水印。
 * 这层不吃点击，留给底下的图滑动。
 */
.shots__veil {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 48px var(--mb-gap-lg) 32px; pointer-events: none;
  background: linear-gradient(to top,
    rgba(0, 0, 0, .72) 0%, rgba(0, 0, 0, .44) 45%, rgba(0, 0, 0, 0) 100%);
}
.shots__eyebrow {
  font-size: var(--mb-font-xs); letter-spacing: 1.5px; color: rgba(255, 255, 255, .78);
}
.shots__title {
  margin-top: 3px; font-size: var(--mb-font-2xl); font-weight: 700;
  line-height: 1.25; color: #fff;
}
.shots__sub { margin-top: 3px; font-size: var(--mb-font-md); color: rgba(255, 255, 255, .85); }
/* 「全部照片(N)」：贴在该栏**最后一张缩略图的右下角**（用户 2026-09-27 口径：不压在大图上）。
   它是 `.shots` 的绝对定位子项 —— 既**不能放进 `.shots__thumbs`**（那一栏窄屏
   `display:none`，放进去按钮就跟着消失，第一版正是这么错的），也**不能放进
   `.shots__stage`**（那一层 `overflow: hidden`，定位到它盒子外、右栏那一列的按钮会被裁掉，
   2026-09-27 第二版因此实际压在了大图右下角）。
   基础规则按窄屏给：窄屏 `.shots` 就等于图片区，按钮落在图片区右下角；
   桌面端再由媒体查询挪到右栏最下面那张小图的右下角。
   `z-index: 1` 是必须的：桌面端它是压在缩略图上的，而 `.shots__thumb` 是
   `position: relative`（当前那张的高亮环要用 ::after 定位），比按钮后出现；
   不给层级的话按钮会被那张 75% 不透明的缩略图盖住、变成一块发暗的雾。 */
.shots__all {
  position: absolute; z-index: 1; right: var(--mb-gap-sm); bottom: 10px;
  display: inline-flex; align-items: center; justify-content: center;
  height: 30px; padding: 0 11px; line-height: 1;
  border-radius: var(--mb-radius-sm); background: rgba(0, 0, 0, .5);
  font-size: var(--mb-font-sm); color: #fff;
  text-decoration: none; white-space: nowrap;
}
.shots__all:hover { background: rgba(0, 0, 0, .68); }
/* 缩略图只在桌面出：手机上横滑就够了，再摆一排缩略图是在小屏幕上抢地方
   （按钮不在这里 —— 窄屏也要能看到画廊入口，见 hero.php 的说明） */
.shots__thumbs { display: none; }

/* ---------- 详情：概览卡 ---------- */
/* 卡片压在头图下沿上一点，两块之间不留一条硬边（同小程序 -48rpx） */
.section--hero { padding-top: 0; }
.section--hero .overview { margin-top: -28px; position: relative; }
.overview--bare { margin-top: 0; }

.detail__title { font-size: var(--mb-font-2xl); font-weight: 700; line-height: 1.3; }
/* 韩文官方名 + 英文名。韩文名对要去当地就诊的人有用（打车、找门牌），不是装饰 */
.detail__alt { margin-top: 4px; font-size: var(--mb-font-md); color: var(--mb-muted); }
.detail__chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: var(--mb-gap); }

/* 价格区间条。它是这页最被惦记的一行，同时是进价目表的入口，所以整条是个链接 */
.detail__band {
  margin-top: var(--mb-gap-lg); padding: var(--mb-gap) var(--mb-gap-lg);
  border-radius: var(--mb-radius-lg); background: var(--mb-accent-soft);
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--mb-gap); flex-wrap: wrap;
}
.detail__band:hover { background: #f7ebd9; }
.detail__band-key { font-size: var(--mb-font-md); color: var(--mb-sub); }
.detail__band-val {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--mb-font-xl); font-weight: 700; color: var(--mb-accent);
}

/* 亮点格子。内容是后台给这家配的标签，不是写死的四句套话 ——
   「正品设备」「专业团队」挂在每一家头上就等于没说，还容易被当成平台背书 */
.hl {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--mb-gap-sm);
  margin-top: var(--mb-gap-lg); padding-top: var(--mb-gap-lg);
  border-top: 1px solid var(--mb-line);
}
.hl__cell {
  display: flex; align-items: center; gap: var(--mb-gap-sm);
  min-width: 0; color: var(--mb-brand-ink);
}
.hl__text {
  min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
  font-size: var(--mb-font-md); color: var(--mb-text);
}
.detail__lead { margin-top: var(--mb-gap-lg); font-size: var(--mb-font-base); color: var(--mb-sub); line-height: 1.7; }
/**
 * 三处 grid 的列都写成 minmax(0, 1fr) 而不是 1fr / 默认的 auto：
 * 1fr 的最小值是 auto，会按内容的固有宽度撑开 —— 价目表是 width:100% 的 <table>，
 * 在按内容算宽的轨道里贡献的是它「一行摆完」的宽度，手机上整页因此被撑到 550px，
 * 右边一截被裁掉、底部操作条跟着错位。列的最小值给成 0，表格才会老老实实折行。
 */
.detail__grid {
  display: grid; gap: var(--mb-gap-lg); grid-template-columns: minmax(0, 1fr);
  align-items: start; margin-top: var(--mb-gap-lg);
}
.detail__side { display: grid; gap: var(--mb-gap-lg); grid-template-columns: minmax(0, 1fr); }
/* 中间那一列。模块顺序跟机构选的模版走，所以间距只能由容器统一给：
   继续靠 .card + .card 这种相邻选择器的话，换个顺序就会有的地方贴上、有的地方空两倍 */
.detail__main {
  display: grid; gap: var(--mb-gap-lg); grid-template-columns: minmax(0, 1fr);
  align-content: start;
}
.detail__main > .card + .card { margin-top: 0; }
.detail__main > .section { padding: 0; }

/* 机构信息。原来是 <table>，现在是 <dl> —— 四行里有三行带动作按钮
   （复制 / 拨打 / 导航），表格单元格里塞按钮排不齐，也不是表格数据 */
.facts { margin: 0; }
.facts__row {
  display: flex; align-items: flex-start; gap: var(--mb-gap);
  padding: 9px 0; border-bottom: 1px solid var(--mb-line);
}
.facts__row:last-child { border-bottom: 0; }
.facts dt {
  display: flex; align-items: center; gap: 5px; flex-shrink: 0; width: 68px;
  font-size: var(--mb-font-base); color: var(--mb-muted);
}
.facts dd {
  margin: 0; flex: 1; min-width: 0; display: flex; align-items: baseline;
  gap: var(--mb-gap); justify-content: space-between; flex-wrap: wrap;
}
.facts__v { min-width: 0; font-size: var(--mb-font-base); line-height: 1.6; }
/* 营业时间备注（午休 / 公休 / 需预约）：跟在时段后面另起一行，比时段本身轻一档 */
.facts__note { color: var(--mb-sub); font-size: var(--mb-font-sm); }
.facts__row--sub dt { color: var(--mb-sub); } /* 韩文/英文地址附注行，带语言标签 */
.facts__link { color: var(--mb-brand-ink); word-break: break-all; }
/* 复制 / 拨打 / 导航。三个都是「行末的小动作」，长得必须一样，
   即便一个是 <button>（复制要 JS）另两个是 <a> */
.facts__act {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px; border: 0; cursor: pointer;
  border-radius: var(--mb-radius-pill); background: var(--mb-brand-soft);
  color: var(--mb-brand-ink); font: var(--mb-font-sm)/1.4 var(--mb-font-family);
}
.facts__act:hover { background: #e7dffa; color: var(--mb-brand-ink); }
.facts__actions { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.facts__act--icon { padding: 6px; border-radius: 999px; } /* 附注行复制按钮：只留图标 */
.facts__act--icon svg { display: block; }

.docs { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--mb-gap); }
.doc__photo {
  width: 100%; aspect-ratio: 3/4; object-fit: contain; object-position: center top;
  border-radius: var(--mb-radius-md); background: var(--mb-fill);
}
.doc__name { margin-top: 6px; font-size: var(--mb-font-base); font-weight: 500; }
.doc__title { font-size: var(--mb-font-sm); color: var(--mb-muted); }
.doc__bio { margin-top: 4px; font-size: var(--mb-font-md); color: var(--mb-sub); line-height: 1.6; }
/* 医生卡整张可点（内页 /doctors/{slug}）。栅格子项本来就按块排，
   这里只是去掉链接的默认样式，hover 只点名字——照片不该跟着变色 */
.docs a { display: block; color: inherit; text-decoration: none; }
.docs a:hover .doc__name { color: var(--mb-brand-ink); }

/* ---------- 医生内页 ---------- */
/* 照片一列 + 资料一列；窄屏一栏不够放就先缩照片列，768 起放大 */
.docpage {
  display: grid; grid-template-columns: 120px minmax(0, 1fr);
  gap: var(--mb-gap); align-items: start;
}
.docpage__meta { min-width: 0; }
.docpage__role { font-size: var(--mb-font-md); color: var(--mb-sub); }
.docpage__k { margin-top: var(--mb-gap); font-size: var(--mb-font-sm); color: var(--mb-muted); }
.docpage__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.docpage__h { margin-top: var(--mb-gap-lg); }
.docpage__cta { margin: var(--mb-gap-lg) 0 0; }
@media (min-width: 768px) {
  .docpage { grid-template-columns: 180px minmax(0, 1fr); gap: var(--mb-gap-lg); }
}

/* ---------- 价目表 ---------- */
.prices { width: 100%; border-collapse: collapse; }
.prices caption { text-align: left; padding-bottom: var(--mb-gap); font-size: var(--mb-font-md); color: var(--mb-muted); }
.prices th, .prices td { padding: 10px 0; border-bottom: 1px solid var(--mb-line); text-align: left; }
.prices thead th { font-size: var(--mb-font-sm); color: var(--mb-muted); font-weight: 400; }
.prices td:last-child, .prices th:last-child { text-align: right; }
.prices tr:last-child td { border-bottom: 0; }
.prices__name { font-size: var(--mb-font-base); }
.prices__tag {
  margin-right: 5px; font-size: var(--mb-font-xs); padding: 1px 6px;
  border-radius: var(--mb-radius-sm); background: var(--mb-brand-soft); color: var(--mb-brand-ink);
}
.prices__meta { display: block; font-size: var(--mb-font-sm); color: var(--mb-muted); }
/* 活动价才给香槟金：一屏里只有这一处是金色，才读得出「这条在打折」 */
.prices__now { font-size: var(--mb-font-lg); font-weight: 700; color: var(--mb-accent); white-space: nowrap; }
.prices__now--plain { color: var(--mb-text); font-weight: 600; }
.prices__was { display: block; font-size: var(--mb-font-sm); color: var(--mb-muted); text-decoration: line-through; }
.prices__meta { display: flex; flex-wrap: wrap; align-items: center; }
/* 「最新收录月份…」与页尾那句免责。都是灰色小字，但不是空态提示，所以不共用 .empty__hint */
.prices__hint {
  margin-top: var(--mb-gap); font-size: var(--mb-font-sm);
  color: var(--mb-muted); line-height: 1.6;
}

/* ---------- 快速筛选（详情页按项目 / 价目表页按月份）---------- */
/**
 * 一排可横滑的胶囊。每一个都是**链接**而不是页内状态：
 * 前台每一组条件都得是一条可分享、可收录的地址（同 parts/filter.php 的规矩）。
 */
.qf {
  display: flex; gap: var(--mb-gap-sm); overflow-x: auto;
  margin-bottom: var(--mb-gap); padding-bottom: 4px;
  scrollbar-width: none;
}
.qf::-webkit-scrollbar { display: none; }
.qf--tabs { margin: var(--mb-gap) 0; }
.qf__chip {
  flex-shrink: 0; display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 14px; border-radius: var(--mb-radius-pill);
  background: var(--mb-fill); color: var(--mb-sub); font-size: var(--mb-font-md);
}
.qf__chip:hover { color: var(--mb-brand-ink); }
.qf__chip--on, .qf__chip--on:hover {
  background: var(--mb-brand); color: #fff; font-weight: 500;
}
.qf__n { font-size: var(--mb-font-xs); font-style: normal; opacity: .7; }

/*
 * 疗程分类默认只露一排，右侧三角可铺开全部项目。只有 JS 确认内容
 * 真的超出时才加这两个 class；没有 JS 时仍保留上面原有的横向滑动降级。
 */
.qf--more {
  position: relative; flex-wrap: wrap; overflow: hidden;
  padding-right: 42px; max-height: 35px;
}
.qf--more.qf--open { max-height: none; }
.qf__more {
  position: absolute; z-index: 1; top: 0; right: 0;
  width: 34px; height: 31px; padding: 0; border: 1px solid var(--mb-line);
  border-radius: var(--mb-radius-pill); background: var(--mb-card);
  color: var(--mb-sub); cursor: pointer;
}
.qf__more:hover { color: var(--mb-brand-ink); border-color: currentColor; }
.qf__more span {
  display: inline-block; width: 0; height: 0;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid currentColor; transition: transform .18s ease;
}
.qf--open .qf__more span { transform: rotate(180deg); }
.qf__more:focus-visible { outline: 2px solid var(--mb-brand); outline-offset: 2px; }

/* ---------- 在售套餐 ---------- */
.goods { margin: 0; list-style: none; }
.goods__row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--mb-gap); padding: 10px 0; border-bottom: 1px solid var(--mb-line);
}
.goods__row:last-child { border-bottom: 0; }
.goods__body { min-width: 0; }
.goods__name { font-size: var(--mb-font-base); line-height: 1.45; }
.goods__meta { margin-top: 3px; font-size: var(--mb-font-sm); color: var(--mb-muted); }
.goods__price { flex-shrink: 0; text-align: right; }

/* ---------- 口碑 ---------- */
.revs { margin: 0; list-style: none; }
.revs__row { padding: 12px 0; border-bottom: 1px solid var(--mb-line); }
.revs__row:last-child { border-bottom: 0; }
.revs__head { display: flex; align-items: baseline; gap: var(--mb-gap-sm); }
.revs__who { font-size: var(--mb-font-base); font-weight: 500; }
.revs__score { font-size: var(--mb-font-sm); color: var(--mb-accent); }
.revs__at { margin-left: auto; font-size: var(--mb-font-sm); color: var(--mb-muted); }
.revs__body {
  margin-top: 5px; font-size: var(--mb-font-md); color: var(--mb-sub); line-height: 1.65;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
/* 「写一条评价」：details/summary 原生折叠，不用 JS。summary 复用 .btn 的样式，
   自己再关掉浏览器默认的三角标记，展开后表单跟其余字段一个间距 */
.revs__submit { margin-top: var(--mb-gap-lg); }
.revs__submit summary { list-style: none; cursor: pointer; width: fit-content; }
.revs__submit summary::-webkit-details-marker { display: none; }
.revs__form { margin-top: var(--mb-gap); }

/* ---------- 简介的展开 / 收起 ---------- */
/**
 * 没有 JS：一个隐藏的 checkbox + 兄弟选择器。
 * 所以 <input> 必须排在标题和正文之前（~ 只能往后找兄弟），见 parts/detail/intro.php。
 */
.intro { position: relative; }
.intro__body {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.intro__flag:checked ~ .detail__lead { -webkit-line-clamp: unset; display: block; }
.intro__toggle { cursor: pointer; }
.intro__toggle:hover { color: var(--mb-brand-ink); }
.intro__close { display: none; }
.intro__flag:checked ~ .section__head .intro__open { display: none; }
.intro__flag:checked ~ .section__head .intro__close { display: inline; }

/* ---------- 价目表页的关键词框 ---------- */
/* GET 表单而不是页内过滤：翻页在服务端，页内只筛得到当前这 50 条 */
/* margin-bottom 不能少：后面紧跟的可能是依疗程分类的 .qf（只有 margin-bottom 没有
   margin-top）、月份页签，或者直接是价目表格，三种情况都得跟搜索框留出间距 */
.pricebar { display: flex; align-items: center; gap: var(--mb-gap-sm); margin: var(--mb-gap) 0; }
.pricebar input {
  flex: 1; min-width: 0; height: 36px; padding: 0 var(--mb-gap);
  border: 1px solid var(--mb-line); border-radius: var(--mb-radius-pill);
  background: var(--mb-card); font-size: var(--mb-font-base); color: var(--mb-text);
}
.pricebar input:focus { outline: 2px solid var(--mb-brand-soft); outline-offset: -2px; }
.pricebar button {
  flex-shrink: 0; height: 36px; padding: 0 var(--mb-gap-lg); border: 0; cursor: pointer;
  border-radius: var(--mb-radius-pill); background: var(--mb-brand); color: #fff;
  font-size: var(--mb-font-base);
}
.pricebar button:hover { background: var(--mb-brand-dark); }
.pricebar__clear { flex-shrink: 0; font-size: var(--mb-font-md); color: var(--mb-muted); }
.pricebar__clear:hover { color: var(--mb-brand-ink); }

/* ---------- 收藏按钮 ---------- */
/**
 * 同一份标记出现两处：手机上在底部操作条里，桌面上在右侧预约卡里。
 * 两处默认 hidden，由 mb-user.js 放出来（收藏是登录态才有意义的动作，
 * 而前台是不起 session 的静态渲染，服务端不知道这次访问登录了没有）。
 */
.fav {
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  border: 0; cursor: pointer; background: transparent; color: var(--mb-sub);
  font: var(--mb-font-base)/1.2 var(--mb-font-family);
}
.fav__icon { font-size: 17px; line-height: 1; color: var(--mb-muted); }
.fav.is-on .fav__icon { color: var(--mb-danger); }
.fav.is-on .fav__text { color: var(--mb-danger); }
.fav[disabled] { opacity: .5; cursor: not-allowed; }
/* 侧栏那颗：跟上面「立即预约」按钮同宽，读起来是一组 */
.fav--side {
  width: 100%; margin-top: var(--mb-gap-sm); padding: 8px 0;
  border-radius: var(--mb-radius-pill); background: var(--mb-bg);
}
.fav--side:hover:not([disabled]) { background: var(--mb-brand-soft); }

/* ---------- 底部操作条（只在手机宽度）---------- */
/**
 * 桌面上右侧那张卡已经有「立即预约」，再钉一条在屏幕底下是把同一个按钮摆两遍，
 * 所以这一条 768px 以上整块隐藏，那颗心在桌面上由 .fav--side 承担。
 */
.dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; align-items: center; gap: var(--mb-gap);
  padding: 8px var(--mb-gap-lg) calc(8px + env(safe-area-inset-bottom));
  background: var(--mb-card); border-top: 1px solid var(--mb-line);
  box-shadow: 0 -2px 12px rgba(27, 27, 27, .06);
}
.dock .fav--dock { flex-direction: column; gap: 2px; flex-shrink: 0; min-width: 48px; }
.dock .fav--dock .fav__text { font-size: var(--mb-font-sm); }
.dock__cta { flex: 1; }
/* 有底部条时页面末尾要留出它的高度，否则最后一块被压住 */
body:has(.dock) .site-foot { padding-bottom: calc(72px + env(safe-area-inset-bottom)); }

/* ---------- 机构站点（二级域名）专有 ---------- */
/* 机构自己的域名下顶部换成机构名 + 它自己的导航，平台名退到页脚一行小字 */
.site-hero {
  /* 中间那一档原来写死成 #efe8fc，模版换了主色之后头图会突然冒出一块紫，
     所以三档全部走 token */
  background: linear-gradient(165deg, var(--mb-brand-wash) 0%, var(--mb-brand-soft) 52%, var(--mb-bg) 100%);
  padding: var(--mb-gap-lg) 0 var(--mb-gap);
}
.site-hero__in { display: flex; align-items: center; gap: var(--mb-gap); flex-wrap: wrap; }
.site-hero__logo {
  width: 44px; height: 44px; flex-shrink: 0; object-fit: cover;
  border-radius: var(--mb-radius-lg); background: var(--mb-card);
}
.site-hero__text { min-width: 0; flex: 1; }
.site-hero__name { font-size: var(--mb-font-2xl); font-weight: 700; line-height: 1.25; }
.site-hero__ko { margin-top: 2px; font-size: var(--mb-font-md); color: var(--mb-sub); }
.site-tabs {
  display: flex; gap: var(--mb-gap-lg); overflow-x: auto;
  padding: var(--mb-gap) 0 0; font-size: var(--mb-font-base);
}
.site-tabs a { flex-shrink: 0; color: var(--mb-sub); padding-bottom: 7px; border-bottom: 2px solid transparent; }
.site-tabs a:hover { color: var(--mb-brand-ink); }
.site-tabs .is-on { color: var(--mb-brand-ink); font-weight: 600; border-bottom-color: var(--mb-brand); }

/* 顶部工具条（语言 / 分享 / 登录）与顶部搜索的样式在 web-site-util.css——
   这个文件已经贴着 20KB 上限，两块新样式放不进来，见那份文件顶部的说明 */

/* ---------- 模版版式 ---------- */
/**
 * 一套模版 = 版式 + 配色 + 模块顺序。配色和顺序是数据（后台改），
 * 版式是这里这几条规则。<body> 上的 tpl-<base> 由 App\Web\Template::bodyClass() 给。
 * 加新版式要同时改那个类的 BASES 常量，只加 CSS 后台是选不到的。
 */

/* 极简：不放封面（PHP 那边就不渲染 img 了），卡片去掉阴影只留细线。
   资料还少的时候，一堆浮起来的空卡片比平铺更显空 */
.tpl-minimal .site-hero { background: var(--mb-card); border-bottom: 1px solid var(--mb-line); }
.tpl-minimal .card { box-shadow: none; border: 1px solid var(--mb-line); }
.tpl-minimal .detail__band { background: transparent; border: 1px solid var(--mb-line); }
.tpl-minimal .detail__band-val { color: var(--mb-text); }

/* 画廊：头图拉高。环境图并进头图轮播之后（见 parts/detail/hero.php），
   这套模版的差异就只剩「照片占更大一块」这一条了 */
.tpl-gallery .shots__img { height: 300px; }

/* 价格优先：价格区间条做成整条主色块，第一屏就把价格说清楚 */
.tpl-pricing .detail__band { background: var(--mb-brand-soft); border: 1px solid var(--mb-brand); }
.tpl-pricing .detail__band dd { font-size: var(--mb-font-2xl); }
.tpl-pricing .prices th, .tpl-pricing .prices td { padding: 12px 0; }

/* ---------- 桌面 ---------- */
@media (min-width: 768px) {
  .detail__grid { grid-template-columns: minmax(0, 1fr) 320px; gap: var(--mb-gap-xl); }
  .docs { grid-template-columns: repeat(6, 1fr); }
  .facts dt { width: 88px; }
  .site-hero__logo { width: 56px; height: 56px; }

  /* 头图：桌面端收进页面主宽度，做成「左边大图、右边竖排小缩略图」——
     之前是贴边占满整个视口宽度，头图在桌面上又比手机高一截，宽高比跟着
     视口宽度走，屏幕越宽裁得越狠，很难控制。收进 `.wrap` 的宽度后宽高比
     稳定在可控范围，缩略图挪到侧边也更像翻相册，不再是贴边走马灯。
     每个缩略图仍然是 #shot-N 锚点，点一下由浏览器把左边的轮播滚过去
     —— 仍然不需要 JS。（下面这套跟着 standard/gallery 两个版式走，
     因为只有这两套会渲染 `.shots`，见 Template::showsCover） */
  /* 头图区在桌面上收成「左大图 + 右竖排缩略图」两栏，**圆角只落在整块图片区的外沿**。
     2026-09-28 用户口径（把 09-27 那两句明确到角）：
       「圆角给整个图片区域，而不仅仅是左侧大图」+「大图的左上角和小图的右上角都有圆角，
       但大图的右上角、小图的左上角不带圆角」，再加大图与小图之间的间隔。
     落法：
       - 左栏 `.shots__stage` 只圆左边两个角 → 大图左上/左下是圆的、右上/右下是直角；
       - 右栏 `.shots__thumbs` 只圆右边两个角 → 右栏外沿上下两个角是圆的，左边不带圆角；
       - 两栏之间留 `--mb-gap`（12px）的缝，缝两侧按口径是直角，露的是页面自己的底；
       - 容器（`.shots`）自己不裁也不圆：它左右各有 24px 内边距，圆角/裁切写在这里
         根本碰不到图片（这正是 09-27 那版「容器上写了圆角、看着却只有大图是圆的」的原因），
         真正生效的是上面那两条分栏规则。 */
  .shots {
    max-width: var(--mb-content-max); margin: 0 auto 0;
    padding: 0 var(--mb-gap-xl);
    display: grid; grid-template-columns: minmax(0, 1fr) 220px;
    gap: var(--mb-gap);
    background: transparent;
  }
  /* 只圆左边两个角（窄屏四个角那条在基础规则里，别删）——
     大图右边那两个角是两栏之间的缝，按 2026-09-28 用户口径不带圆角 */
  .shots__stage {
    grid-column: 1; min-width: 0;
    border-radius: var(--mb-radius-lg) 0 0 var(--mb-radius-lg);
  }
  /* 轮播条本身也不留底色，否则大图没铺到的地方会露出 `--mb-fill` 那条灰边 */
  .shots__track { background: transparent; }
  /* 只有一张图时 hero.php 不出 `.shots__thumbs`（见该文件 $total > 1 判断），
     右边那栏没有内容，大图要把让出来的位置吃掉，不然凭空留一块空白；同时 stage
     与图片恢复四角圆角。多图仍由后面的左右分栏规则各自只圆外沿。 */
  .shots:not(:has(.shots__thumbs)) { grid-template-columns: minmax(0, 1fr); }
  .shots:not(:has(.shots__thumbs)) .shots__stage { border-radius: var(--mb-radius-lg); }
  .shots:not(:has(.shots__thumbs)) .shots__img { border-radius: var(--mb-radius-lg); }
  /* 桌面端大图自己的圆角也收成左边两个角：图片自己那份（基础规则里）是给窄屏留的，
     这里不覆盖的话大图右上/右下会自己圆出来，两栏的缝两侧就不是直角了 */
  .shots__img { height: 380px; border-radius: var(--mb-radius-lg) 0 0 var(--mb-radius-lg); }
  /* 画廊模版在桌面上也要比标准版高一档。这一条必须写在这里：
     `.tpl-gallery .shots__img` 的权重比上面那条高，写在媒体查询外面的话
     桌面上反而会把头图压回 300px —— 比标准版还矮，正好反了 */
  .tpl-gallery .shots__img { height: 460px; }
  .shots__veil { padding: 64px var(--mb-gap-xl) 40px; }
  /* 右栏放**两张**缩略图、带间隔，不出滚动条：两条轨道平分这一栏的高度。
     圆角 + 裁切挂在**这一栏**上、只圆右边两个角：第一张的右上、第二张的右下由它裁出来，
     两张之间那条缝两侧仍是直角（2026-09-28 用户在两个选项里选的是这一种）。
     所以每张缩略图自己不再带圆角、也不留 `border` 内缩 —— 图要铺到这一栏的边上，
     裁出来的圆角才是真的 12px（原来那 2px 透明 border 会把图缩进去，圆角只剩一小段缺口）。
     （按钮不在这条流里，它是 `.shots` 上的绝对定位元素，见 `.shots__all`）。 */
  .shots__thumbs {
    grid-column: 2; display: grid;
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--mb-gap-sm);
    height: 380px; overflow: hidden;
    border-radius: 0 var(--mb-radius-lg) var(--mb-radius-lg) 0;
    padding: 0; background: transparent;
  }
  /* 同 .tpl-gallery .shots__img：画廊模版的缩略图栏要跟着大图一样高 */
  .tpl-gallery .shots__thumbs { height: 460px; }
  /* 桌面端：贴右栏最下面那张小图的右下角。
     定位祖先是 `.shots`（按钮是它的直接子项，见 hero.php）：容器右内边距 24px
     → `right: var(--mb-gap-xl)` 让按钮右端正好落在右栏右沿；
     `bottom: 8px`（= 缩略图之间的间隔）让它与第二张小图的下沿差同样的 8px。
     写在 `.shots__stage` 里的话会被那一层的 `overflow: hidden` 裁掉（09-27 的坑）。 */
  .shots__all { right: var(--mb-gap-xl); bottom: var(--mb-gap-sm); }
  .shots__thumb {
    display: block; position: relative; min-height: 0; line-height: 0;
    border-radius: 0; overflow: hidden;
    background: transparent;   /* 同「去掉图片区的灰底」：没图时也不露 `--mb-fill` */
  }
  .shots__thumb img {
    display: block; width: 100%; height: 100%; object-fit: cover;
    opacity: .75; transition: opacity .15s;
  }
  .shots__thumb:hover img { opacity: 1; }
  /* 「当前这张」的高亮环用 ::after 的 inset 阴影，不用 border ——
     border 会把图挤进去 2px，右栏裁出来的圆角跟着缩水；
     ::after 是定位子项、画在图上，不占位置也不改变图片尺寸 */
  .shots__thumb[aria-current="true"]::after {
    content: ''; position: absolute; inset: 0;
    box-shadow: inset 0 0 0 2px var(--mb-accent);
  }
  .shots__thumb[aria-current="true"] img { opacity: 1; }

  .section--hero .overview { margin-top: -36px; }
  .hl { grid-template-columns: repeat(4, 1fr); }

  /* 底部操作条只属于手机：桌面上「立即预约」在侧栏，收藏在它下面 */
  .dock { display: none; }
  body:has(.dock) .site-foot { padding-bottom: var(--mb-gap-xl); }
}

/* ---------- 详情：头图画廊弹层（.shots-gallery） ----------
   头图右下角「全部照片(N)」点开的整屏画廊。用原生 <dialog>：
   Esc 关闭、焦点收在弹层里、::backdrop 都是浏览器给的，不自己造一套。

   两条开法，互为兜底：
     有 JS → web-gallery.js 拦下 click 调 showModal()，标题栏的 ✕ 走 close()；
     没有 JS → 那颗按钮就是个 href="#shots-gallery" 的锚点，靠下面 :target 那条规则
              把默认 display:none 的 <dialog> 顶出来（此时关闭 = 点遮罩/再点一次链）。
   弹层里所有类名都带 shots-gallery 前缀：`.shots__thumb` 那套是右栏缩略图的
   （桌面媒体查询里给它上了 border / opacity / object-fit），画廊的缩略条不跟着吃。 */
.shots-gallery {
  width: 100vw; max-width: 100vw; height: 100dvh; max-height: 100dvh;
  margin: 0; padding: 0; border: 0; background: transparent; color: #fff;
}
.shots-gallery:target { display: block; }   /* 无 JS 兜底，见文件头注释 */
.shots-gallery::backdrop { background: rgba(0, 0, 0, .82); }
.shots-gallery__head {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px; font-size: var(--mb-font-md);
}
.shots-gallery__title { font-weight: 600; }
.shots-gallery__close {
  margin-left: auto; width: 34px; height: 34px; padding: 0;
  border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(255, 255, 255, .12); color: #fff; font-size: 17px; line-height: 1;
}
.shots-gallery__close:hover { background: rgba(255, 255, 255, .24); }
.shots-gallery__stage {
  position: relative; display: flex; align-items: center; justify-content: center;
  /* 高度自己占满，不按视口算：上下还有标题栏 / 计数 / 缩略条 */
  height: calc(100dvh - 210px);
}
.shots-gallery__img {
  max-width: 100%; max-height: 100%; width: auto; height: auto;
  object-fit: contain; border-radius: var(--mb-radius-sm); background: rgba(255, 255, 255, .04);
}
.shots-gallery__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(0, 0, 0, .42); color: #fff; font-size: 22px; line-height: 1;
}
.shots-gallery__nav:hover { background: rgba(0, 0, 0, .68); }
.shots-gallery__nav--prev { left: 12px; }
.shots-gallery__nav--next { right: 12px; }
.shots-gallery__count {
  margin: 8px 0 6px; text-align: center;
  font-size: var(--mb-font-sm); color: rgba(255, 255, 255, .72);
}
.shots-gallery__thumbs {
  display: flex; gap: var(--mb-gap-sm); padding: 0 16px 14px;
  overflow-x: auto; scrollbar-width: none;
}
.shots-gallery__thumbs::-webkit-scrollbar { display: none; }
.shots-gallery__thumb {
  display: block; flex: 0 0 auto; line-height: 0;
  /* 现在只有这两条列表是链接，32px 的可点高度在手机上要留够 */
  min-height: 44px;
  border-radius: var(--mb-radius-sm); overflow: hidden; background: rgba(255, 255, 255, .08);
  border: 2px solid transparent;
}
.shots-gallery__thumb img {
  display: block; width: 84px; height: 63px; object-fit: cover; opacity: .62;
}
.shots-gallery__thumb:hover img { opacity: 1; }
.shots-gallery__thumb[aria-current="true"] { border-color: #fff; }
.shots-gallery__thumb[aria-current="true"] img { opacity: 1; }
