/* Web-embed layer for the reconstruction viewer.
 *
 * styles.css is the desktop-only sheet that ships with the reconstruction
 * package (`min-width: 1040px`, fixed 344px side column). This file loads after
 * it and adapts the same markup to phones, tablets and iframe embeds without
 * editing the original.
 */

html, body {
  min-width: 0;
  /* 100% inside an iframe is the iframe box; svh keeps phone browser chrome out. */
  height: 100%;
}

#app {
  width: 100%;
  height: 100%;
  max-width: 100%;
}

.panel-toggle { display: none; }

/* Labels that carry a `data-zh` counterpart are wrapped in <i> so the language
   swap can replace the text without clobbering sibling icon spans. They are
   labels, not emphasis. (<span> is not usable here: the package styles
   `.status-pill span` as the status dot.) */
i[data-zh] { font-style: normal; }

.viewer-fallback {
  display: grid;
  gap: 20px;
  align-content: center;
  height: 100%;
  padding: 28px;
  text-align: center;
  background: #0b1217;
}
.viewer-fallback[hidden] { display: none; }
.viewer-fallback img {
  width: 100%;
  max-width: 620px;
  margin-inline: auto;
  border-radius: 10px;
}
.viewer-fallback h2 { margin: 0 0 8px; font-size: 17px; font-weight: 610; }
.viewer-fallback p {
  max-width: 52ch;
  margin: 0 auto;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.6;
}

/* --- tablet: narrow the control column ------------------------------------ */

@media (max-width: 1180px) and (min-width: 861px) {
  #app { grid-template-columns: minmax(0, 1fr) 300px; }
}

/* --- phone / small embed: control column becomes a bottom drawer ----------- */

@media (max-width: 860px) {
  #app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
  }

  .topbar {
    gap: 12px;
    padding: 10px 14px;
  }
  .topbar h1 { font-size: 15px; }
  .topbar .eyebrow { font-size: 9px; letter-spacing: 0.1em; }
  .status-pill { flex-shrink: 0; }

  .view-buttons {
    top: 10px;
    left: 10px;
    right: 10px;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .view-buttons::-webkit-scrollbar { display: none; }
  .view-buttons button {
    flex: 0 0 auto;
    padding: 9px 11px;
    font-size: 12px;
  }

  .hint {
    left: 10px;
    right: 10px;
    bottom: 64px;
    text-align: center;
  }

  /* The drawer sits above the canvas and slides up over it. */
  .panel {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 6;
    max-height: min(72vh, 560px);
    /* Bottom padding clears the floating Controls button, which stays on top of
       the sheet so it can be closed again. */
    padding: 18px 16px calc(78px + env(safe-area-inset-bottom));
    border-left: 0;
    border-top: 1px solid var(--line);
    border-radius: 14px 14px 0 0;
    background: rgba(10, 16, 21, 0.97);
    backdrop-filter: blur(16px);
    box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.45);
    transform: translateY(101%);
    transition: transform 240ms cubic-bezier(0.22, 0.8, 0.3, 1);
    overscroll-behavior: contain;
  }
  .panel[data-open="true"] { transform: none; }

  /* A grab handle, so the sheet reads as a sheet. */
  .panel::before {
    content: "";
    display: block;
    width: 38px;
    height: 4px;
    margin: -6px auto 14px;
    border-radius: 100px;
    background: rgba(161, 195, 212, 0.32);
  }

  .panel-toggle {
    position: absolute;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 7;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    padding: 11px 18px;
    color: #eef4f8;
    border: 1px solid rgba(72, 183, 235, 0.4);
    border-radius: 100px;
    background: rgba(11, 18, 23, 0.92);
    backdrop-filter: blur(14px);
    box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45);
    font-size: 13px;
    font-weight: 640;
    cursor: pointer;
  }
  .panel-toggle::before {
    content: "";
    width: 13px;
    height: 9px;
    border-top: 2px solid var(--accent);
    border-bottom: 2px solid var(--accent);
    box-sizing: content-box;
  }
  .panel-toggle[aria-expanded="true"]::before {
    border-bottom-color: transparent;
    transform: translateY(3px);
  }

  /* Touch targets: the shipped sheet is sized for a mouse. */
  .wide-button { min-height: 46px; }
  input[type="range"] { height: 30px; }
  label { font-size: 13px; margin: 18px 0 8px; }
  .process-card > p:not(.section-label) { font-size: 12px; min-height: 0; }
  .part-card p:not(.section-label) { font-size: 13px; min-height: 0; }

  footer {
    padding: 5px 14px;
    font-size: 9px;
    /* 三段挤在 375px 一行里会互相截断,让它换行、行高自适应。 */
    flex-wrap: wrap;
    row-gap: 2px;
    align-items: baseline;
  }
  footer span:first-child { display: none; }
  /* viewer-host.js 把这句搬进控制条了(页脚在固定条后面看不见),所以这里不再
     为页脚里的它留位置。 */
  .mobile-bar .caveat {
    order: 99;
    margin: 0;
    color: #6a7d87;
    font-size: 9.5px;
    line-height: 1.45;
    text-transform: none;
    letter-spacing: 0.01em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* --- back control (standalone page only) ---------------------------------- */

.viewer-back {
  flex: none;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  margin-right: 4px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.04);
  color: #eef4f8;
  font-size: 17px;
  line-height: 1;
  text-decoration: none;
}
.viewer-back:hover,
.viewer-back:focus-visible {
  background: rgba(72, 183, 235, 0.18);
  border-color: var(--accent);
}

/* Host overlays park a close button in the top-right corner. */
body.is-embedded .topbar { padding-right: 62px; }

/* The topbar is space-between with two children; adding a third would centre
   the title. Push everything after the title to the right instead. */
body.has-back .topbar { gap: 12px; }
body.has-back .topbar > div:not(.status-pill) { margin-right: auto; }

@media (max-width: 860px) {
  .viewer-back { width: 40px; height: 40px; }
}

/* --- phone: one compact control bar, everything else on defaults ---------- */

/* The shipped panel is a full control desk: five sliders, six display toggles,
   a part inspector. On a phone that is a wall of controls in front of the thing
   people came to look at. viewer-host.js MOVES the two that matter — the
   production sequence and the cut-away — into #mobileBar (moves, not clones, so
   every listener viewer.js bound still fires) and this hides the rest. The
   model keeps running on its defaults. */
@media (max-width: 860px) {
  body.compact-controls .panel,
  body.compact-controls .panel-toggle,
  body.compact-controls .hint { display: none !important; }

  body.compact-controls #app {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
  }

  .mobile-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 8;
    display: grid;
    gap: 8px;
    padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
    border-top: 1px solid var(--line);
    background: rgba(10, 16, 21, 0.94);
    backdrop-filter: blur(16px);
    box-shadow: 0 -14px 40px rgba(0, 0, 0, 0.5);
  }

  .mobile-bar-stage {
    display: flex;
    align-items: baseline;
    gap: 10px;
    min-width: 0;
  }
  .mobile-bar-stage h2 {
    flex: 1;
    min-width: 0;
    margin: 0;
    font-size: 13px;
    font-weight: 620;
    line-height: 1.35;
    color: #eef4f8;
    /* Stage names run long; two lines then clip, so the bar never grows. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .mobile-bar-stage output {
    flex: none;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
  }

  .mobile-bar-row {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  .mobile-bar-row input[type="range"] {
    flex: 1;
    min-width: 0;
    height: 34px;
    margin: 0;
  }
  /* Icon-only buttons: 46px is the smallest comfortable thumb target. */
  .mobile-bar-row .wide-button {
    flex: none;
    width: 46px;
    min-height: 46px;
    padding: 0;
    display: grid;
    place-items: center;
    margin: 0;
  }
  /* viewer.js rewrites the play button's label as a bare text node, so hide by
     zeroing the type rather than by selecting an element that may not exist. */
  .mobile-bar-row .wide-button { font-size: 0; }
  .mobile-bar-row .wide-button i { display: none; }
  .mobile-bar-row .wide-button .icon { margin: 0; font-size: 15px; }

  /* Give the canvas the bar's height back so nothing sits under it. */
  body.compact-controls .viewport { padding-bottom: 132px; }
  body.compact-controls .view-buttons { bottom: auto; }
}

/* Entry-level phones (Tecno/itel class, 320 CSS px) are a real slice of the
   target markets: claw some width back for the slider from the buttons. */
@media (max-width: 360px) {
  .mobile-bar { padding-left: 10px; padding-right: 10px; }
  .mobile-bar-row { gap: 8px; }
  .mobile-bar-row .wide-button { width: 42px; min-height: 42px; }
}

/* Landscape phone: stack the bar into a single row to keep the canvas usable. */
@media (max-width: 860px) and (max-height: 480px) {
  .mobile-bar { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  .mobile-bar-stage h2 { -webkit-line-clamp: 1; }
  body.compact-controls .viewport { padding-bottom: 96px; }
}

@media (max-width: 420px) {
  .topbar h1 { font-size: 13.5px; }
  .status-pill { display: none; }
}

/* Landscape phone: the drawer would swallow the canvas, so cap it harder. */
@media (max-width: 860px) and (max-height: 480px) {
  .panel { max-height: 82vh; }
  .hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .panel { transition: none; }
}

/* --- 页脚免责说明 ---------------------------------------------------------
 * 「3D 仅供示意」这句必须每台设备都看得见,所以它在页脚而不在面板里 —— 手机上
 * (compact-controls)整块侧面板是 display:none 的,写在面板里等于对手机访客没写。
 * 页脚原来那句「还原重点」讲的是这次重建做到了什么,在手机上本来就藏掉;这一句
 * 相反,窄屏时留下来的应该是它。 */
/* 三段之间要有排水沟 —— 900px 左右三段会顶到一起,文字贴文字比换行难看得多。 */
footer { gap: 18px; }

footer .caveat {
  text-transform: none;
  letter-spacing: 0.01em;
  color: #6a7d87;
}
