/* The lead page, phone first.
 *
 * 390px is the design width, not a breakpoint it degrades to: this page is
 * opened from a builder's site on a phone, in a driveway, by somebody who has
 * just been asked for their mobile number. Everything above 560px is a wider
 * version of the same column, never a different layout.
 *
 * Colour comes from the tenant, substituted into <style id="brand"> as a :root
 * override. The values here are the defaults so the file on disk names no
 * builder's colour as "the" colour.
 */

/* The two faces, served from this origin. Both are SIL Open Font Licensed, so
   self-hosting is the licence's intent rather than a workaround. DM Sans is one
   variable file covering every weight the page uses; Cormorant Garamond is the
   600 the headings are set in and nothing else. Latin subset only: this page is
   English and a 40 KB font is 40 KB of a homeowner's data. */
@font-face {
  font-family: "DM Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/assets/fonts/dm-sans-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Cormorant Garamond";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/cormorant-garamond-600-latin.woff2") format("woff2");
}

:root {
  --ink: #2a3b47;
  --ink-soft: #4a5b66;
  --paper: #f2f0ec;
  --muted: #78868f;
  --brass: #a07c4a;
  --brass-deep: #7a5c36;
  --brass-on-dark: #c4a26d;
  --brass-soft: #ede3d2;

  --card: #fffefb;
  --line: rgba(42, 59, 71, 0.14);
  --radius: 14px;
  --pad: 20px;
  --tap: 52px; /* every control clears the 44px minimum with room to spare */
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font:
    16px/1.55 "DM Sans",
    -apple-system,
    BlinkMacSystemFont,
    "Segoe UI",
    sans-serif;
  -webkit-font-smoothing: antialiased;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

/* ------------------------------------------------------------------ header */
.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px var(--pad);
  border-bottom: 1px solid var(--line);
  background: var(--card);
}

.lockup {
  display: flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: var(--ink);
}

.lockup svg {
  width: 20px;
  height: 26px;
  fill: var(--ink);
  flex: none;
}

.lockup svg .pt {
  fill: var(--brass);
}

.lockup span {
  font-weight: 700;
  font-size: 15px;
  letter-spacing: 0.01em;
}

.product {
  margin: 0;
  font-size: 12px;
  color: var(--muted);
  text-align: right;
  line-height: 1.25;
}

/* -------------------------------------------------------------------- main */
main {
  flex: 1 0 auto;
  width: 100%;
  max-width: 560px;
  margin: 0 auto;
  padding: 24px var(--pad) 34px;
}

.step[hidden] {
  display: none;
}

.eyebrow {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--brass-deep);
}

h1 {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  font-size: 33px;
  line-height: 1.12;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}

h2 {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-weight: 600;
  font-size: 28px;
  line-height: 1.15;
  margin: 0 0 10px;
}

.lede {
  margin: 0 0 22px;
  color: var(--ink-soft);
  font-size: 15.5px;
}

.help {
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.mono {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 4px 0 14px;
}

/* -------------------------------------------------------------------- form */
.field {
  position: relative;
  margin: 0 0 18px;
}

label {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  margin: 0 0 6px;
}

input {
  width: 100%;
  min-height: var(--tap);
  padding: 12px 14px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  /* 16px or iOS zooms the whole page on focus and the visitor loses the form. */
  font: 16px/1.3 inherit;
  font-family: inherit;
}

input:focus-visible,
button:focus-visible,
a:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}

.field.bad input {
  border-color: #b4442f;
  background: #fff7f5;
}

.err {
  margin: 6px 0 0;
  font-size: 13px;
  color: #b4442f;
  font-weight: 500;
}

.form-err {
  margin-bottom: 10px;
}

/* The typeahead. A plain list under the field, never a floating overlay: on a
   phone a floating list lands under the keyboard. */
.suggest {
  list-style: none;
  margin: 8px 0 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  overflow: hidden;
}

.suggest[hidden] {
  display: none;
}

.suggest li {
  padding: 13px 14px;
  font-size: 14.5px;
  min-height: 46px;
  cursor: pointer;
  border-bottom: 1px solid var(--line);
}

.suggest li:last-child {
  border-bottom: 0;
}

.suggest li:hover,
.suggest li[aria-selected="true"] {
  background: var(--brass-soft);
}

.go {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: var(--tap);
  margin: 4px 0 0;
  padding: 14px 18px;
  border: 0;
  border-radius: var(--radius);
  background: var(--brass);
  color: #fff;
  font: 600 16px/1.2 inherit;
  text-decoration: none;
  cursor: pointer;
}

.go:hover {
  background: var(--brass-deep);
}

.go[disabled] {
  opacity: 0.55;
  cursor: default;
}

.cta {
  margin-top: 20px;
}

.privacy {
  margin: 16px 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}

.privacy a {
  color: inherit;
}

/* The honeypot: off screen rather than display:none, which some form-filling
   scripts know to skip. */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.cta-top {
  margin: 0 0 16px;
}

.soft {
  margin-top: 10px;
}

/* -------------------------------------------------------------------- wait */
#step-wait {
  text-align: center;
  padding-top: 34px;
}

.emblem {
  width: 104px;
  height: 104px;
  margin: 0 auto 22px;
}

.emblem svg {
  width: 100%;
  height: 100%;
}

/* The stage line. Under the emblem and above the heading, small and quiet: it
   changes four or five times while somebody waits, and a line that changes
   should not be the loudest thing on the screen. */
.stage {
  margin: -8px 0 12px;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brass);
}

.emblem .ring-bg {
  fill: none;
  stroke: var(--line);
  stroke-width: 4;
}

.emblem .ring {
  fill: none;
  stroke: var(--brass);
  stroke-width: 4;
  stroke-linecap: round;
  stroke-dasharray: 62 227;
  transform-origin: 60px 60px;
  animation: spin 1.5s linear infinite;
}

.emblem .mark path {
  fill: var(--ink);
}

.emblem .mark .pt {
  fill: var(--brass);
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* A visitor who has asked not to be moved gets a still mark and the same
   words. The words are what carry the state; the ring never did. */
@media (prefers-reduced-motion: reduce) {
  .emblem .ring {
    animation: none;
    stroke-dasharray: 289;
    opacity: 0.5;
  }
}

/* ------------------------------------------------------------------ result */

/* THE 3D PANEL, ON A PHONE.
 *
 * Two things it must do at 390 x 844, and they pull against each other. It has
 * to be big enough to read a section in — the drawing is what the visitor came
 * for — and it must not be so tall that the book-a-site-visit button and the
 * footer are pushed somewhere nobody scrolls to.
 *
 * So: FULL WIDTH, breaking the reading column's 20px gutter, because every
 * pixel of width is a metre of section and the model has its own chrome inside
 * it that wants the room. And a HEIGHT IN VIEWPORT UNITS rather than an aspect
 * ratio, because an aspect ratio grows with the width and a 3:4 box on a phone
 * is 467px of an 844px screen with a header above it — the CTA lands below the
 * fold and stays there. 54svh caps it at about 456px on a tall phone and
 * shrinks with a short one, which leaves the claim, the button and its note in
 * the same scroll as the bottom of the drawing.
 *
 * `svh`, not `vh`: on mobile Safari `vh` is the tallest the viewport ever gets,
 * so a panel sized in `vh` is taller than the screen for as long as the URL bar
 * is showing, which is exactly when the visitor is looking at it.
 */
.scene {
  margin: 18px 0 14px;
  /* Full-bleed out of the centred column, however wide that column is. */
  margin-inline: calc(50% - 50vw);
  width: 100vw;
  height: 54svh;
  min-height: 300px;
  /* Raised from 460px (Max, 2026-09-25: "the viewer needs to be much larger"):
     54svh only reaches this on a tall screen, so on a phone the CTA keeps its
     place in the same scroll. */
  max-height: 760px;
  border-block: 1px solid var(--line);
  overflow: hidden;
  background: var(--card);
}

.scene[hidden] {
  display: none;
}

.scene iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The decline's own drawing: the section with what is in the way on it. */
.shot {
  margin: 18px 0 14px;
}

.shot[hidden] {
  display: none;
}

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
}

/* The placement chips live inside the panel, not out here. See index.html. */

/* The 2D site plans under the 3D panel (Max, 2026-10-02). One card per
 * option, stacked in the reading column; two abreast once a framed page has
 * the width, breaking out of the column the way the panel does. The image is
 * shown whole, never cropped: the disclaimer and the LINZ credit are in it. */
.plans {
  margin: 22px 0 18px;
}

.plans[hidden] {
  display: none;
}

.plans h3 {
  margin: 0 0 4px;
  font-size: 18px;
}

.plans .help {
  margin: 0 0 14px;
}

.plans-grid {
  display: grid;
  gap: 16px;
}

.plan {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
  overflow: hidden;
}

.plan img {
  display: block;
  width: 100%;
  height: auto;
  background: var(--paper);
}

.plan figcaption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 12px;
  border-top: 1px solid var(--line);
}

.plan-name {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
}

.go.dl {
  width: auto;
  flex: none;
  margin: 0;
  padding: 0 18px;
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--line);
}

.go.dl:hover {
  background: var(--brass-soft);
}

.rationale,
.next {
  margin: 0 0 14px;
  font-size: 14.5px;
  color: var(--ink-soft);
}

.next {
  padding: 13px 15px;
  border-left: 3px solid var(--brass);
  background: var(--brass-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* The decline's full reason, folded. Closed it is one tappable line under the
   drawing; open it is every word the pipeline wrote, unchanged. */
.why {
  margin: 0 0 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--card);
}

.why[hidden] {
  display: none;
}

.why summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  padding: 0 15px;
  font-size: 14.5px;
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}

.why summary::-webkit-details-marker {
  display: none;
}

.why summary::after {
  content: "+";
  margin-left: auto;
  font-weight: 700;
  color: var(--brass-deep);
}

.why[open] summary::after {
  content: "\2212";
}

.why p {
  margin: 0 15px 14px;
  font-size: 14.5px;
  color: var(--ink-soft);
}

.why p:empty {
  display: none;
}

/* The red-flag line. One sentence, in the brass the page uses for the thing it
   wants read, and never a claim about the section. */
.flag {
  margin: 0 0 14px;
  padding: 13px 15px;
  border-left: 3px solid var(--brass);
  background: var(--brass-soft);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
}

.flag[hidden] {
  display: none;
}

.claim {
  margin: 0 0 6px;
  font-size: 13px;
  color: var(--muted);
}

/* ------------------------------------------------------------------ footer */
.legal {
  flex: none;
  border-top: 1px solid var(--line);
  padding: 16px var(--pad) 26px;
  background: var(--card);
}

.legal p {
  max-width: 560px;
  margin: 0 auto;
}

.disc {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-soft);
}

.attr {
  margin-top: 6px !important;
  font-size: 11.5px;
  color: var(--muted);
}

/* Wider than the reading column. The panel STAYS full-bleed on a desktop:
   it used to come back inside the 560px card here, and Max ruled against that
   on 2026-09-25 ("the viewer needs to be much larger, full screen width").
   The text keeps its column; the drawing takes the screen. Taller than the
   phone rule because a desktop has the room, capped so the button below it
   is still one scroll away. The clip stops 100vw adding a sideways scroll
   when the page shows a vertical scrollbar. */
@media (min-width: 560px) {
  h1 {
    font-size: 38px;
  }

  html:not(.framed) body {
    overflow-x: clip;
  }

  .scene {
    height: min(72svh, 760px);
    max-height: none;
  }
}

/* ------------------------------------------------------------------ framed
 * Inside the builder's page (lead.js adds `.framed`). The frame is sized to
 * this page's height by the page around it, so any height in viewport units
 * here would be a height in units of itself and the two would chase each
 * other. Fixed heights instead, stepped by the frame's own width.
 *
 * WIDTH is safe in viewport units, because the builder's page sets the frame's
 * width and nothing here feeds back into it. On the result step the builder's
 * page breaks the frame out to the full screen width (Max, 2026-09-25: "the
 * viewer needs to be much larger, full screen width"), so the panel leaves the
 * 560px reading column and takes all of it, edge to edge. The clip on the body
 * is what keeps 100vw from adding a sideways scroll when the frame ever shows a
 * vertical scrollbar.
 */
.framed body {
  min-height: 0;
  overflow-x: clip;
}

.framed .scene {
  margin-inline: calc(50% - 50vw);
  width: 100vw;
  height: 460px;
  min-height: 0;
  max-height: none;
  aspect-ratio: auto;
  border: 0;
  border-block: 1px solid var(--line);
  border-radius: 0;
}

@media (min-width: 600px) {
  .framed .scene {
    height: 560px;
  }
}

@media (min-width: 900px) {
  .framed .scene {
    height: 720px;
  }
}

/* On a phone the top button rides the bottom of the screen while the result
   shows, with room left under the footer so it never covers it. Not in
   a frame: there the viewport is the frame, as tall as the page, so "the
   bottom of the viewport" is just the end of the page. */
@media (max-width: 520px) {
  html:not(.framed) #step-result:not([hidden]) .cta-top {
    position: fixed;
    left: 12px;
    right: 12px;
    bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 20;
    width: auto;
    margin: 0;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.18);
  }

  /* The room goes under the footer, not the result: the footer is last, and
     its LINZ attribution is a licence term that nothing may sit on top of. */
  html.on-result:not(.framed) .legal {
    padding-bottom: 96px;
  }
}

/* The 2D plans, two abreast once a framed page has the width (see .plans). */
@media (min-width: 900px) {
  .framed .plans {
    width: min(1100px, 100vw - 32px);
    margin-inline: calc(50% - min(550px, 50vw - 16px));
  }

  .framed .plans-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
