* {
  box-sizing: border-box;
}

html, body {
  height: 100%;
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  color: #111;
  background: #e9e9e9;
}

#app {
  display: flex;
  height: 100vh;
}

/* #panel-scroll holds everything scrollable; #panel-actions (Generate +
   share) stays pinned to the bottom of the panel via flex, rather than
   literal `position: fixed` (which would anchor to the viewport, not the
   panel, and need its width/position hardcoded to match). */
#panel {
  width: 280px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  background: #fafafa;
  border-right: 1px solid #ddd;
  overflow: hidden;
}

#panel-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}

#panel-actions {
  flex-shrink: 0;
  padding: 16px 24px 12px;
  border-top: 1px solid #ddd;
  background: #fafafa;
}

#panel h1 {
  font-size: 18px;
  margin: 0 0 8px;
}

.hint {
  font-size: 13px;
  color: #666;
  line-height: 1.4;
  text-align: justify;
}

.field {
  display: block;
  font-size: 13px;
  font-weight: 600;
  margin: 20px 0 6px;
}

.field select {
  display: block;
  width: 100%;
  margin-top: 6px;
  padding: 8px;
  font-size: 14px;
}

#detail-panel,
#colour-panel {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid #ddd;
}

.section-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
}

.section-header h2 {
  font-size: 13px;
  font-weight: 600;
  margin: 0 0 6px;
}

.section-header-actions {
  display: flex;
  gap: 10px;
}

.link-btn {
  border: none;
  background: none;
  padding: 0;
  font-size: 11px;
  color: #666;
  text-decoration: underline;
  cursor: pointer;
}

.link-btn:hover {
  color: #111;
}

#detail-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}

.detail-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid #eee;
  font-size: 12px;
}

/* "Show" selected but not achievable even at the largest detail-boost grid
   option, dimmed as a signal that it won't currently do anything. */
.detail-row--unreachable {
  opacity: 0.4;
}

.detail-row-main {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.detail-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid #999;
  background: transparent;
}

.detail-dot.is-visible {
  background: #111;
  border-color: #111;
}

.detail-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.detail-zoom {
  color: #999;
  font-size: 11px;
  flex-shrink: 0;
}

.detail-row-override {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.detail-row-override select {
  font-size: 11px;
  padding: 1px;
}

#colour-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}

.colour-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 6px 0;
  border-bottom: 1px solid #eee;
  font-size: 12px;
}

.colour-row input[type="color"] {
  width: 28px;
  height: 20px;
  padding: 0;
  border: 1px solid #ccc;
  border-radius: 3px;
  cursor: pointer;
}

.action-row {
  display: flex;
  gap: 8px;
}

.action-btn {
  padding: 12px;
  font-size: 14px;
  font-weight: 600;
  color: #fff;
  background: #111;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.action-btn:disabled {
  background: #999;
  cursor: wait;
}

#export-btn {
  flex: 1;
}

.action-btn--icon {
  flex: 0 0 auto;
  width: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
}

#export-status,
#share-status {
  margin: 6px 0 0;
  min-height: 1.4em;
  word-break: break-all;
}

#stage {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  overflow: hidden;
}

/* #poster-frame is a FIXED 500x700 CSS-px box, MapLibre always sees this
   exact container size, so its zoom (and therefore which roads pass their
   minzoom filter) never changes when the browser window is resized.
   #poster-slot is sized in JS (app.js: layoutPosterFrame) to the visually
   scaled footprint, purely so flexbox centers it correctly; #poster-frame
   is absolutely positioned inside it and scaled down/up with a CSS
   transform, which is paint-only and doesn't affect MapLibre's measured
   container size. */
#poster-slot {
  position: relative;
}

#poster-frame {
  position: absolute;
  top: 0;
  left: 0;
  width: 500px;
  height: 700px;
  transform-origin: top left;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
  background: #fff;
}

/* Position/size for #map, #poster-rule and #poster-footer are all set in
   JS (app.js: applyStaticLayout) from one set of mm constants shared with
   the export compositing, see that function rather than duplicating the
   numbers here. */
#map {
  position: absolute;
}

.map-attribution {
  position: absolute;
  right: 6px;
  bottom: 4px;
  font-size: 9px;
  color: #999;
  font-family: sans-serif;
  pointer-events: none;
  z-index: 5;
}

#poster-rule {
  position: absolute;
  background: #000000;
}

#poster-footer {
  position: absolute;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  text-align: left;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.editable {
  outline: none;
  cursor: text;
  min-width: 1em;
}

.editable:empty:before {
  content: attr(data-placeholder);
  color: #aaa;
  font-style: italic;
}

.editable:focus {
  outline: 1px dashed #999;
  outline-offset: 2px;
}

/* Explicit margin/padding/text-align on all three (rather than relying on
   #poster-footer's inherited text-align + browser div defaults) so their
   left edges are guaranteed to sit at the exact same x, matching the
   export's canvas text which also draws all three from one shared textX. */
#poster-title,
#poster-subtitle,
#poster-location {
  margin: 0;
  padding: 0;
  text-align: left;
  line-height: 1;
}

#poster-title {
  font-weight: 700;
  color: #000;
}

#poster-subtitle {
  font-weight: 400;
  color: #000;
}

#poster-location {
  font-weight: 400;
  color: #444;
}
