/* The 3D view is the page. Everything else floats over it as light chrome,
   tinted to whichever display mode is active so the overlay never fights the
   scene it sits on. */

:root {
  --ink: #e8edf3;
  --ink-dim: #93a1b1;
  --panel: rgba(16, 20, 27, 0.82);
  --panel-line: rgba(255, 255, 255, 0.09);
  --accent: #d8a657;
  --radius: 10px;
  --shadow: 0 8px 32px rgba(0, 0, 0, 0.42);
  --font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

/* CAD mode is a light room; the chrome inverts with it. */
body[data-mode="cad"] {
  --ink: #16202c;
  --ink-dim: #5b6b7d;
  --panel: rgba(255, 255, 255, 0.88);
  --panel-line: rgba(20, 32, 46, 0.12);
  --accent: #2f6fb0;
  --shadow: 0 8px 28px rgba(22, 32, 44, 0.16);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  font-family: var(--font);
  color: var(--ink);
  background: #11141a;
}

#stage {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  touch-action: none;
}

svg {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
svg .fill { fill: currentColor; stroke: none; }

/* ── Top bar ────────────────────────────────────────────────────────────── */

.topbar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.1rem;
  pointer-events: none;
}
.topbar > * { pointer-events: auto; }

.wordmark {
  margin: 0;
  font-size: 0.95rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink);
  text-shadow: 0 1px 12px rgba(0, 0, 0, 0.35);
}
body[data-mode="cad"] .wordmark { text-shadow: none; }
.wordmark span { color: var(--accent); }

.segmented {
  display: flex;
  gap: 2px;
  padding: 3px;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
}
.segmented button {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.42rem 0.78rem;
  font: inherit;
  font-size: 0.78rem;
  color: var(--ink-dim);
  background: none;
  border: 0;
  border-radius: 7px;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
.segmented button:hover { color: var(--ink); }
.segmented button.is-active {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ── Parameter panel ────────────────────────────────────────────────────── */

.panel {
  position: fixed;
  top: 4.2rem;
  left: 1.1rem;
  bottom: 5.2rem;
  z-index: 10;
  width: 17.5rem;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
  overflow: hidden;
}

.panel-head {
  padding: 0.85rem 0.95rem 0.6rem;
  border-bottom: 1px solid var(--panel-line);
}
.panel-head h2 {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.panel-note {
  margin: 0.3rem 0 0;
  font-size: 0.7rem;
  color: var(--accent);
}

.panel-body {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.5rem 0.95rem 1rem;
}
.panel-body::-webkit-scrollbar { width: 8px; }
.panel-body::-webkit-scrollbar-thumb {
  background: var(--panel-line);
  border-radius: 4px;
}

.group { margin-top: 0.9rem; }
.group h3 {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.55rem;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.group h3 svg { font-size: 0.95rem; color: var(--accent); }

.row { margin-bottom: 0.68rem; }
.row.is-disabled { opacity: 0.38; }

.row-label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.22rem;
  font-size: 0.78rem;
  cursor: help;
}
.row-label output {
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  color: var(--ink-dim);
}

input[type="range"] {
  width: 100%;
  height: 3px;
  margin: 0.35rem 0;
  appearance: none;
  background: var(--panel-line);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
  appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--panel);
  cursor: grab;
}
input[type="range"]::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border: 2px solid var(--panel);
  border-radius: 50%;
  background: var(--accent);
  cursor: grab;
}
input[type="range"]:disabled { cursor: not-allowed; }

input[type="checkbox"] {
  accent-color: var(--accent);
  width: 0.95rem;
  height: 0.95rem;
  cursor: pointer;
}
.row-label input[type="checkbox"] { margin-right: 0.15rem; }

/* ── Bottom dock ────────────────────────────────────────────────────────── */

.dock {
  position: fixed;
  left: 50%;
  bottom: 1.1rem;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.55rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
  font-size: 0.78rem;
}

.dock-control {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: help;
}
.dock-control input[type="range"] { width: 8rem; margin: 0; }

.dock-button {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.7rem;
  font: inherit;
  font-size: 0.78rem;
  color: var(--ink-dim);
  background: none;
  border: 1px solid var(--panel-line);
  border-radius: 7px;
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}
.dock-button:hover { color: var(--ink); border-color: var(--accent); }

.dock-status {
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--ink-dim);
  min-width: 9rem;
  text-align: right;
}

@media (max-width: 720px) {
  .panel { top: 3.8rem; left: 0.6rem; right: 0.6rem; width: auto; bottom: 6.5rem; }
  .dock { left: 0.6rem; right: 0.6rem; transform: none; justify-content: space-between; }
  .dock-control input[type="range"] { width: 5rem; }
}

/* Compact segmented control and icon toggles in the dock. */
.segmented-sm button { padding: 0.35rem 0.5rem; }
.segmented-sm svg { font-size: 1rem; }

.dock-toggles {
  display: flex;
  gap: 2px;
  padding: 3px;
  border: 1px solid var(--panel-line);
  border-radius: 8px;
}
.dock-toggles button {
  display: flex;
  padding: 0.35rem 0.5rem;
  font-size: 1rem;
  color: var(--ink-dim);
  background: none;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
  transition: background 0.18s, color 0.18s;
}
.dock-toggles button:hover { color: var(--ink); }
.dock-toggles button.is-active {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 22%, transparent);
}

/* ── Measurement checklist ──────────────────────────────────────────────── */

.dock-caret svg { font-size: 0.85rem; }

/* The [hidden] attribute sets display:none from the UA stylesheet, which a
   class-level display:flex overrides. Without this the popover stays on screen
   however correct the JavaScript is. */
.popover[hidden] { display: none; }

.popover {
  position: fixed;
  left: 50%;
  bottom: 4.6rem;
  transform: translateX(-50%);
  z-index: 20;
  width: 22rem;
  max-height: min(60vh, 34rem);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
  overflow: hidden;
}

.popover-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--panel-line);
}
.popover-head h2 {
  margin: 0;
  font-size: 0.7rem;
  font-weight: 650;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.popover-actions { display: flex; gap: 0.3rem; }
.popover-actions button {
  padding: 0.22rem 0.5rem;
  font: inherit;
  font-size: 0.68rem;
  color: var(--ink-dim);
  background: none;
  border: 1px solid var(--panel-line);
  border-radius: 5px;
  cursor: pointer;
  transition: color 0.18s, border-color 0.18s;
}
.popover-actions button:hover { color: var(--ink); border-color: var(--accent); }

.popover-body {
  flex: 1;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0.3rem 0.9rem 0.9rem;
}
.popover-body::-webkit-scrollbar { width: 8px; }
.popover-body::-webkit-scrollbar-thumb {
  background: var(--panel-line);
  border-radius: 4px;
}

.popover-group { margin-top: 0.7rem; }
.popover-group h3 {
  margin: 0 0 0.35rem;
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
}

.popover-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.22rem 0;
  font-size: 0.78rem;
  cursor: pointer;
  border-radius: 5px;
}
.popover-row:hover { color: var(--ink); }
.popover-row input { accent-color: var(--accent); cursor: pointer; }

@media (max-width: 720px) {
  .popover { left: 0.6rem; right: 0.6rem; width: auto; transform: none; }
}

/* Per-parameter icons: the kind of measurement, not a picture of the part.
   Dimmed so they support the label rather than competing with it. */
.row-label svg {
  font-size: 0.95rem;
  color: var(--ink-dim);
  opacity: 0.75;
  flex: none;
}
.row-label > span { flex: 1; }

/* A layout that could not close says why, in place of the engine note. */
.panel-note.is-warning { color: #e0904a; }

/* ── Exports ────────────────────────────────────────────────────────────── */

/* Word buttons rather than icons: STEP and STL are not things anyone would
   recognise from a picture, and the visitor is choosing a file format, not an
   action. */
#exports button {
  padding: 0.35rem 0.6rem;
  white-space: nowrap;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.08em;
}
#exports button:disabled {
  opacity: 0.4;
  cursor: progress;
}
#exports button.is-busy {
  color: var(--accent);
  cursor: progress;
}

/* The kernel's loading state, shown under the panel heading where the engine
   note already lives. A bar rather than a spinner: eighteen megabytes wants a
   readout you can watch move, not a shape that turns whatever happens. */
.kernel-bar {
  height: 2px;
  margin-top: 0.4rem;
  background: var(--panel-line);
  border-radius: 1px;
  overflow: hidden;
}
.kernel-bar span {
  display: block;
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width 0.25s var(--ease-out);
}
.kernel-bar[hidden] { display: none; }

/* A note above the export buttons while the CAD kernel is still starting.
   Placed there rather than in the panel because that is where someone is
   looking when they wonder why nothing has happened yet. */
#exports { position: relative; }

.export-hint {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 0.55rem);
  transform: translateX(-50%);
  margin: 0;
  padding: 0.45rem 0.7rem;
  width: max-content;
  max-width: 17rem;
  font-size: 0.7rem;
  line-height: 1.45;
  text-align: center;
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: 8px;
  box-shadow: var(--shadow);
  backdrop-filter: blur(14px);
  pointer-events: none;
}
.export-hint[hidden] { display: none; }
.export-hint strong { color: var(--accent); font-weight: 600; }

/* The little pointer down to the buttons. */
.export-hint::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: var(--panel-line);
}

/* The stock options popover is a short form, not a long checklist. */
.popover-narrow { width: 15rem; }
.popover-narrow .popover-body { padding-top: 0.6rem; }

/* Headings inside the stock popover. The two sets of numbers are identical in
   name, so without a heading each there is no telling which sheet width is
   which. */
.stock-heading {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  margin: 0.7rem 0 0.2rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.stock-heading:first-child { margin-top: 0; }
.stock-heading small {
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-dim);
}

/* ── Sheet viewer ─────────────────────────────────────────────────────────
   Drawings are white and want to be looked at as paper, so the pages sit on
   a dim backdrop at their own aspect rather than being themed to match the
   app around them. */

.sheets {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  background: rgba(6, 9, 13, 0.72);
  backdrop-filter: blur(3px);
}
.sheets[hidden] { display: none; }

.sheets-panel {
  display: flex;
  flex-direction: column;
  width: min(1400px, 100%);
  height: 100%;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--panel-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.sheets-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.85rem 1.1rem;
  border-bottom: 1px solid var(--panel-line);
}
.sheets-head h2 {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink);
}
.sheets-head p {
  margin: 0.15rem 0 0;
  font-size: 0.75rem;
  color: var(--ink-dim);
}
.sheets-actions { display: flex; align-items: center; gap: 0.5rem; }
.sheets-actions .btn-primary {
  padding: 0.45rem 0.9rem;
  font: inherit;
  font-size: 0.78rem;
  letter-spacing: 0.03em;
  color: #16202c;
  background: var(--accent);
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}
.sheets-actions .btn-primary:disabled { opacity: 0.45; cursor: default; }
#sheet-close {
  padding: 0.2rem 0.55rem;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--ink-dim);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 6px;
  cursor: pointer;
}
#sheet-close:hover { color: var(--ink); }

.sheets-body { display: flex; flex: 1; min-height: 0; }

.sheets-rail {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  width: 10.5rem;
  padding: 0.75rem;
  overflow-y: auto;
  border-right: 1px solid var(--panel-line);
}
.sheet-thumb {
  display: block;
  padding: 0;
  overflow: hidden;
  background: #fff;
  border: 1px solid var(--panel-line);
  border-radius: 4px;
  cursor: pointer;
}
.sheet-thumb img { display: block; width: 100%; }
.sheet-thumb.is-current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.sheet-thumb-label {
  display: block;
  padding: 0.3rem 0.4rem;
  font-size: 0.64rem;
  text-align: left;
  color: var(--ink-dim);
  background: var(--panel);
}
.sheet-thumb.is-current .sheet-thumb-label { color: var(--ink); }
.sheet-thumb-note {
  display: grid;
  place-items: center;
  aspect-ratio: 297 / 210;
  font-size: 1.6rem;
  font-weight: 700;
  color: #b9541f;
  background: #fdf2e6;
}

/* Flex rather than grid, and min-height:0 on both, so that `max-height:100%`
   on the page resolves against the panel instead of against a grid track that
   has already grown to fit the image. Grid let an A3 sheet render at its
   natural size and pushed the bottom of the drawing below the fold. */
.sheets-stage {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-width: 0;
  min-height: 0;
  padding: 1rem;
  overflow: auto;
}
.sheet-page {
  max-width: 100%;
  max-height: 100%;
  min-height: 0;
  object-fit: contain;
  background: #fff;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
}
.sheet-text {
  max-width: 40rem;
  margin: 0;
  padding: 1.2rem;
  font-size: 0.78rem;
  line-height: 1.5;
  white-space: pre-wrap;
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--panel-line);
  border-radius: 6px;
}

.sheet-waiting { max-width: 26rem; text-align: center; color: var(--ink-dim); }
.sheet-waiting p { margin: 1rem 0 0.35rem; font-size: 0.9rem; color: var(--ink); }
.sheet-waiting small { font-size: 0.74rem; line-height: 1.5; }

.sheet-spinner {
  width: 2.2rem;
  height: 2.2rem;
  margin: 0 auto;
  border: 2px solid var(--panel-line);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: sheet-spin 0.8s linear infinite;
}
@keyframes sheet-spin { to { transform: rotate(360deg); } }

/* Someone who has asked for less motion still needs to know it is working. */
@media (prefers-reduced-motion: reduce) {
  .sheet-spinner { animation-duration: 2.4s; }
}

/* A booklet is handed to the browser's own PDF reader, which brings its own
   page rail; ours is hidden for that case rather than sitting empty. */
.sheets-rail[hidden] { display: none; }
.sheet-pdf {
  width: 100%;
  height: 100%;
  background: #fff;
  border: 0;
  border-radius: 4px;
}

/* The plans popover. Wider than the stock one because each output carries a
   line saying what it is for -- three exports behind one button need to say
   which is which at the moment of choosing, not in a tooltip. */
.popover-plans { width: 19rem; }
.popover-plans .popover-body { padding-top: 0.6rem; }

.dock-menu {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.dock-menu svg {
  width: 0.85rem;
  height: 0.85rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.plan-output {
  display: block;
  width: 100%;
  margin-bottom: 0.4rem;
  padding: 0.55rem 0.65rem;
  font: inherit;
  text-align: left;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 6px;
  cursor: pointer;
}
.plan-output:hover:not(:disabled) { border-color: var(--accent); }
.plan-output:disabled { opacity: 0.45; cursor: default; }
.plan-output strong {
  display: block;
  font-size: 0.8rem;
  font-weight: 600;
}
.plan-output small {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.68rem;
  line-height: 1.35;
  color: var(--ink-dim);
}

/* A choice between a few named values, where a slider would imply a range. */
.choice { display: flex; gap: 0.3rem; margin-top: 0.25rem; }
.choice button {
  flex: 1;
  padding: 0.3rem 0;
  font: inherit;
  font-size: 0.72rem;
  color: var(--ink-dim);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 5px;
  cursor: pointer;
}
.choice button.is-current {
  color: var(--ink);
  border-color: var(--accent);
  background: rgba(216, 166, 87, 0.12);
}


/* ── Presets, above the parameters ─────────────────────────────────────── */
.presets {
  padding: 0.6rem 0.95rem 0.55rem;
  border-bottom: 1px solid var(--panel-line);
}
.presets-line {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 0.4rem;
}
.presets select,
.presets input[type="text"] {
  flex: 1;
  min-width: 0;
  padding: 0.3rem 0.4rem;
  font: inherit;
  font-size: 0.74rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 6px;
}
.presets select option,
.presets select optgroup { color: #1b1b1b; }
.btn-small {
  flex: none;
  padding: 0.3rem 0.55rem;
  font: inherit;
  font-size: 0.72rem;
  color: var(--ink);
  background: transparent;
  border: 1px solid var(--panel-line);
  border-radius: 6px;
  cursor: pointer;
}
.presets-line .btn-small:only-of-type,
.presets-line:nth-child(3) .btn-small { flex: 1; }
.btn-small:hover:not(:disabled) { border-color: var(--accent); }
.btn-small:disabled { opacity: 0.4; cursor: default; }
.btn-accent { color: var(--accent); border-color: var(--accent); }
.presets .panel-note { margin: 0; min-height: 1em; }
