:root {
  --bg: #f2f2f2;
  --panel: rgba(255, 255, 255, 0.94);
  --panel-2: #f4f4f4;
  --border: #e0e0e0;
  --text: #111111;
  --muted: #6b7280;
  --accent: #e8873b;
  --font-display: 'Roboto', system-ui, sans-serif;
  --font-mono: 'Roboto Mono', ui-monospace, monospace;
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); font-family: var(--font-display); overflow: hidden; }
#scene {
  position: absolute;
  inset: 0;
  display: block;
  width: 100vw;
  height: 100vh;
}

#header-bar {
  position: absolute;
  top: 24px;
  left: 20px;
  right: 20px;
  height: 48px;
  z-index: 20; /* higher than #left-panel/#export-panel/#hud's 10 below — they come later in the DOM, so at equal z-index they'd otherwise win the stacking order and cover the mobile dropdown menu (a child of #header-bar) */
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.15);
  padding: 0 28px;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.header-nav {
  display: flex;
  align-items: center;
  gap: 32px;
  width: 100%;
}
.header-nav-item {
  font-size: 14px;
  font-weight: 500;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
  transition: color 0.12s ease;
}
.header-nav-item:hover { color: var(--accent); }

/* Default (desktop) display for the links wrapper — makes it behave
   exactly like the individual <a> tags used to (each its own flex item
   with .header-nav's own 32px gap) now that they're grouped inside this
   div for the mobile dropdown. Without this explicit flex+gap, the div
   would fall back to its default block display, breaking the desktop
   row into a single bunched-up box. */
#header-nav-links { display: flex; align-items: center; gap: 32px; }

/* Hidden on desktop — shown only inside the @media (max-width: 760px)
   block below, which also defines its actual look (flex/gap/etc). */
#header-menu-toggle { display: none; }

.header-brand {
  color: var(--accent);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
  padding-right: 20px;
  border-right: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: 6px;
}
.header-brand:hover { opacity: 0.8; }
.header-logo-mark {
  height: 30px;
  width: auto;
  display: block;
}
.header-logo-right {
  display: flex;
  align-items: center;
  margin-left: auto;
}

#hud {
  position: absolute;
  top: 92px;
  left: 20px;
  z-index: 10;
}

.back {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
  font-size: 13px;
  font-weight: 600;
  padding: 10px 14px;
  border-radius: 8px;
  backdrop-filter: blur(8px);
  display: block;
  width: 280px;
  box-sizing: border-box;
  text-align: center;
}
.back:hover { border-color: var(--accent); }

#export-panel {
  position: absolute;
  top: 92px; /* matches #hud ("Terug naar kaart") — takes the spot #hud-info used to occupy, now removed */
  right: 20px;
  z-index: 10;
  width: 240px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px;
  backdrop-filter: blur(8px);
}

#geometrySelectBtn {
  flex: 1 1 100%;
}

#formatSelectBtn {
  flex: 1 1 100%;
}

#export-format {
  flex: 1 1 100%;
  min-width: 0;
}

#export-btn {
  flex: 1 1 100%;
}

#buy-credit-btn {
  flex: 1 1 100%;
}

#buy-credit-row {
  flex: 1 1 100%;
}

#export-dxf-btn {
  flex: 1 1 100%;
}

/* Left side, matching index.html's #panel: full height, same width,
   same white/rounded/shadow styling and left inset. */
#left-panel {
  position: absolute;
  top: 144px;
  left: 20px;
  bottom: 20px;
  width: 280px;
  z-index: 10;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 16px;
  overflow-y: auto;
  box-shadow: 0 20px 50px rgba(0,0,0,0.15);
}

#layers-panel {
  height: 100%;
}

.layers-title {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.1em;
  color: var(--accent);
  text-transform: uppercase;
  margin-bottom: 8px;
}

.layer-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 0;
  font-size: 13px;
  color: var(--text);
  user-select: none;
}

.layer-row input[type="checkbox"] {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.layer-swatch {
  width: 11px;
  height: 11px;
  border-radius: 3px;
  flex-shrink: 0;
  border: 1px solid rgba(255, 255, 255, 0.25);
}

.layer-label {
  flex: 1;
}

.layer-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
}

.layers-empty {
  font-size: 12px;
  color: var(--muted);
}

.layer-category {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-transform: uppercase;
  margin-top: 10px;
  padding-bottom: 2px;
}
.layer-category:first-child { margin-top: 0; }

.layer-category-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 4px 0;
}
.layer-category-row:first-child { margin-top: 0; }
.layer-category-row input[type="checkbox"] {
  accent-color: var(--accent);
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}
.layer-category-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--text);
  flex: 1;
}
.layer-category-row .layer-count {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--muted);
  flex-shrink: 0;
}
.layer-collapse-btn {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 20px;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  line-height: 1;
  border-radius: 6px;
}
.layer-collapse-btn:hover { color: var(--accent); background: rgba(255,255,255,0.05); }

.layer-category-children {
  overflow: hidden;
}
.layer-category-children.collapsed {
  display: none;
}

.layer-supergroup-row {
  margin-top: 14px;
  padding-top: 10px;
  border-top: 1px solid var(--border);
}
.layer-supergroup-row:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.layer-supergroup-row .layer-category-label {
  font-size: 13px;
  letter-spacing: 0.02em;
  color: var(--accent);
}
.layer-supergroup-children {
  padding-left: 18px;
}
.layer-supergroup-children .layer-category-row {
  margin-top: 6px;
}

.layer-row.indent {
  padding-left: 40px;
}

.layer-label {
  cursor: pointer;
}
.layer-label:hover { color: var(--accent); }

.layer-detail {
  font-size: 12px;
  color: var(--muted);
  line-height: 1.5;
  padding: 2px 0 10px 22px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 2px;
}
.layer-detail .stat { color: var(--text); font-family: var(--font-mono); }

#info-panel {
  position: absolute;
  bottom: 106px; /* clears the #info-btn/#pegman-wrap row, same clearance as #help-panel uses for the same reason */
  right: 20px;
  z-index: 15;
  width: 240px;
  max-height: 45vh;
  background: var(--panel);
  border: 1px solid var(--accent);
  border-radius: 8px;
  backdrop-filter: blur(8px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#info-panel.hidden { display: none; }

.info-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 12px 14px 10px;
  border-bottom: 1px solid var(--border);
}
#info-close {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  padding: 2px 6px;
}
#info-close:hover { color: var(--text); }

#info-content {
  overflow-y: auto;
  padding: 4px 14px 12px;
}

.info-row {
  display: flex;
  flex-direction: column;
  gap: 2px;
  font-size: 12px;
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
}
.info-row .k { color: var(--muted); font-family: var(--font-mono); }
.info-row .v { color: var(--text); overflow-wrap: anywhere; }
.info-row .v a { color: var(--accent); }

#geometrySelectBtn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#geometrySelectBtn:disabled { opacity: 0.35; cursor: not-allowed; }

#formatSelectBtn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
#formatSelectBtn:disabled { opacity: 0.35; cursor: not-allowed; }
#geometrySelectBtn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
#geometrySelectSummary {
  font-family: var(--font-mono);
  font-weight: 400;
  color: var(--muted);
}

#export-format {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 8px;
}

#top-controls-row {
  display: flex;
  gap: 8px;
  margin-bottom: 14px;
}
#top-controls-row > * { flex: 1 1 0; min-width: 0; } /* min-width:0 so a long "Stijl: Standaard" option doesn't force the row wider than the panel */

#style-select {
  width: 100%;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 14px;
  cursor: pointer;
}

#realheight-toggle-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

#terrain-thickness-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: -6px 0 14px; /* pulls up snug under style-select, same spacing convention as the row it replaces when hidden */
  font-size: 11px;
  color: var(--text);
}
#terrain-thickness-row.hidden { display: none; }
#terrain-thickness-row label { flex: 1 1 auto; line-height: 1.3; }
#terrain-thickness-input {
  width: 56px;
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 6px;
  text-align: right;
}

#stl-scale-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: -6px 0 14px; /* same convention as #terrain-thickness-row above — pulls up snug under the row it sits below when both are visible */
  font-size: 11px;
  color: var(--text);
}
#stl-scale-row.hidden { display: none; }
#stl-scale-row label { flex: 1 1 auto; line-height: 1.3; }
#stl-scale-input {
  width: 64px;
  flex: 0 0 auto;
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 6px;
  text-align: right;
}

/* ---- PDF export settings — paper size/orientation/scale + the frame
   overlay's center control. Same conditional-row pattern as
   #stl-scale-row above (shown only while a pdf format checkbox is
   selected — see updateFormatSelectSummary in viewer.js), but stacked
   (own column) rather than a single row, since three selects + a
   button + a readout doesn't fit one line at this panel width. ---- */
#pdf-settings-row {
  flex: 1 1 100%; /* #export-panel uses align-items:center, not stretch — every direct child needs this explicitly, same as #geometrySelectBtn/#formatSelectBtn/#export-btn etc. above */
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: -6px 0 14px;
  font-size: 11px;
  color: var(--text);
}
#pdf-settings-row.hidden { display: none; }
.pdf-settings-selects {
  display: flex;
  gap: 6px;
}
.pdf-settings-selects select,
.pdf-settings-selects button {
  flex: 1 1 0;
  width: 0; /* combined with flex-grow above — some browsers still size a bare <select> by its content instead of the flex-basis otherwise, leaving the row left-aligned with unused space on the right rather than filling the panel */
  min-width: 0;
  font-family: var(--font-display);
  font-size: 11px;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 4px;
}
.pdf-settings-selects button {
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.pdf-settings-selects button:hover { border-color: var(--accent); }
#pdf-frame-toggle-btn[aria-pressed="true"] {
  background: var(--accent);
  color: #1a1206;
  border-color: var(--accent);
}

/* Floating readout of the PDF frame's real-world size, positioned every
   frame (see updatePdfFrameLabelPosition in viewer.js) directly over the
   frame's on-screen location in the 3D view itself, rather than living
   in the settings panel — so it reads naturally as "this is the size of
   that rectangle" instead of a disconnected number in a side panel.
   Fixed CSS pixel size (not an in-scene sprite) so it stays equally
   readable regardless of zoom level or frame size. */
#pdf-frame-label {
  position: fixed;
  left: 0;
  top: 0;
  transform: translate(-50%, -100%);
  pointer-events: none;
  z-index: 5;
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 600;
  color: #1a1a1a;
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid rgba(0, 0, 0, 0.15);
  border-radius: 6px;
  padding: 4px 9px;
  white-space: nowrap;
}
#pdf-frame-label.hidden { display: none; }

/* ---- Kadaster zoom-gate distance slider — hidden in 3D Print mode
   (no Kadaster geometry exists there at all), same conditional-row
   pattern as #terrain-thickness-row/#sun-rotate-row above. Raises
   PARCEL_VISIBILITY_DISTANCE (viewer.js) so parcels/kadastrale
   grenzen/labels can be made visible from farther away than the
   180m default — useful in top view, where the camera is often much
   higher up than the everyday oblique orbit view. Label gets its own
   line (not sharing a row with the slider) — a single flex row
   overflowed the panel width, since unlike "Zonrichting" this label
   doesn't have room to shrink. ---- */
#kadaster-distance-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: -6px 0 14px;
  font-size: 11px;
  color: var(--text);
}
#kadaster-distance-row.hidden { display: none; }
#kadaster-distance-row label { line-height: 1.3; }
.kadaster-distance-control {
  display: flex;
  align-items: center;
  gap: 8px;
}
#kadaster-distance-input {
  flex: 1 1 auto;
  min-width: 0;
}
#kadaster-distance-value {
  flex: 0 0 auto;
  width: 44px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 11px;
}

/* Time-of-day / month sliders (see #sun-time-row / #sun-month-row) —
   same layout pattern as .kadaster-distance-control above, reused
   rather than duplicated under a new name since it's visually and
   structurally identical (slider + right-aligned value readout). */
#sun-time-row, #sun-month-row {
  flex: 1 1 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: -6px 0 14px;
  font-size: 11px;
  color: var(--text);
}
#sun-time-row.hidden, #sun-month-row.hidden { display: none; }
#sun-time-row label, #sun-month-row label { line-height: 1.3; }
.sun-slider-control {
  display: flex;
  align-items: center;
  gap: 8px;
}
#sun-time-input, #sun-month-input {
  flex: 1 1 auto;
  min-width: 0;
}

/* ---- Consistent range-slider look across every browser ----
   accent-color alone (what these three inputs used to rely on) only
   tints the thumb/filled portion in browsers that support it, and
   leaves the UNFILLED track background to each browser's own default —
   confirmed live as the cause of a real bug: Firefox's default happens
   to be a light grey (looked fine), Edge/Chromium's default rendered
   near-black (looked broken). Fully custom track+thumb styling here
   replaces both browsers' native rendering with one consistent look.

   The filled (left-of-thumb) portion needs two different techniques:
   Firefox exposes ::-moz-range-progress directly, so its fill is pure
   CSS. WebKit/Chromium has no equivalent pseudo-element — its fill
   comes from a linear-gradient on the track whose split point is driven
   by the --range-progress custom property, which viewer.js's
   updateRangeFillProgress() keeps in sync with the input's value on
   every 'input' event (and once on load). */
#kadaster-distance-input,
#sun-time-input,
#sun-month-input {
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  cursor: pointer;
}

#kadaster-distance-input::-webkit-slider-runnable-track,
#sun-time-input::-webkit-slider-runnable-track,
#sun-month-input::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(
    to right,
    var(--accent) 0%,
    var(--accent) var(--range-progress, 50%),
    var(--border) var(--range-progress, 50%),
    var(--border) 100%
  );
}
#kadaster-distance-input::-moz-range-track,
#sun-time-input::-moz-range-track,
#sun-month-input::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}
#kadaster-distance-input::-moz-range-progress,
#sun-time-input::-moz-range-progress,
#sun-month-input::-moz-range-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--accent);
}

#kadaster-distance-input::-webkit-slider-thumb,
#sun-time-input::-webkit-slider-thumb,
#sun-month-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
  margin-top: -6px; /* centers the 16px thumb on the 4px track: (4px - 16px) / 2 */
  cursor: pointer;
}
#kadaster-distance-input::-moz-range-thumb,
#sun-time-input::-moz-range-thumb,
#sun-month-input::-moz-range-thumb {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.25);
  cursor: pointer;
}
#sun-time-value, #sun-month-value {
  flex: 0 0 auto;
  width: 44px;
  text-align: right;
  font-family: var(--font-mono);
  font-size: 11px;
}

#export-style-select {
  width: 100%;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 600;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  cursor: pointer;
}

#shadow-toggle-btn, #axo-toggle-btn, #topview-toggle-btn, #realheight-toggle-btn {
  width: 100%;
  font-family: var(--font-display);
  font-size: 10px;
  font-weight: 600;
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 6px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#shadow-toggle-btn:hover, #axo-toggle-btn:hover, #topview-toggle-btn:hover, #realheight-toggle-btn:hover { border-color: var(--accent); }
#realheight-toggle-btn { font-size: 9px; } /* "Werkelijke-hoogte" overflows the button at the shared 10px size — the other three fit fine, so only this one needs it */
#shadow-toggle-btn[aria-pressed="true"], #axo-toggle-btn[aria-pressed="true"], #topview-toggle-btn[aria-pressed="true"], #realheight-toggle-btn[aria-pressed="true"] {
  background: var(--accent);
  color: #1a1206;
  border-color: var(--accent);
}

#export-btn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  background: var(--accent);
  color: #1a1206;
  border: none;
  border-radius: 6px;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
}
#export-btn:disabled { opacity: 0.35; cursor: not-allowed; }
/* Applied only while #export-btn-label briefly shows the longer post-
   export confirmation text ("Gratis (al betaald voor deze scene)" /
   "N credits gebruikt") — see updateExportButtonLabel in viewer.js.
   That text is noticeably longer than "Exporteren"/"Exporteren (N cr.)",
   and with the button's own white-space:nowrap could otherwise run past
   the button's edges. */
#export-btn-label.compact { font-size: 11px; }
#export-btn-dots {
  display: inline-block;
  text-align: left;
  white-space: pre;
}
#export-btn.exporting #export-btn-dots { min-width: 30px; }

#buy-credit-btn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  cursor: pointer;
}
#buy-credit-btn:hover { border-color: var(--accent); color: var(--accent); }
#export-btn:hover:not(:disabled) { filter: brightness(1.05); }

#buy-credit-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
#buy-credit-label {
  font-family: var(--font-display);
  font-size: 12px;
  color: var(--muted);
}
#buy-credit-stepper {
  display: flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
#buy-credit-minus, #buy-credit-plus {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  background: var(--panel-2);
  border: none;
  width: 28px;
  height: 28px;
  cursor: pointer;
  line-height: 1;
}
#buy-credit-minus:hover, #buy-credit-plus:hover { background: var(--accent); color: #1a1206; }
#buy-credit-minus:disabled, #buy-credit-plus:disabled { opacity: 0.35; cursor: not-allowed; background: var(--panel-2); color: var(--text); }
#buy-credit-qty {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  color: var(--text);
  min-width: 28px;
  text-align: center;
}

#export-dxf-btn {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 14px;
  cursor: pointer;
  white-space: nowrap;
}
#export-dxf-btn:disabled { opacity: 0.35; cursor: not-allowed; }
#export-dxf-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }

#empty-state {
  position: absolute;
  inset: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}
#empty-state.hidden { display: none; }
.card {
  text-align: center;
  color: var(--text);
  max-width: 320px;
}
.card h1 { font-size: 20px; margin-bottom: 8px; }
.card p { color: var(--muted); font-size: 14px; margin-bottom: 20px; }
.button {
  display: inline-block;
  background: var(--accent);
  color: #1a1206;
  font-weight: 600;
  text-decoration: none;
  padding: 10px 18px;
  border-radius: 8px;
  font-size: 13px;
}

#error-banner {
  position: absolute;
  bottom: 20px;
  left: 20px;
  right: 20px;
  z-index: 30;
  background: rgba(40, 15, 15, 0.95);
  border: 1px solid #a44;
  color: #ffdede;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.5;
  padding: 14px 40px 14px 16px;
  border-radius: 8px;
  max-height: 40vh;
  overflow-y: auto;
  white-space: pre-wrap;
}
#error-banner.hidden { display: none; }
#error-banner b { color: #ff9d9d; }
#error-banner-close {
  position: absolute;
  top: 8px;
  right: 10px;
  background: transparent;
  border: none;
  color: #ffdede;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 6px;
  opacity: 0.7;
}
#error-banner-close:hover { opacity: 1; }

#attribution {
  position: absolute;
  bottom: 20px; /* aligned with #left-panel's own bottom:20px, per request — was 8px */
  right: 20px; /* matches #export-panel's right edge, instead of the previous 12px */
  z-index: 35;
  font-family: var(--font-mono);
  font-size: 10px;
}
#attribution a {
  color: var(--muted);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.7);
  padding: 2px 6px;
  border-radius: 4px;
}
#attribution a:hover { color: var(--text); }

/* ---- Geometry selection: dropdown anchored to its own button (not a
   full-screen modal), independent of both the layer panel and the
   export button ---- */
.geometry-select-wrap {
  position: relative;
  flex: 1 1 100%;
}
#geometrySelectBtn { width: 100%; }
#formatSelectBtn { width: 100%; }

.geometry-dropdown {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  width: 100%;
  max-height: 380px;
  z-index: 50;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.25);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.geometry-dropdown.hidden { display: none; }

.ifc-select-all-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  font-weight: 600;
  font-size: 13px;
  cursor: pointer;
  flex-shrink: 0;
}
.ifc-select-all-row input { width: 15px; height: 15px; accent-color: var(--accent); }

.modal-list {
  flex: 1;
  overflow-y: auto;
  padding: 4px 16px;
  min-height: 0;
}
.ifc-type-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
  font-size: 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.ifc-type-row:last-child { border-bottom: none; }
.ifc-type-row input { width: 14px; height: 14px; accent-color: var(--accent); flex-shrink: 0; }

.format-hint {
  font-size: 11px;
  color: var(--muted);
  padding: 0 0 8px 24px;
  margin-top: 3px;
  line-height: 1.4;
}

.modal-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  flex-shrink: 0;
}
.modal-summary { font-size: 11px; color: var(--muted); }
#ifcSelectConfirm {
  background: var(--accent);
  color: #1a1206;
  border: none;
  border-radius: 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  padding: 6px 14px;
  cursor: pointer;
}
#ifcSelectConfirm:disabled { opacity: 0.4; cursor: not-allowed; }

/* ---- Confirm modal: replaces the browser's native confirm() dialog
   (which can't be styled and looks out of place) for things like the
   "this export costs N credits" prompt ---- */
#confirmModalBackdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgba(0, 0, 0, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
}
#confirmModalBackdrop.hidden { display: none; }

#confirmModal {
  width: min(420px, calc(100vw - 40px));
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3);
  padding: 20px;
}

#confirmModalTitle {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 15px;
  color: var(--text);
  margin-bottom: 10px;
}

#confirmModalMessage {
  font-size: 13px;
  line-height: 1.6;
  color: var(--text);
  white-space: pre-wrap;
}

#confirmModalFooter {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
}

#confirmModalCancel {
  background: var(--panel-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  padding: 7px 16px;
  cursor: pointer;
}
#confirmModalCancel:hover { border-color: var(--accent); }
#confirmModalCancel.hidden { display: none; }
#buy-credit-row.hidden { display: none; }
#buy-credit-btn.hidden { display: none; }

#confirmModalOk {
  background: var(--accent);
  color: #1a1206;
  border: none;
  border-radius: 6px;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 12px;
  padding: 7px 16px;
  cursor: pointer;
}
#confirmModalOk:hover { opacity: 0.9; }

/* ---- Measure tool — same row as #pegman-wrap/#info-btn, one slot left
   of pegman (its own 48px width + 12px gap, same reasoning as pegman's
   own right:76px positions it left of #info-btn). ---- */
#measure-toggle-btn {
  position: absolute;
  bottom: 52px; /* same row as #pegman-wrap/#info-btn */
  right: 136px; /* pegman's right:76px + pegman's own 48px width + 12px gap */
  z-index: 20;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#measure-toggle-btn:hover { border-color: var(--accent); }
#measure-toggle-btn[aria-pressed="true"] { background: var(--accent); color: #1a1206; border-color: var(--accent); }

#measure-clear-btn {
  position: absolute;
  bottom: 104px; /* clears #measure-toggle-btn: 52px bottom + 44px height + 8px gap */
  right: 136px;
  z-index: 20;
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  padding: 6px 12px;
  border-radius: 8px;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15);
  white-space: nowrap;
}
#measure-clear-btn:hover { border-color: var(--accent); }

/* ---- Street-view-style walk mode (pegman drag-drop + WASD/mouse-look) ---- */
#pegman-wrap {
  position: absolute;
  bottom: 52px; /* clears #attribution (bottom:20px + its own ~24px height) sitting below it */
  right: 76px; /* left of #info-btn: its own 44px width + 20px right + 12px gap */
  z-index: 20;
}
#pegman-btn {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid #fff;
  box-shadow: 0 4px 14px rgba(0,0,0,0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
}
#pegman-btn:active { cursor: grabbing; }

#walk-start-overlay {
  position: absolute;
  inset: 0;
  z-index: 40;
  background: rgba(20, 24, 20, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
#walk-start-overlay.hidden { display: none; }
#walk-start-card {
  background: var(--panel);
  border-radius: 14px;
  padding: 22px 28px;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0,0,0,0.3);
}
#walk-start-card p {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--text);
  margin: 0 0 6px;
}
#walk-start-card span {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

#walk-hud {
  position: absolute;
  top: 92px; /* matches #hud ("Terug naar kaart") and #export-panel — same row */
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 12px;
  background: rgba(20, 24, 20, 0.72);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 12px;
  padding: 8px 10px 8px 16px;
  border-radius: 999px;
}
#walk-hud.hidden { display: none; }
#walk-exit-btn {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: rgba(255,255,255,0.18);
  color: #fff;
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
}
#walk-exit-btn:hover { background: rgba(255,255,255,0.3); }

/* ---- Info button + panel, bottom-right — aligned with #left-panel's
   own bottom:20px, on the opposite side of the screen ---- */
#info-btn {
  position: absolute;
  bottom: 52px; /* same row as #pegman-wrap, clearing #attribution below it */
  right: 20px;
  z-index: 20;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text);
  font-family: var(--font-display);
  font-weight: 700;
  font-style: italic;
  font-size: 17px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
#info-btn:hover { border-color: var(--accent); }
#info-btn[aria-expanded="true"] { background: var(--accent); color: #1a1206; border-color: var(--accent); }

#help-panel {
  position: absolute;
  bottom: 106px; /* clears the #info-btn/#pegman-wrap row (52px bottom + 44px button height + small gap) */
  right: 20px;
  z-index: 25;
  width: 340px;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.2);
  backdrop-filter: blur(10px);
}
#help-panel.hidden { display: none; }
#help-panel-header {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--border);
  border-radius: 14px 14px 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
}
#help-panel-close {
  background: transparent;
  border: none;
  font-size: 18px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}
#help-panel-close:hover { color: var(--text); }
#help-panel-body {
  padding: 4px 16px 18px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text);
}
#help-panel-body h4 {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 16px 0 4px;
}
#help-panel-body h4:first-child { margin-top: 14px; }
#help-panel-body p { margin: 0 0 6px; }

/* ---- Idle-pause overlay — dims the scene after IDLE_TIMEOUT_MS of no
   input, once the render loop has actually stopped calling
   requestAnimationFrame (see animate() in viewer.js) ---- */
#idle-pause-overlay {
  position: absolute;
  inset: 0;
  z-index: 45; /* above walk-start-overlay (40) — idle-pause can in principle catch the scene in any mode, so it should win visually if both were ever somehow relevant at once */
  background: rgba(20, 24, 20, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
#idle-pause-overlay.hidden { display: none; }
#idle-pause-card {
  background: var(--panel);
  border-radius: 14px;
  padding: 22px 28px;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0,0,0,0.3);
}
#idle-pause-card p {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 16px;
  color: var(--text);
  margin: 0 0 6px;
}
#idle-pause-card span {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--muted);
}

/* ---- Maintenance notice banner override, viewer.html only ---- */
/* maintenance-notice.css (shared with index.html, loaded AFTER this
   file) defaults the banner to top:0 — index.html keeps that, but for
   the viewer specifically it should sit at the BOTTOM instead. The
   `html body` prefix isn't decoration — it bumps this rule's specificity
   just enough to win over maintenance-notice.css's own `top: 0` despite
   loading first, without needing !important. */
html body .maintenance-notice-banner {
  top: auto;
  bottom: 0;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15); /* shadow direction flipped to match — a bottom banner should cast its shadow upward, not down into nothing */
}

/* ---- Loading overlay — shown for the duration of loadScene() (initial
   page load AND every subsequent style switch / area change), so a
   multi-second wait (e.g. "3D Print" style fetching AHN terrain +
   rectangle-clipped buildings on top of the normal scene fetch) isn't
   just a frozen-looking screen with no feedback. ---- */
#loading-overlay {
  position: absolute;
  inset: 0;
  z-index: 60; /* above everything else in the viewer (confirm modal is 100, error banner 50, this sits above ordinary UI chrome but still below an actual confirm/error dialog if one somehow fires mid-load) */
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(3px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
#loading-overlay.hidden { display: none; }
#loading-spinner {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 4px solid var(--border);
  border-top-color: var(--accent);
  animation: loading-spin 0.8s linear infinite;
}
@keyframes loading-spin {
  to { transform: rotate(360deg); }
}
#loading-text {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 14px;
  color: var(--text);
  background: var(--panel);
  padding: 6px 16px;
  border-radius: 999px;
  border: 1px solid var(--border);
  box-shadow: 0 4px 14px rgba(0,0,0,0.12);
}

/* ---- Sun rotation slider — visible only while "Zon & schaduw" is on
   (same conditional-row pattern as #terrain-thickness-row) ---- */
#sun-rotate-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 8px 0 14px;
  font-size: 11px;
  color: var(--text);
}
#sun-rotate-row.hidden { display: none; }
#sun-rotate-row label { flex: 0 0 auto; }
#sun-rotate-input {
  flex: 1 1 auto;
  accent-color: var(--accent);
}

/* ==========================================================================
   Mobile responsive layout
   ==========================================================================
   Below this breakpoint, #left-panel (style + layers) and #export-panel
   (export controls) stop being permanently-visible desktop side panels
   — at phone width there's no room for a 280px + 240px panel next to a
   3D view that's the whole point of the page — and become slide-up
   bottom sheets instead: hidden by default, opened via the two toggle
   buttons in #mobile-panel-bar (new markup, viewer.html), closed again
   by tapping the same button. Everything here is driven by the
   .mobile-open class that toggle adds/removes; the small inline script
   next to it in viewer.html does nothing else, so this file has no
   other dependency on it and is inert outside this media query. */
@media (max-width: 760px) {

  /* ---- Header: nav links now collapse behind a hamburger toggle
     (#header-menu-toggle / #header-nav-links, see header-menu.js)
     instead of the bar scrolling horizontally — same pattern as
     style.css, for consistency across pages. #auth-widget (a separate
     script) stays outside the collapsible links and is unaffected
     either way. ---- */
  #header-bar {
    left: 10px;
    right: 10px;
    top: 10px;
    padding: 0 14px;
    overflow: visible; /* was hidden — only ever needed to clip content to the bar's own rounded corners on desktop; the dropdown menu below needs room to actually show */
  }
  .header-brand { padding-right: 12px; }
  .header-logo-mark { height: 24px; }
  .lang-toggle button { padding: 5px 6px; font-size: 10px; }

  #header-menu-toggle {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    gap: 5px;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    flex-shrink: 0;
  }
  #header-menu-toggle span {
    display: block;
    height: 2px;
    background: var(--text);
    border-radius: 1px;
  }
  #header-nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 8px;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    background: rgba(255, 255, 255, 0.97);
    backdrop-filter: blur(10px);
    border: 1px solid var(--border);
    border-radius: 14px;
    box-shadow: 0 20px 50px rgba(0,0,0,0.15);
    padding: 10px;
  }
  #header-nav-links.open { display: flex; }
  #header-nav-links .header-nav-item {
    padding: 11px 12px;
    border-radius: 8px;
    color: var(--text);
  }
  #header-nav-links .header-nav-item:hover { background: var(--panel-2); }

  /* ---- Back-to-map link: was a fixed 280px wide, wider than most
     phones' available width once the 20px+20px side margins are gone. ---- */
  #hud { top: 78px; left: 10px; right: 10px; }
  .back { width: auto; }

  #walk-hud {
    top: 78px;
    max-width: calc(100vw - 20px);
    overflow-x: auto;
  }

  /* ---- The two main panels: slide-up bottom sheets instead of
     permanent side panels. Anchored 66px above the viewport bottom
     (not 0) so they never sit underneath #mobile-panel-bar — that bar
     needs to stay reachable to close whichever sheet is open. ---- */
  #left-panel,
  #export-panel {
    top: auto;
    left: 10px;
    right: 10px;
    bottom: 66px;
    width: auto;
    max-height: 60vh;
    border-radius: 16px;
    overflow-y: auto;
    transform: translateY(calc(100% + 76px)); /* clears its own height AND the bottom offset, fully off-screen when closed */
    transition: transform 0.25s ease;
    z-index: 55;
  }
  #left-panel.mobile-open,
  #export-panel.mobile-open {
    transform: translateY(0);
  }
  #export-panel { flex-direction: column; align-items: stretch; }

  /* Geometry/format dropdowns open relative to their own button, which
     now lives inside a scrolling bottom sheet rather than a plain
     panel — capped shorter here so they stay usable (self-scrolling
     via .modal-list, same as before) instead of trying to float
     outside a sheet that clips overflow. */
  .geometry-dropdown { max-height: 40vh; }

  /* ---- Bottom toggle bar: the new default-visible affordance,
     replacing "both panels permanently on screen" as the resting
     state. ---- */
  #mobile-panel-bar {
    position: fixed;
    left: 10px;
    right: 10px;
    bottom: 10px;
    z-index: 56;
    display: flex;
    gap: 8px;
  }
  .mobile-panel-toggle {
    flex: 1 1 0;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 13px;
    background: var(--panel);
    color: var(--text);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 12px 10px;
    backdrop-filter: blur(10px);
    box-shadow: 0 8px 24px rgba(0,0,0,0.18);
    cursor: pointer;
  }
  .mobile-panel-toggle[aria-expanded="true"] {
    background: var(--accent);
    color: #1a1206;
    border-color: var(--accent);
  }

  /* ---- Everything that used to cluster bottom-right needs to clear
     the new bar (its own ~48px height + 10px bottom + margin ≈ 76px)
     instead of the old #attribution row it used to align with. ---- */
  #pegman-wrap { bottom: 86px; right: 76px; }
  #measure-toggle-btn { bottom: 86px; right: 136px; }
  #measure-clear-btn { bottom: 138px; right: 136px; }
  #info-btn { bottom: 86px; right: 20px; }
  #attribution { bottom: 86px; right: 20px; }
  #error-banner { bottom: 86px; left: 10px; right: 10px; }
  #info-panel { left: 10px; right: 10px; bottom: 140px; width: auto; }
  #help-panel { left: 10px; right: 10px; bottom: 140px; width: auto; max-height: 50vh; }

  /* ---- A couple of desktop fixed-widths that would otherwise
     overflow a narrow phone screen. ---- */
  #confirmModal { width: calc(100vw - 20px); }
}

/* NL/EN taalknop — zelfde design tokens als de rest van de header. */
.lang-toggle {
  display: flex;
  border-radius: 6px;
  overflow: hidden;
  flex-shrink: 0;
}
.lang-toggle button {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  background: var(--panel-2);
  color: var(--muted);
  border: none;
  padding: 6px 9px;
  cursor: pointer;
  transition: background 0.15s ease, color 0.15s ease;
}
.lang-toggle button.active {
  background: var(--accent);
  color: #1a1206;
}
.lang-toggle button:not(.active):hover {
  color: var(--text);
}
