/*
 * The "Studio" look (chosen by John on 29 Sep 2026 from five mockups).
 *
 * Dark and cinematic, lit like the hero video: near-black, with warm copper
 * highlights and violet shadows. The 3D print is the star of the page.
 *
 * Every colour and font is a named variable ("custom property") here at the
 * top, so the look can be tuned in one place.
 */

:root {
  --ink: #0c0b0f;        /* the page background, the black of the video */
  --ink-2: #15131b;      /* fields and panels, a step up from the background */
  --dusk: #231f2e;       /* the glow behind the 3D print */
  --violet: #3a3350;     /* shadows in the video; switches that are off */
  --copper: #e3a878;     /* sunlit ridges in the video: buttons, the selection box */
  --peach: #f6dcc6;      /* highlights, notes */
  --text: #eee8f1;
  --mist: #a7a1b4;       /* quieter text: labels, hints */
  --line: rgba(233, 221, 255, 0.14); /* hairlines between things */
  --error: #ff9d8c;

  /* Space at the left and right of the page: 16 px on a phone, up to 56 px. */
  --gutter: clamp(16px, 4vw, 56px);

  /* Fonts (loaded by vendor/fonts/fonts.css), each with fallbacks that are
     already on the computer, used until it loads or if it can't. */
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --mono: "Azeret Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;

  /* Tells the browser the page is dark, so scrollbars and the built-in parts
     of form controls are drawn dark too. */
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box; /* width includes padding and border: much easier to reason about */
}

html {
  scroll-behavior: smooth; /* "Choose your place" glides down to the map */
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font: 400 16px/1.6 var(--sans);
}

a {
  color: inherit;
}

/* The hidden attribute (hidden="" in the HTML, el.hidden = true in main.js)
   must always win, even over rules below that set display: flex or grid. */
[hidden] {
  display: none !important;
}

:focus-visible {
  outline: 2px solid var(--copper);
  outline-offset: 3px;
}

h1,
h2 {
  text-wrap: balance; /* evens out the line lengths of headings */
}

/* The small spaced-out capitals used for labels ("SIZE", "YOUR PRINT"). */
.kicker,
.label {
  font: 500 11px/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.kicker {
  color: var(--copper);
  margin: 0 0 18px;
}

.label {
  display: block;
  color: var(--mist);
  margin: 0 0 10px;
  padding: 0;
  font-size: 10.5px;
}

.button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--copper);
  color: #1c1411;
  border: 0;
  border-radius: 999px;
  padding: 14px 24px;
  font: 600 15px/1 var(--sans);
  text-decoration: none;
  cursor: pointer;
  transition: background 0.2s;
}

.button:hover {
  background: var(--peach);
}

.button:disabled {
  background: var(--violet);
  color: var(--mist);
  cursor: not-allowed;
}

.small-button {
  background: rgba(12, 11, 15, 0.75);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 7px 14px;
  font: 500 13px/1 var(--sans);
  cursor: pointer;
}

.small-button:hover {
  border-color: var(--copper);
}

/* --- The opening screen, over the video ------------------------------------------ */

.hero {
  position: relative;
  isolation: isolate; /* keeps the video and its shading behind the text, and nothing else */
  min-height: clamp(560px, 86vh, 880px);
  display: grid;
  grid-template-rows: auto 1fr auto; /* menu at the top, headline at the bottom */
  /* The poster frame, for the moment before the video starts. */
  background: var(--ink) url("../media/landing_bg_poster.jpg") center / cover no-repeat;
}

.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover; /* fill the screen, cropping the edges rather than squashing */
  z-index: -2;
}

/* Shading over the video, so the white text stays readable: darker at the
   bottom where the headline is, and a little at the top for the menu. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(12, 11, 15, 0.95) 0%, rgba(12, 11, 15, 0.55) 34%, rgba(12, 11, 15, 0) 62%),
    linear-gradient(to bottom, rgba(12, 11, 15, 0.6), rgba(12, 11, 15, 0) 20%);
  pointer-events: none;
}

.top-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 22px var(--gutter);
}

.wordmark {
  font: 500 12px/1 var(--mono);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
}

.nav-button {
  border: 1px solid rgba(227, 168, 120, 0.6);
  color: var(--peach);
  padding: 8px 16px;
  border-radius: 999px;
  font-size: 14px;
  text-decoration: none;
}

.nav-button:hover {
  border-color: var(--copper);
}

.hero-copy {
  align-self: end;
  max-width: 900px;
  padding: 0 var(--gutter) 8px;
}

h1 {
  font: 300 clamp(2.7rem, 6.4vw, 5.6rem)/0.95 var(--serif);
  letter-spacing: -0.015em;
  margin: 0 0 24px;
}

h1 em {
  color: var(--peach);
}

.lede {
  max-width: 48ch;
  margin: 0 0 30px;
  color: #d3cbd8;
  font-size: 17px;
}

.hero-credit {
  justify-self: end;
  margin: 0;
  padding: 18px var(--gutter) 22px;
  font: 400 11px/1.4 var(--mono);
  letter-spacing: 0.05em;
  color: #8f889c;
}

/* For people who've asked their computer for less motion: no video, just
   the poster frame (the background of .hero). */
@media (prefers-reduced-motion: reduce) {
  .hero-video {
    display: none;
  }

  html {
    scroll-behavior: auto;
  }
}

/* --- The stage: the map and the 3D view ------------------------------------------ */

.stage {
  position: relative; /* the title is placed over it */
  height: clamp(620px, 88vh, 900px);
  display: grid;
  grid-template-rows: minmax(0, 1fr) auto; /* the map/3D area takes what the controls leave */
  background: radial-gradient(ellipse 70% 62% at 50% 50%, var(--dusk) 0%, var(--ink) 72%);
  border-top: 1px solid var(--line);
}

/* In full screen, the whole stage (3D view, map and controls) fills the screen. */
.stage:fullscreen {
  height: 100vh;
}

.stage-area {
  position: relative;
  min-height: 0;
}

/* A dark fade across the top, so the title stays readable over the map. */
.stage-area::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 190px;
  z-index: 2;
  background: linear-gradient(to bottom, rgba(12, 11, 15, 0.85), rgba(12, 11, 15, 0));
  pointer-events: none;
}

.stage-title {
  position: absolute;
  left: var(--gutter);
  top: 36px;
  z-index: 3;
  max-width: min(46%, 560px);
  pointer-events: none; /* clicks go through to the map underneath */
}

.stage-title h2 {
  font: 300 clamp(2.2rem, 4.4vw, 3.9rem)/1 var(--serif);
  margin: 0 0 12px;
}

#box-info {
  margin: 0;
  font: 400 12.5px/1.5 var(--mono);
  color: var(--mist);
}

#status {
  margin: 12px 0 0;
  font-size: 14px;
  color: var(--peach);
}

#status:empty {
  display: none;
}

#status.error {
  color: var(--error);
  font-weight: 600;
}

/* Both panels fill the stage by default; the mode rules below shrink one of
   them into the corner. */
.panel {
  position: absolute;
  inset: 0;
  z-index: 1;
  isolation: isolate; /* Leaflet's own layers stay inside the map panel */
}

#map,
#viewer {
  position: absolute;
  inset: 0;
}

/* The small picture in the corner: the map in "view" mode, the last 3D
   preview in "map" mode. */
.stage[data-mode="view"] #map-panel,
.stage[data-mode="map"] #viewer-box {
  inset: 32px var(--gutter) auto auto;
  width: 232px;
  height: 232px;
  z-index: 4;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: var(--ink);
  box-shadow: 0 18px 40px -16px rgba(0, 0, 0, 0.7);
}

.stage[data-mode="map"] #viewer-box {
  height: 174px;
}

/* Before the first preview there's no 3D view to show in the corner. */
.stage[data-mode="map"]:not(.has-preview) #viewer-box {
  display: none;
}

/* The corner picture is one big button that swaps the two over. */
.swap-button {
  display: none;
  position: absolute;
  inset: 0;
  z-index: 1001; /* above Leaflet's layers and controls (1000) */
  align-items: flex-end;
  justify-content: space-between;
  padding: 10px 12px;
  background: linear-gradient(to bottom, rgba(12, 11, 15, 0) 55%, rgba(12, 11, 15, 0.88));
  border: 0;
  color: var(--copper);
  font: 500 13px/1 var(--sans);
  cursor: pointer;
}

.swap-button:hover {
  color: var(--peach);
}

.stage[data-mode="view"] #edit-area-button,
.stage[data-mode="map"] #back-to-3d-button {
  display: flex;
}

/* The map's zoom buttons are no use on the small locator. */
.stage[data-mode="view"] .leaflet-control-zoom {
  display: none;
}

/* On the small locator the OpenStreetMap credit moves to the top, clear of
   "Change area" (its licence asks for the credit to stay on the map). */
.stage[data-mode="view"] .leaflet-bottom.leaflet-right {
  top: 0;
  bottom: auto;
}

.stage[data-mode="view"] .leaflet-control-attribution.leaflet-control {
  font-size: 9px;
}

/* Colour switch, legend and full screen button, along the bottom of the 3D
   view. Only when the 3D view is big. */
.view-tools {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: 18px;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 18px;
  pointer-events: none;
}

.view-tools > * {
  pointer-events: auto;
}

.stage[data-mode="map"] .view-tools {
  display: none;
}

#fullscreen-button {
  margin-left: auto;
}

.colour-switch {
  display: flex;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(12, 11, 15, 0.75);
}

.colour-switch button {
  background: transparent;
  border: 0;
  border-radius: 999px;
  padding: 6px 12px;
  color: var(--mist);
  font: 500 13px/1 var(--sans);
  cursor: pointer;
}

.colour-switch button[aria-pressed="true"] {
  background: #2c2738;
  color: var(--text);
}

#legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  font-size: 12.5px;
  color: var(--mist);
}

.swatch {
  display: inline-block;
  width: 11px;
  height: 11px;
  border-radius: 3px;
  margin-right: 6px;
  vertical-align: -1px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.3);
}

/* --- The controls bar --------------------------------------------------------------- */

.dock {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  margin: 0 var(--gutter) 24px;
  background: rgba(15, 13, 20, 0.92);
  border: 1px solid var(--line);
  border-radius: 16px;
}

.dock-item {
  margin: 0;
  padding: 14px 20px;
  border: 0;
  min-width: 0;
}

.dock-item + .dock-item {
  border-left: 1px solid var(--line);
}

/* A fieldset draws its legend in its top border, above the padding; floating
   it puts it inside, level with the other labels. */
.dock-item legend {
  float: left;
  width: 100%;
}

/* The size buttons: real radio buttons, hidden, with their labels drawn as
   a row of segments. */
.segments {
  clear: both;
  display: flex;
  gap: 4px;
}

.segments label {
  position: relative;
}

.segments input {
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}

.segments span {
  display: block;
  padding: 7px 12px;
  border-radius: 9px;
  color: var(--mist);
  font-size: 14px;
  white-space: nowrap;
  cursor: pointer;
}

.segments small {
  font: 400 11px var(--mono);
  opacity: 0.75;
  margin-left: 5px;
}

.segments input:checked + span {
  background: #2c2738;
  color: #fff;
}

.segments input:focus-visible + span {
  outline: 2px solid var(--copper);
}

.heights {
  min-width: 200px;
}

.heights output {
  color: var(--peach);
  margin-left: 6px;
  letter-spacing: 0.05em;
}

.heights input {
  width: 100%;
  accent-color: var(--copper); /* colours the browser's own slider */
}

/* The on/off switch for "Show buildings". */
.switch {
  position: relative;
  display: inline-flex;
}

.switch input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  z-index: 1;
}

.switch-track {
  width: 38px;
  height: 22px;
  border-radius: 999px;
  background: var(--violet);
  position: relative;
  transition: background 0.2s;
}

.switch-track::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #f6f1f8;
  transition: transform 0.2s;
}

.switch input:checked + .switch-track {
  background: var(--copper);
}

.switch input:checked + .switch-track::after {
  transform: translateX(16px);
}

.switch input:focus-visible + .switch-track {
  outline: 2px solid var(--copper);
  outline-offset: 2px;
}

/* Greyed out when the area is too big for buildings (see main.js). */
.switch input:disabled + .switch-track {
  opacity: 0.35;
}

.switch input:disabled {
  cursor: not-allowed;
}

.readouts {
  display: flex;
  gap: 26px;
}

.readouts dd {
  margin: 0;
  font: 400 15px/1.2 var(--mono);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.dock-go {
  margin-left: auto;
  display: flex;
  align-items: center;
}

.dock-note {
  flex-basis: 100%;
  margin: 0;
  padding: 12px 20px;
  border-top: 1px solid var(--line);
  font-size: 14px;
  color: var(--peach);
}

/* Show all the time for big areas, so quieter than the out-of-date note. */
#buildings-hint,
#roads-hint {
  color: var(--mist);
}

/* --- The map (Leaflet) ------------------------------------------------------------- */

.leaflet-container {
  background: var(--ink);
  font-family: var(--sans);
}

/* The map's pictures are LINZ's aerial photos. A little darker and less
   colourful than they come, so they sit in the dark page and the copper box
   and outlines stand out on them. It changes only how they look, not what's
   on them. (main.js gives the tiles this class name.) The old
   OpenStreetMap map needed its colours turned inside out; photos don't. */
.map-tiles {
  filter: brightness(0.82) saturate(0.8);
}

/* Over the top-right of the map, when it can't show its pictures (see
   main.js). pointer-events: none lets clicks through to the map beneath,
   so the box can still be placed under it. */
.map-message {
  position: absolute;
  right: 16px;
  top: 16px;
  z-index: 500; /* above Leaflet's layers, below its controls */
  pointer-events: none;
  width: min(380px, calc(100% - 32px));
  margin: 0;
  padding: 14px 18px;
  background: rgba(15, 13, 20, 0.94);
  border: 1px solid var(--line);
  border-left: 2px solid var(--error);
  border-radius: 12px;
  font-size: 14px;
  color: var(--peach);
}

.leaflet-bar a {
  background: var(--ink-2);
  color: var(--text);
  border-bottom-color: var(--line);
}

.leaflet-bar a:hover {
  background: #221f2b;
  color: #fff;
}

.leaflet-control-attribution.leaflet-control {
  background: rgba(12, 11, 15, 0.75);
  color: var(--mist);
  font-size: 10.5px;
}

.leaflet-control-attribution a {
  color: var(--copper);
}

/* The two handles on the selection box (see selection_box.js). */
.box-handle {
  background: var(--ink);
  border: 2px solid var(--copper);
  box-sizing: border-box;
}

.box-handle-move {
  border-radius: 50%;
  cursor: move;
}

.box-handle-resize {
  cursor: nwse-resize;
}

/* --- About this print (after a preview) ----------------------------------------------- */

.about-print {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(28px, 5vw, 80px);
  padding: 72px var(--gutter) 56px;
  border-top: 1px solid var(--line);
}

.about-print h2 {
  font: 300 clamp(2.2rem, 4vw, 3.4rem)/1 var(--serif);
  margin: 0 0 24px;
}

.note {
  margin: 0 0 12px;
  padding: 10px 14px;
  border-left: 2px solid var(--copper);
  background: rgba(227, 168, 120, 0.08);
  color: var(--peach);
  font-size: 15px;
  max-width: 60ch;
}

#details {
  display: grid;
  grid-template-columns: minmax(120px, max-content) 1fr;
  margin: 0;
  align-self: start;
}

#details dt,
#details dd {
  margin: 0;
  padding: 11px 0;
  border-bottom: 1px solid var(--line);
}

#details dt {
  color: var(--mist);
  font-size: 14px;
  padding-right: 20px;
}

#details dd {
  font-size: 15px;
}

/* --- Ordering (after a preview; see order_form.js) -------------------------------------- */

.order {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: clamp(28px, 5vw, 80px);
  padding: 56px var(--gutter) 72px;
  border-top: 1px solid var(--line);
}

.order h2 {
  font: 300 clamp(2.2rem, 4vw, 3.4rem)/1 var(--serif);
  margin: 0 0 24px;
}

#order-summary {
  margin: 0 0 14px;
  font-size: 17px;
  max-width: 44ch;
}

.order-small {
  margin: 0;
  font-size: 14px;
  color: var(--mist);
  max-width: 48ch;
}

/* Two columns of fields; the wide ones take a whole row. */
.order-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px 20px;
  align-content: start;
}

.field {
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.field-wide {
  grid-column: 1 / -1;
}

.field .label small {
  letter-spacing: 0.05em;
  text-transform: none;
}

.field input,
.field textarea {
  width: 100%;
  padding: 11px 14px;
  background: var(--ink-2);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 10px;
  font: 400 15px/1.4 var(--sans);
}

.field textarea {
  resize: vertical;
}

.field input::placeholder {
  color: var(--mist);
}

.field input:focus-visible,
.field textarea:focus-visible {
  border-color: var(--copper);
  outline-offset: 1px;
}

/* The frame buttons are .segments, like the size buttons, so they need the
   same trick for a fieldset's legend (see .dock-item legend). */
.field legend {
  float: left;
  width: 100%;
}

.order-stale {
  grid-column: 1 / -1;
  margin: 0;
  padding: 10px 14px;
  border-left: 2px solid var(--copper);
  background: rgba(227, 168, 120, 0.08);
  color: var(--peach);
  font-size: 14px;
}

.order-go {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
}

#order-status {
  margin: 0;
  font-size: 14px;
  color: var(--peach);
}

#order-status.error {
  color: var(--error);
}

.order-done {
  align-self: start;
  padding: 24px 26px;
  border: 1px solid var(--line);
  border-left: 2px solid var(--copper);
  border-radius: 14px;
  background: rgba(15, 13, 20, 0.88);
}

.order-done h3 {
  font: 300 2rem/1.1 var(--serif);
  margin: 0 0 12px;
}

.order-done p:last-child {
  margin: 0;
}

/* The payment step (launch milestone L2): Stripe's own payment form, which
   Stripe draws inside #checkout (an iframe from Stripe, in its own colours;
   they can be set in the Stripe dashboard's branding settings). */
.order-pay {
  align-self: start;
  min-width: 0;
}

.order-pay h3 {
  font: 300 2rem/1.1 var(--serif);
  margin: 0 0 16px;
}

#checkout {
  margin: 0 0 16px;
  border-radius: 14px;
  overflow: hidden; /* rounds the corners of Stripe's form too */
}

#order-pay-status {
  margin: 0 0 14px;
  font-size: 14px;
  color: var(--peach);
}

#order-pay-status.error {
  color: var(--error);
}

/* --- Admin: John's list of orders (templates/admin_orders.html) ---------------------------- */

.admin {
  padding: 8px var(--gutter) 64px;
  max-width: 1400px;
}

.admin-title {
  font-size: clamp(2.4rem, 5vw, 3.6rem);
}

/* The privacy page (templates/privacy.html): plain reading text, not too wide. */
.prose {
  max-width: 72ch;
  line-height: 1.6;
}

.prose h2 {
  font: 400 1.8rem/1.2 var(--serif);
  margin: 36px 0 12px;
}

.prose li {
  margin-bottom: 10px;
}

/* In the mono font: the serif's old-style "1" looks like a Roman numeral I. */
.admin-count {
  color: var(--mist);
  font: 400 0.32em var(--mono);
  margin-left: 10px;
  vertical-align: middle;
}

.admin-nav .kicker {
  margin: 0; /* level with the wordmark */
}

.admin-empty {
  color: var(--mist);
}

.order-card {
  margin: 0 0 22px;
  padding: 22px 24px;
  background: var(--ink-2);
  border: 1px solid var(--line);
  border-radius: 16px;
  /* The link back after a button lands here; keep it clear of the window's top edge. */
  scroll-margin-top: 16px;
}

.order-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding-bottom: 16px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line);
}

.order-head .kicker {
  margin-bottom: 10px;
}

.order-head h2 {
  font: 400 2rem/1.05 var(--serif);
  margin: 0;
}

.order-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.order-status .label {
  margin: 0;
}

.order-status select {
  padding: 7px 10px;
  background: var(--ink);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  font: 400 14px var(--sans);
}

.order-body {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 22px 36px;
}

.order-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 0;
  font-size: 14.5px;
}

.order-facts dt {
  color: var(--mist);
}

.order-facts dd {
  margin: 0;
  overflow-wrap: anywhere; /* long email addresses wrap instead of spilling out */
}

.order-address {
  white-space: pre-line; /* keeps the line breaks the customer typed */
}

.files-status {
  margin: 0 0 10px;
  font-weight: 600;
}

.files-ready {
  color: #b9e3b0;
}

.files-failed {
  color: var(--error);
}

.files-waiting,
.files-building {
  color: var(--peach);
}

/* Paid or not (launch milestone L2). An unpaid order is someone who opened
   the payment form: shown faded, as there's nothing to do for it. */
.order-head .paid {
  color: #b9e3b0;
}

.order-head .not-paid,
.files-unpaid {
  color: var(--mist);
}

.order-unpaid {
  opacity: 0.6;
}

.files-note {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-left: 2px solid var(--error);
  background: rgba(255, 157, 140, 0.08);
  font-size: 13.5px;
  overflow-wrap: anywhere;
}

.order-files {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
}

.order-files li {
  padding: 4px 0;
}

.order-files a {
  color: var(--copper);
  font-family: var(--mono);
  font-size: 13.5px;
}

.order-files span,
.order-credit {
  color: var(--mist);
  font-size: 13px;
}

.order-credit {
  margin: 14px 0 0;
}

/* --- Footer ------------------------------------------------------------------------- */

.site-footer {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px 24px;
  padding: 26px var(--gutter) 40px;
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--mist);
}

.site-footer p {
  margin: 0;
  max-width: 70ch;
}

/* --- Phones and narrow windows --------------------------------------------------------- */

@media (max-width: 900px) {
  /* The stage grows to fit instead of having a fixed height: title, then
     the big panel, then the controls, one under the other. */
  .stage {
    height: auto;
    display: flex;
    flex-direction: column;
  }

  .stage-area {
    height: 64vh;
    min-height: 360px;
    order: 2;
  }

  .stage-area::before {
    display: none;
  }

  .stage-title {
    position: static;
    order: 1;
    max-width: none;
    padding: 28px var(--gutter) 16px;
  }

  .stage[data-mode="view"] #map-panel,
  .stage[data-mode="map"] #viewer-box {
    top: 12px;
    right: 12px;
    width: 150px;
    height: 150px;
  }

  .stage[data-mode="map"] #viewer-box {
    height: 112px;
  }

  .dock {
    order: 3;
    margin-top: 16px;
  }

  .dock-item {
    flex: 1 1 100%;
  }

  .dock-item + .dock-item {
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  .dock-go {
    margin-left: 0;
  }

  .about-print,
  .order {
    grid-template-columns: 1fr;
    padding-top: 48px;
  }

  .order-form {
    grid-template-columns: 1fr;
  }
}

/* --- Your land (in the title, over the map; see land.js) ------------------------------- */

.land {
  margin-top: 20px;
  max-width: 440px;
  pointer-events: auto; /* the title lets clicks through to the map; this part is clickable */
}

/* A soft dark edge keeps "Find your land" readable over busy map labels. */
.land-search .label {
  text-shadow: 0 0 6px var(--ink), 0 0 2px var(--ink);
}

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

#address {
  flex: 1;
  min-width: 0;
  padding: 9px 14px;
  background: rgba(12, 11, 15, 0.82);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 999px;
  font: 400 14px/1.2 var(--sans);
}

#address::placeholder {
  color: var(--mist);
}

#address:focus-visible {
  border-color: var(--copper);
  outline-offset: 1px;
}

.address-results {
  list-style: none;
  margin: 8px 0 0;
  padding: 4px;
  max-height: 240px;
  overflow-y: auto;
  background: rgba(15, 13, 20, 0.96);
  border: 1px solid var(--line);
  border-radius: 12px;
}

.address-results button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: var(--text);
  font: 400 14px/1.3 var(--sans);
  text-align: left;
  cursor: pointer;
}

.address-results button:hover,
.address-results button:focus-visible {
  background: #2c2738;
}

#land-status {
  margin: 8px 0 0;
  font-size: 13.5px;
  color: var(--peach);
}

#land-status:empty {
  display: none;
}

#land-status.error {
  color: var(--error);
}

/* The customer's land: a card with a copper edge, like the outline on the map. */
.land-card {
  margin-top: 14px;
  padding: 12px 14px;
  background: rgba(15, 13, 20, 0.88);
  border: 1px solid var(--line);
  border-left: 2px solid var(--copper);
  border-radius: 12px;
}

.land-card .label {
  color: var(--copper);
  margin-bottom: 8px;
}

#land-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

#land-list li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  padding: 3px 0;
}

.land-name {
  display: block;
  font: 400 1.3rem/1.15 var(--serif);
}

.land-facts {
  display: block;
  margin-top: 3px;
  font: 400 11.5px/1.4 var(--mono);
  color: var(--mist);
}

.land-remove {
  flex: none;
  padding: 0;
  background: none;
  border: 0;
  color: var(--mist);
  font: 500 12.5px/1 var(--sans);
  text-decoration: underline;
  cursor: pointer;
}

.land-remove:hover {
  color: var(--copper);
}

#land-hint {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--mist);
}

#land-hint.warning {
  color: var(--peach);
}

#pick-land-button {
  margin-top: 12px;
}

/* On while picking: filled in copper, like a pressed switch. */
#pick-land-button[aria-pressed="true"] {
  background: var(--copper);
  border-color: var(--copper);
  color: #1c1411;
}

/* While picking, the map shows a crosshair instead of Leaflet's hand. */
#map-panel.picking .leaflet-grab {
  cursor: crosshair;
}

/* In the 3D view the land card stays (it's what the print is about), but
   finding and changing the land is for the map. */
.stage[data-mode="view"] .land-edit,
.stage[data-mode="view"] #land-status {
  display: none;
}
