/*! (c) Flair Design (flair.design). Part of the flair.design platform, used by this deployment under license — see LICENSE-GRANT.md. */
/* flair3d.css — the 3D rendering platform's own styles: the picker under the
   model (swatch dots, family capsules, rotate button) and the material
   thumbnails. Owner, 2026-09-15: the rendering platform gives other platforms
   only rendering technology, in its own namespace. Every selector here is
   flair3d- and reaches no interface or host class; a platform may restyle
   these pieces from its own sheets. scripts/render-boundary.test.mjs holds it. */

/* The swatch dot and its selection ring. They were the sidebar's project
   colour dots (flair-bar-projects.css) until the picker got its own; the
   geometry is the same 26px dot and 21px ring. Feedback stays in place, by
   brightness, never by scaling: a scaled dot is clipped by the picker's
   horizontal scroller. */
.flair3d-dot {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
  padding: 0;
  outline: none;
  box-sizing: border-box;
  -webkit-appearance: none;
  appearance: none;
  position: relative;
}
.flair3d-dot-ring {
  display: none;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 21px;
  height: 21px;
  border-radius: 50%;
  border: 2px solid #fff;
  pointer-events: none;
}
.flair3d-dot.is-active .flair3d-dot-ring { display: block; }
html:not([data-input="touch"]) .flair3d-dot:hover { filter: brightness(var(--press-hover)); }
.flair3d-dot:active { filter: brightness(var(--press-active)); }
.flair3d-dot-row { display: flex; gap: 8px; }

/* ── 3D 底部居中选择器:上排=当前类目的选项,下排=类目(Gem / Metal)──
   ★配色跟【三维场景的背景】走,不跟应用界面的亮/暗主题走:它浮在渲染画面上,
   场景是白底,所以取比白略深的灰轨 + 白色选中丸。用 --color-bg-panel 那套会在
   暗色模式下变成深色块压在白场景上。场景背景若改档,这三处色值跟着改。
   形制沿用全站胶囊基准:999px 圆角、12px/500 字。
   桌面端默认淡出,鼠标进画面才显形(JS 加 .is-shown);触屏没有 hover,常驻。 */
.flair3d-pick {
  position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%);
  z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 8px;
  opacity: 0; pointer-events: none; transition: opacity 0.25s ease;
}
.flair3d-pick.is-shown { opacity: 1; pointer-events: auto; }
@media (hover: none) and (pointer: coarse) {
  .flair3d-pick { opacity: 1; pointer-events: auto; }
}
.flair3d-pick-row {
  display: flex; align-items: center; gap: 2px;
  padding: 6px; border-radius: 999px;
  background: rgba(0, 0, 0, 0.05); border: none;
}
.flair3d-pick-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 7px 14px; border: none; border-radius: 999px;
  background: transparent; color: rgba(0, 0, 0, 0.55);
  font-family: inherit; font-size: 12px; font-weight: 500; line-height: 1;
  white-space: nowrap; cursor: pointer; transition: background 0.12s, color 0.12s;
}
/* A shape is recognised by looking at it, so the shape row shows the drawing
   and keeps the name on the button (title + aria-label) for hover and for a
   screen reader; nine names in Chinese or French would force the row to scroll.
   Height is the row's own unit, 26px, the same as a colour dot and as a text
   pill (7 + 12 + 7) — switching tab must not make this row grow or shrink. */
.flair3d-pick-btn.is-icon { padding: 2px 6px; }
.flair3d-pick-btn.is-icon svg { display: block; width: 22px; height: 22px; }
.flair3d-pick-btn.is-active { background: #ffffff; color: #1a1a1a; }
html:not([data-input="touch"]) .flair3d-pick-btn:hover{ background: rgba(0, 0, 0, 0.05); color: #1a1a1a; }
html:not([data-input="touch"]) .flair3d-pick-btn.is-active:hover,
html:not([data-input="touch"]) .flair3d-pick-btn.is-active:active{ background: #ffffff; }

.flair3d-pick-btn:active { background: rgba(0, 0, 0, 0.08); color: #1a1a1a; }
/* 选项行里的色圆:浅色圆在浅轨上要有边界,选中环改取深色 */
/* 内距四边相等:圆是正圆,左右与上下留白不等会一眼看出偏心 */
.flair3d-pick .flair3d-dot-row,
.flair3d-pick-row.flair3d-dot-row { gap: 8px; padding: 6px; }
/* 快捷横条的色圆滑区:货架有限库存无限 —— 多出的自己横滑,+ 在滑区外永远可达
   (它是修货架的门,不许被货挤出屏)。横滑形制同 .studio-org-agents(隐滚动条+触摸惯性)。 */
.flair3d-pick-scroll {
  display: flex; align-items: center; gap: 8px;
  overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch;
  max-width: min(52vw, 380px);
}
.flair3d-pick-scroll::-webkit-scrollbar { height: 0; }
/* 滑区的意义是【溢出去滚】,不是把子项压瘦:flex 子项默认可收缩,圆点会被压扁成椭圆 */
.flair3d-pick-scroll > * { flex: 0 0 auto; }
/* 两端导航 chevron:哪侧真有货哪侧才出现(is-on 由滚动位置驱动)。它是提示也是入口 ——
   桌面鼠标没有顺手的横滚手段,点它滚一段。配色随这条给白色画布调的胶囊走。 */
.flair3d-pick-nav {
  display: none; width: 20px; height: 26px; padding: 0; border: none; background: transparent;
  align-items: center; justify-content: center; color: rgba(0, 0, 0, 0.4); cursor: pointer; flex: 0 0 auto;
}
/* 占位与亮灯分开:is-here 只随"整条溢不溢出"变(占布局),is-on 随滚动位置变(只改可见性)
   —— 滚到中间两侧同亮时,整条宽度纹丝不动 */
.flair3d-pick-nav.is-here { display: inline-flex; visibility: hidden; }
.flair3d-pick-nav.is-on { visibility: visible; }
.flair3d-pick-nav svg { width: 14px; height: 14px; }
.flair3d-pick-nav.is-flip svg { transform: rotate(180deg); }
html:not([data-input="touch"]) .flair3d-pick-nav:hover{ color: rgba(0, 0, 0, 0.8); }

.flair3d-pick-nav:active { color: rgba(0, 0, 0, 0.8); }
/* 边缘渐变降级为纯装饰:软化切口,方向跟"哪边还有货"走;提示的职责在箭头,不在它 */
.flair3d-pick-scroll.can-left.can-right {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12px, #000 calc(100% - 12px), transparent);
  mask-image: linear-gradient(to right, transparent, #000 12px, #000 calc(100% - 12px), transparent);
}
.flair3d-pick-scroll.can-left:not(.can-right) {
  -webkit-mask-image: linear-gradient(to right, transparent, #000 12px);
  mask-image: linear-gradient(to right, transparent, #000 12px);
}
.flair3d-pick-scroll.can-right:not(.can-left) {
  -webkit-mask-image: linear-gradient(to left, transparent, #000 12px);
  mask-image: linear-gradient(to left, transparent, #000 12px);
}
/* On a narrow screen the thing that has to fit is the ROW, not the shelf
   inside it. A fixed shelf width is a guess about what else the row carries,
   and the guess broke as soon as a ring builder set arrived: nine shapes and
   five tabs is more than any earlier model put in this bar, and the two round
   buttons beside the tabs — positioned outside the tab row so the tabs stay
   centred, and therefore counting for nothing when the browser centres them —
   hung 7px off both edges of a 412px phone. So: cap the row at the screen and
   let the shelf take what is left after the arrows and the "+", and cap the
   tab row with room for a round button on each side kept out of its width. */
/* No row may be wider than the screen, at any width — and the tab row leaves
   room for a round button on each side, because those two are positioned
   outside it and so count for nothing when the browser centres it. */
.flair3d-pick-row { max-width: calc(100vw - 16px); box-sizing: border-box; }
/* 38px button + 8px of its own margin + 8px of air, each side. */
.flair3d-pick-tabs > .flair3d-pick-row { max-width: calc(100vw - 108px); }
/* The tabs sit closer together than swatches do: 2px, the gap the tab row had
   before it became a shelf. They are also bounded by their row rather than by
   the shelf's own width, or a long set of tabs would scroll on a desktop with
   room to spare. */
.flair3d-pick-scroll.is-tabs { gap: 2px; max-width: none; }
@media (max-width: 768px), (max-height: 500px) {
  .flair3d-pick-scroll { max-width: none; flex: 1 1 auto; min-width: 0; }
}
/* A finger scrolls the shelf by touching it; the arrows are here because a
   desktop mouse has no handy way to scroll sideways. On a touch screen they
   cost 40px of shelf — which is the difference between all nine shapes being
   on screen and two of them being cut off the ends. The edge fade stays: it
   is what says there is more. */
@media (hover: none) and (pointer: coarse) {
  .flair3d-pick-nav.is-here { display: none; }
}
.flair3d-pick .flair3d-dot { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12); }
/* 选中环 = 纯色单环(owner 2026-08-06:否掉描边方案),颜色跟【色块深浅】走、与主题无关:
   深色块(大溪地黑)白环、浅色块(Akoya 白)深环 —— 单一颜色的环压同色块必隐形。
   深浅由 JS 按 hex 亮度定(is-deep/is-pale,快捷栏专用,项目色盘维持真源原样) */
.flair3d-pick .flair3d-dot.is-deep .flair3d-dot-ring { border-color: #fff; }
.flair3d-pick .flair3d-dot.is-pale .flair3d-dot-ring { border-color: #1a1a1a; }
/* 行末的加号:与色圆等大(26px),圆环画在 svg 里,按钮自身不画边框 */
.flair3d-pick-add {
  width: 26px; height: 26px; padding: 0; border: none; background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  color: rgba(0, 0, 0, 0.55); cursor: pointer; flex: 0 0 auto; box-sizing: border-box;
}
/* overflow:visible 与 Studio 那颗 + 同因:icon-plus-circle 的圆环外缘压在 viewBox 边界上,
   不放开裁切会被亚像素一舍削掉外半边(它的注释里记着"圆形缺左上两边")。共享图标,共享前提。 */
.flair3d-pick-add svg { width: 100%; height: 100%; display: block; overflow: visible; }
 html:not([data-input="touch"]) .flair3d-pick-add:hover{ color: rgba(0, 0, 0, 0.85); } 
.flair3d-pick-add:active { color: rgba(0, 0, 0, 0.85); }
/* 环绕播放键:浮在类目胶囊右侧(绝对定位→胶囊始终居中不动),间距同色圆间距 8px;
   外圈等胶囊高 38px,内圆等色圆 26px */
.flair3d-pick-tabs { position: relative; display: flex; align-items: center; }
.flair3d-pick-play {
  position: absolute; left: 100%; top: 50%; transform: translateY(-50%); margin-left: 8px;
  width: 38px; height: 38px; padding: 0; border: none; border-radius: 50%;
  background: rgba(0, 0, 0, 0.05); display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; flex: 0 0 auto;
}
.flair3d-pick-play-in {
  width: 26px; height: 26px; border-radius: 50%; background: #ffffff;
  display: inline-flex; align-items: center; justify-content: center;
  color: rgba(0, 0, 0, 0.55);   /* 同胶囊未选中文字的灰,不随亮暗主题翻转 */
  transition: background 0.12s;
}
.flair3d-pick-play-in svg { width: 18px; height: 18px; display: block; }
/* 停止那颗是【满幅】方块(24 视框画到边),播放三角的墨迹只占视框约四成 ——
   同样 18px 画出来一个比一个大一倍。按墨迹比例把方块收到 8px,两个态大小才一致 */
.flair3d-pick-play.is-active .flair3d-pick-play-in svg { width: 8px; height: 8px; }
.flair3d-pick-play.is-active .flair3d-pick-play-in { background: #1a1a1a; color: #ffffff; }
 html:not([data-input="touch"]) .flair3d-pick-play:hover .flair3d-pick-play-in{ background: #fafafa; } 
.flair3d-pick-play:active .flair3d-pick-play-in { background: rgba(0, 0, 0, 0.08); }
/* The host's slot (FlairHost.pickerStart): the rotate button's mirror image -
   the same 8px to the LEFT of the capsules, centred on them - so the capsules
   stay centred between the two. Its size is the host's. */
.flair3d-pick-start {
  position: absolute; right: 100%; top: 50%; transform: translateY(-50%); margin-right: 8px;
}

/* ── Material thumbnails ── */
.flair3d-matball {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 6px 2px; border: none; background: transparent; cursor: pointer; min-width: 0;
  border-radius: var(--radius-list-row);
}
html:not([data-input="touch"]) .flair3d-matball:hover{ background: var(--color-bg-hover); }

.flair3d-matball:active { background: var(--color-bg-hover); }
.flair3d-matball-sphere {
  width: 40px; height: 40px; border-radius: 50%; position: relative; flex: 0 0 auto;
  box-shadow: inset -6px -8px 12px rgba(0, 0, 0, 0.28), inset 5px 6px 10px rgba(255, 255, 255, 0.5), inset 0 0 0 1px var(--color-border);
}
.flair3d-matball-sphere::after {
  content: ""; position: absolute; left: 18%; top: 12%; width: 34%; height: 26%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0));
}
/* 真材质球照片:自带打光,CSS 画的球形明暗与高光都退场,只留 1px 描边圈住照片 */
.flair3d-matball-sphere.has-img { box-shadow: inset 0 0 0 1px var(--color-border); }
.flair3d-matball-sphere.has-img::after { content: none; }
.flair3d-matball-name {
  font-size: 11px; color: var(--color-text-secondary); max-width: 100%;   /* 图内配文档:名字是要读的,10px 是徽标档 */
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.flair3d-matball.is-on .flair3d-matball-sphere { box-shadow: inset -6px -8px 12px rgba(0, 0, 0, 0.28), inset 5px 6px 10px rgba(255, 255, 255, 0.5), 0 0 0 2px var(--color-text); }
