/*
 * The 1st Sale - builder.
 *
 * The object on a gallery wall on the left, the controls on the right. Every
 * measurement inside the poster is in cqw (a fraction of the sheet's own
 * width), never pixels, which is what lets the ~600px preview, the email
 * snapshot and the 11,820px print file carry identical proportions.
 *
 * Poster geometry itself lives in includes/poster-layout.php and arrives as CSS
 * custom properties injected by create/index.php. The fallbacks below are the
 * same values, kept only so the poster still renders if that block goes missing.
 */

@font-face {
  font-family: Inter;
  src: url("fonts/Inter-Regular-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: Inter;
  src: url("fonts/Inter-SemiBold-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 600;
  font-display: swap;
}

@font-face {
  font-family: Inter;
  src: url("fonts/Inter-Bold-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Fragment Mono";
  src: url("fonts/FragmentMono-Regular-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400;
  font-display: swap;
}

:root {
  --font-body: Inter, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-mono: "Fragment Mono", ui-monospace, SFMono-Regular, Consolas, monospace;

  --ink: #11110f;
  --surface: #fff;
  --surface-soft: #f7f7f5;
  --stage: #dcdcd7;
  --line: #deded9;
  --line-strong: #c8c8c1;
  --muted: #6d6d66;
  --green: #2c7650;
  --green-soft: #e8f2ec;
  --error: #a8392c;
  --focus: #5e755f;

  --radius-sm: 5px;
  --radius: 8px;
  --shadow-panel: -16px 0 40px rgba(26, 26, 22, 0.08);
  --shadow-frame: 0 34px 62px rgba(20, 20, 17, 0.26), 0 8px 16px rgba(20, 20, 17, 0.14);
  --transition: 180ms ease;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html,
body {
  min-height: 100%;
}

html {
  background: var(--stage);
}

body {
  margin: 0;
  color: var(--ink);
  background: var(--stage);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button,
input,
select,
textarea {
  color: inherit;
  font: inherit;
}

button,
label,
select {
  -webkit-tap-highlight-color: transparent;
}

button {
  cursor: pointer;
}

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

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ==========================================================================
   Shell
   ========================================================================== */

.builder {
  display: grid;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  grid-template-columns: minmax(0, 1fr) 448px;
  overflow: hidden;
}

/* ==========================================================================
   Preview
   ========================================================================== */

.preview-stage {
  position: relative;
  display: grid;
  min-width: 0;
  min-height: 0;
  grid-template-rows: auto minmax(0, 1fr) auto;
  overflow: hidden;
  background:
    linear-gradient(90deg, rgba(255, 255, 255, 0.3), transparent 16%, transparent 84%, rgba(0, 0, 0, 0.03)),
    #deded9;
}

.preview-header,
.preview-caption {
  position: relative;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 28px;
}

.mini-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--ink);
  text-decoration: none;
}

.mini-brand-mark {
  display: grid;
  width: 34px;
  height: 34px;
  place-items: center;
  border-radius: 50%;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 11px;
}

.mini-brand-name {
  font-size: 11px;
  font-weight: 700;
}

.preview-tools {
  display: inline-grid;
  grid-template-columns: 32px 48px 32px;
  align-items: center;
  border: 1px solid rgba(17, 17, 15, 0.13);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.54);
  backdrop-filter: blur(10px);
}

.preview-tools button {
  display: grid;
  width: 32px;
  height: 32px;
  place-items: center;
  border: 0;
  border-radius: 999px;
  background: transparent;
  font-size: 18px;
  line-height: 1;
}

.preview-tools button[disabled] {
  cursor: default;
  opacity: 0.32;
}

.preview-tools span {
  color: #5f5f59;
  font-family: var(--font-mono);
  font-size: 10px;
  text-align: center;
}

.wall-scene {
  position: relative;
  display: grid;
  min-height: 0;
  place-items: center;
  padding: 8px 56px 12px;
}

/* The skirting line. Without something at the bottom of the wall the poster
   reads as floating on a swatch rather than hanging in a room. */
.wall-scene::after {
  position: absolute;
  right: 0;
  bottom: 5%;
  left: 0;
  height: 1px;
  background: rgba(17, 17, 15, 0.06);
  box-shadow: 0 18px 32px rgba(17, 17, 15, 0.04);
  content: "";
}

/*
 * Sized to fill the wall, not to a fixed fraction of it.
 *
 * The sheet's height follows its width through aspect-ratio, so the stage's
 * spare height only gets used if the width is derived from it. --wall-height is
 * the viewport minus the preview header, the caption and some air; the
 * coefficient per shape is 1/aspect with a little margin, which is why portrait
 * (tall) gets the smallest one and landscape (wide) the largest.
 *
 * An unframed sheet is the tallest case: a frame takes width away from the
 * print faster than it adds height to the outside.
 */
.preview-scale {
  --wall-height: calc(100vh - 190px);
  z-index: 1;
  width: min(38vw, calc(var(--wall-height) * 0.7));
  min-width: 260px;
  transform: scale(var(--preview-zoom, 1));
  transition: transform 220ms ease;
}

.preview-scale.is-square {
  width: min(40vw, calc(var(--wall-height) * 0.96));
}

.preview-scale.is-landscape {
  width: min(52vw, calc(var(--wall-height) * 1.28));
}

.preview-caption {
  justify-content: center;
  gap: 8px;
  color: #60605a;
  font-family: var(--font-mono);
  font-size: 10px;
}

.live-dot {
  width: 6px;
  height: 6px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--green);
  box-shadow: 0 0 0 3px rgba(44, 118, 80, 0.12);
}

/* ==========================================================================
   Poster shell, frame and mat
   ========================================================================== */

.poster {
  position: relative;
  container-type: inline-size;
  width: 100%;
  margin: 0 auto;
  isolation: isolate;
  filter: drop-shadow(0 26px 40px rgba(18, 16, 13, 0.22));
}

/* The frame, the rabbet and the glazing live in assets/frame.css,
   which the home page hero links too so the two cannot drift. */

/* Canvas is a stretched print: it stands off the wall instead of sitting behind
   glass, so it gets a wrapped edge rather than a moulding. */
.poster.finish-canvas .poster-base {
  box-shadow:
    2.2cqw 0 0 -0.2cqw rgba(0, 0, 0, 0.28),
    0 2.6cqw 0 -0.3cqw rgba(0, 0, 0, 0.34),
    0 30px 44px rgba(18, 16, 13, 0.3);
}

/* ==========================================================================
   The printed sheet
   ==========================================================================
   container-type sits on .poster-base rather than on .poster so every cqw
   inside the artwork is a fraction of the print itself - add a frame and the
   type stays exactly the size it will be off the press. */

.poster-base {
  position: relative;
  container-type: inline-size;
  width: 100%;
  aspect-ratio: var(--poster-aspect, 3 / 4);
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(180deg, #faf8f3, #f0ece3);
  color: #12100d;
  --poster-muted: #6f695e;
  --poster-rule: #c9c2b4;
  --poster-accent: #9a7b3f;
  --poster-stamp: #8a6a2f;
}

.poster-keyline {
  position: absolute;
  z-index: 1;
  inset: var(--poster-border-inset, 4%);
  border: var(--poster-border-width, 0.32cqw) solid var(--poster-rule);
  opacity: var(--poster-border-opacity, 0.55);
  pointer-events: none;
}

.poster-canvas {
  position: absolute;
  z-index: 2;
  inset: var(--poster-margin-top, 10.5%) var(--poster-margin-x, 11.5%) var(--poster-margin-bottom, 9.5%);
  display: flex;
  flex-direction: column;
  text-align: center;
}

.tpl {
  display: none;
  flex: 1;
  min-height: 0;
  flex-direction: column;
}

.poster.template-plaque .tpl-plaque,
.poster.template-receipt .tpl-receipt,
.poster.template-signal .tpl-signal,
.poster.template-order .tpl-order,
.poster.template-timestamp .tpl-timestamp {
  display: flex;
}

/* --- shared type roles ----------------------------------------------------
   font-size, line-height, letter-spacing, font-weight and text-transform for
   every .type-* role are GENERATED by tfs_poster_layout_css() and injected by
   create/index.php. They are deliberately absent here.

   They used to be written out again in this file, and that is precisely how
   the print file came to disagree with the preview: create.css uppercased and
   tracked the business name, includes/render-service.php never saw a
   stylesheet and drew it sentence-case and untracked, so the sheet a customer
   approved was not the sheet that would have been printed. Restating a value
   from poster-layout.php in this file re-opens that gap - only the fallback in
   var(--type-*, …) may name a size, and only so the page degrades rather than
   collapsing if the generated block is ever missing.

   What stays below is what the spec does not describe: colour roles and
   numeric rendering. */

.type-monument {
  font-size: var(--type-monument, 24cqw);
  font-variant-numeric: lining-nums tabular-nums;
}

.type-display {
  font-size: var(--type-display, 7.2cqw);
}

.type-title {
  font-size: var(--type-title, 4cqw);
}

.type-lead {
  font-size: var(--type-lead, 2.1cqw);
  color: var(--poster-muted);
}

.type-body {
  font-size: var(--type-body, 1.65cqw);
}

.type-label {
  font-size: var(--type-label, 1.25cqw);
  color: var(--poster-muted);
}

.type-micro {
  font-size: var(--type-micro, 1.05cqw);
  color: var(--poster-muted);
}

.mono {
  font-family: var(--font-mono);
}

.poster-rule {
  flex: none;
  width: 100%;
  height: var(--poster-rule-width, 0.22cqw);
  margin: 0;
  border: 0;
  background: var(--poster-rule);
}

.poster-rule.short {
  width: 22%;
  margin: 0 auto;
}

.poster-logo {
  max-width: var(--poster-logo-width, 34cqw);
  max-height: var(--poster-logo-height, 5.2cqw);
  margin: 0 auto;
  object-fit: contain;
  /* One ink. A full-colour logo fights the sheet; a monochrome mark sits on it
     like a maker's stamp, which is the register the whole object is in. */
  filter: grayscale(1) contrast(1.15);
  opacity: 0.92;
}

.poster-spacer {
  flex: 1;
  min-height: 0;
}

.poster-stamp {
  display: grid;
  width: var(--poster-stamp-size, 11.6cqw);
  height: var(--poster-stamp-size, 11.6cqw);
  place-items: center;
  margin: 0 auto;
  border: var(--poster-stamp-ring, 0.35cqw) solid var(--poster-stamp);
  border-radius: 999px;
  color: var(--poster-stamp);
  font-size: calc(var(--type-label, 1.25cqw) * 1.15);
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  transform: rotate(-8deg);
}

/* Two lines, hard. The field takes 140 characters, and on a short landscape
   sheet an unclamped quote is the one piece of user content long enough to
   push the whole stack off the paper. */
.poster-annotation {
  display: -webkit-box;
  margin: 0;
  overflow: hidden;
  color: var(--poster-muted);
  font-size: var(--type-body, 1.65cqw);
  font-style: italic;
  line-height: 1.5;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

.poster-annotation cite {
  display: block;
  margin-top: 0.6em;
  font-size: 0.82em;
  font-style: normal;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* The record grid: DATE / TIME / ORDER / PAID as mono columns. Shared by the
   families that present themselves as a document rather than as an award. */
.poster-record-grid {
  display: grid;
  width: 100%;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0 1.2cqw;
  margin: 0;
  padding: 2.6cqw 0;
  border-top: var(--poster-rule-width, 0.22cqw) solid var(--poster-rule);
  border-bottom: var(--poster-rule-width, 0.22cqw) solid var(--poster-rule);
  font-family: var(--font-mono);
  text-align: left;
}

.poster-record-grid div {
  min-width: 0;
}

.poster-record-grid dt {
  margin: 0 0 1cqw;
  color: var(--poster-muted);
  font-size: var(--type-micro, 1.05cqw);
  letter-spacing: 0.1em;
}

.poster-record-grid dd {
  margin: 0;
  overflow: hidden;
  font-size: var(--type-body, 1.65cqw);
  letter-spacing: 0.01em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.poster-sheet-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.4cqw;
  width: 100%;
  padding-top: 2.2cqw;
  border-top: var(--poster-rule-width, 0.22cqw) solid var(--poster-rule);
}

.verification-mark {
  display: inline-flex;
  align-items: center;
  gap: 1cqw;
}

.verification-mark i {
  display: grid;
  width: 2.7cqw;
  height: 2.7cqw;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--font-body);
  font-size: 1.5cqw;
  font-style: normal;
}

/* --- THE PLAQUE ----------------------------------------------------------
   One enormous numeral over a lot of quiet space, with the transaction
   recorded small underneath. It should read as an award, never as an invoice. */

.tpl-plaque {
  gap: 0;
  justify-content: flex-start;
}

.tpl-plaque .plaque-eyebrow {
  margin: 0;
}

.tpl-plaque .plaque-monument {
  margin: 0.32em 0 0;
  color: var(--poster-accent);
}

/* The monument is sized off the sheet's width, but a landscape sheet is wide
   and short - at full size the stack below it has no room left. This is the
   only place the ratio has to be broken. */
.poster-landscape .tpl-plaque .plaque-monument {
  font-size: calc(var(--type-monument, 24cqw) * 0.74);
}

.tpl-plaque .plaque-business {
  margin: 0.5em 0 0;
}

.tpl-plaque .plaque-statement {
  max-width: 78%;
  margin: 0.7em auto 0;
}

.tpl-plaque .plaque-record {
  display: grid;
  gap: 0.35em;
  margin: 0;
}

.tpl-plaque .plaque-record strong {
  font-weight: 600;
}

.tpl-plaque .plaque-foot {
  display: grid;
  gap: 0.6em;
  margin: 0;
}

/* --- THE RECEIPT ---------------------------------------------------------
   A till receipt at gallery scale. Everything is mono and centred, and the
   rules are the perforations. */

.tpl-receipt {
  gap: 0;
  font-family: var(--font-mono);
}

/* space-between rather than a fixed gap: the receipt is eleven rows tall, and a
   gap sized in em overruns the sheet as soon as the canvas gets short - a
   landscape sheet has half the height of a portrait one. Distributing the rows
   across whatever height exists means every shape fits by construction. */
.tpl-receipt .receipt-column {
  display: flex;
  flex: 1;
  width: 84%;
  min-height: 0;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  margin: 0 auto;
}

.tpl-receipt .receipt-business {
  font-family: var(--font-mono);
  letter-spacing: 0.1em;
}

.tpl-receipt .receipt-total {
  font-size: calc(var(--type-display, 7.2cqw) * 0.62);
  font-weight: 700;
  letter-spacing: 0.02em;
}

.tpl-receipt .receipt-statement {
  font-size: calc(var(--type-display, 7.2cqw) * 0.42);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.tpl-receipt .receipt-paid {
  color: var(--poster-stamp);
  letter-spacing: 0.3em;
}

/* --- THE SIGNAL ----------------------------------------------------------
   The amount at full height, left-aligned like a ledger rather than centred
   like an award, with the transaction recorded underneath as data. Built for
   software founders, where there is no product photo and the number is the
   whole story. */

.tpl-signal {
  justify-content: flex-start;
  gap: 0;
  text-align: left;
}

.tpl-signal .signal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1em;
  min-height: 6cqw;
}

.tpl-signal .poster-logo {
  margin: 0;
}

.tpl-signal .signal-monument {
  margin: 0.1em 0 0;
  font-size: calc(var(--type-monument, 24cqw) * 0.52);
}

.tpl-signal .signal-step {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  margin: 1.1em 0 0;
  padding: 0.5em 0.9em;
  border: var(--poster-rule-width, 0.22cqw) solid var(--poster-accent);
  border-radius: 999px;
  color: var(--poster-accent);
  font-family: var(--font-mono);
  font-size: var(--type-body, 1.65cqw);
  letter-spacing: 0.1em;
  align-self: flex-start;
}

.tpl-signal .signal-business {
  margin: 1.1em 0 0;
}

.tpl-signal .signal-statement {
  margin: 0.5em 0 0;
  font-size: var(--type-lead, 2.1cqw);
  letter-spacing: 0.04em;
}

/* --- THE ORDER -----------------------------------------------------------
   A deliberate nod to the admin screen the founder refreshed all night, rebuilt
   in the house typeface so it is platform-neutral and ages well. */

.tpl-order {
  justify-content: flex-start;
  gap: 0;
  text-align: left;
}

.tpl-order .order-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1em;
}

.tpl-order .poster-logo {
  margin: 0;
}

.tpl-order .order-id {
  text-align: right;
}

.tpl-order .order-status {
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  margin-top: 0.5em;
  color: var(--poster-stamp);
}

.tpl-order .order-status::before {
  width: 0.62em;
  height: 0.62em;
  border-radius: 999px;
  background: currentColor;
  content: "";
}

.tpl-order .order-section {
  display: grid;
  gap: 0.45em;
  margin: 0;
}

.tpl-order .order-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1em;
}

.tpl-order .order-line strong {
  font-weight: 600;
}

.tpl-order .order-amount {
  font-weight: 700;
  white-space: nowrap;
}

.tpl-order .order-foot {
  display: grid;
  gap: 0.5em;
}

/* --- THE TIMESTAMP -------------------------------------------------------
   The year set in mono at full height - a machine-written number, not a
   designed one - over the exact moment. Reads like a historical marker, which
   is precisely the claim being made. */

.tpl-timestamp {
  justify-content: center;
  gap: 0;
}

.tpl-timestamp .timestamp-year {
  margin: 0;
  font-family: var(--font-mono);
  font-size: calc(var(--type-monument, 24cqw) * 0.86);
  letter-spacing: -0.06em;
}

.tpl-timestamp .timestamp-parts {
  display: flex;
  justify-content: center;
  gap: 1.6em;
  margin: 0.9em 0 0;
  font-family: var(--font-mono);
  font-size: var(--type-lead, 2.1cqw);
  letter-spacing: 0.24em;
}

.tpl-timestamp .timestamp-business {
  margin: 1.5em 0 0;
}

.tpl-timestamp .timestamp-statement {
  margin: 0.7em 0 0;
}

/* ==========================================================================
   Builder panel
   ========================================================================== */

.builder-panel {
  position: relative;
  z-index: 10;
  display: flex;
  min-width: 0;
  height: 100%;
  flex-direction: column;
  overflow: hidden;
  background: var(--surface);
  box-shadow: var(--shadow-panel);
}

.builder-header {
  display: flex;
  flex: 0 0 auto;
  align-items: flex-start;
  justify-content: space-between;
  padding: 24px 24px 18px;
  border-bottom: 1px solid var(--line);
}

.eyebrow,
.step-label {
  margin: 0 0 7px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1.3;
}

.builder-header h1 {
  margin: 0;
  font-size: 23px;
  line-height: 1.12;
  letter-spacing: -0.035em;
}

.close-builder {
  display: grid;
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--surface);
  color: var(--ink);
  font-size: 22px;
  line-height: 1;
  text-decoration: none;
}

.step-nav {
  display: grid;
  flex: 0 0 auto;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid var(--line);
}

.step-tab {
  position: relative;
  display: flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 0;
  background: var(--surface);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
}

.step-tab::after {
  position: absolute;
  right: 14px;
  bottom: -1px;
  left: 14px;
  height: 2px;
  background: transparent;
  content: "";
}

.step-tab.active {
  color: var(--ink);
}

.step-tab.active::after {
  background: var(--ink);
}

.step-tab span {
  display: grid;
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  place-items: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-family: var(--font-mono);
  font-size: 8px;
}

.step-tab.done span {
  border-color: var(--green);
  background: var(--green);
  color: #fff;
}

#builder-form {
  display: flex;
  min-height: 0;
  flex: 1 1 auto;
  flex-direction: column;
}

.builder-scroll {
  min-height: 0;
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: #c9c9c3 transparent;
}

.step-panel {
  display: none;
}

.step-panel.active {
  display: block;
}

.form-section {
  padding: 26px 24px 28px;
  border-bottom: 1px solid var(--line);
}

.section-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}

.section-heading h2 {
  margin: 0;
  font-size: 18px;
  line-height: 1.18;
  letter-spacing: -0.025em;
}

.privacy-chip,
.optional-chip {
  flex: 0 0 auto;
  padding: 5px 7px;
  border-radius: 3px;
  background: var(--green-soft);
  color: var(--green);
  font-family: var(--font-mono);
  font-size: 8px;
  white-space: nowrap;
}

.optional-chip {
  background: var(--surface-soft);
  color: var(--muted);
}

.section-copy {
  margin: 12px 0 20px;
  color: var(--muted);
  font-size: 13px;
}

/* --- import methods ------------------------------------------------------ */

.method-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  margin-bottom: 16px;
  padding: 3px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-soft);
}

.method-tabs button {
  min-height: 38px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--muted);
  font-size: 11px;
  font-weight: 600;
}

.method-tabs button.active {
  background: #fff;
  color: var(--ink);
  box-shadow: 0 1px 4px rgba(17, 17, 15, 0.1);
}

.source-panel {
  display: none;
  margin-bottom: 22px;
}

.source-panel.active {
  display: block;
}

.platform-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}

.platform-button {
  display: flex;
  min-height: 48px;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  font-size: 11px;
  font-weight: 600;
  text-align: left;
}

.platform-button i {
  display: grid;
  width: 24px;
  height: 24px;
  flex: 0 0 auto;
  place-items: center;
  border-radius: 5px;
  background: #20201d;
  color: #fff;
  font-family: var(--font-mono);
  font-size: 10px;
  font-style: normal;
}

.platform-button.active {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

/* Honest rather than hidden: a connector with no credentials on this host says
   so instead of opening a flow that dead-ends. */
.platform-button[data-not-ready] i {
  background: #b6b6ae;
}

.platform-button[data-not-ready] span::after {
  content: " · soon";
  color: var(--muted);
  font-weight: 400;
}

/* --- fields -------------------------------------------------------------- */

.field {
  display: block;
  min-width: 0;
  margin-top: 16px;
}

.field > span,
.control-label {
  display: block;
  margin-bottom: 7px;
  font-size: 11px;
  font-weight: 600;
}

.field > span em {
  color: var(--muted);
  font-size: 9px;
  font-style: normal;
  font-weight: 400;
}

.field input,
.field select,
.field textarea,
.input-suffix {
  width: 100%;
  min-height: 44px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: #fff;
}

.field input,
.field select,
.field textarea {
  padding: 10px 11px;
  transition: border-color var(--transition), box-shadow var(--transition);
}

.field textarea {
  min-height: 68px;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(17, 17, 15, 0.06);
  outline: 0;
}

.input-suffix {
  display: flex;
  align-items: center;
  overflow: hidden;
}

.input-suffix input {
  min-width: 0;
  flex: 1;
  border: 0;
  box-shadow: none;
}

.input-suffix em {
  padding-right: 11px;
  color: var(--muted);
  font-size: 11px;
  font-style: normal;
}

.field-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0 10px;
}

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

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

/* --- buttons ------------------------------------------------------------- */

.button-pair {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: 8px;
  margin-top: 14px;
}

.button {
  display: inline-flex;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  border: 1px solid var(--ink);
  border-radius: var(--radius-sm);
  font-size: 11px;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}

.button.primary {
  background: var(--ink);
  color: #fff;
}

.button.secondary {
  background: #fff;
  color: var(--ink);
}

.button[disabled] {
  cursor: not-allowed;
  opacity: 0.56;
}

.inline-status {
  margin: 10px 0 0;
  color: var(--muted);
  font-size: 10px;
  line-height: 1.45;
}

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

.inline-status.success {
  color: var(--green);
}

/* --- candidates ---------------------------------------------------------- */

.candidate-list {
  margin-top: 14px;
  border-top: 1px solid var(--line);
}

.candidate-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 14px 0 8px;
}

.candidate-heading strong {
  font-size: 11px;
}

.candidate-heading span {
  color: var(--green);
  font-family: var(--font-mono);
  font-size: 8px;
}

.candidate-order {
  display: grid;
  width: 100%;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  padding: 11px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  text-align: left;
}

.candidate-order strong,
.candidate-order small {
  display: block;
}

.candidate-order strong {
  margin-bottom: 3px;
  font-size: 11px;
}

.candidate-order small {
  color: var(--muted);
  font-size: 9px;
}

.candidate-order em {
  color: var(--green);
  font-size: 10px;
  font-style: normal;
  font-weight: 600;
  text-align: right;
}

.candidate-order em small {
  margin-top: 4px;
  color: var(--error);
}

.candidate-order.active {
  box-shadow: inset 3px 0 var(--ink);
  padding-left: 9px;
}

.candidate-order:hover strong {
  text-decoration: underline;
}

/* Suspicion badges — test-order detection */
.suspicion-badge {
  font-size: 10px;
  font-style: normal;
  font-weight: 600;
  text-align: right;
  color: var(--muted);
}

.suspicion-badge.suspicion-high {
  color: var(--error);
}

.suspicion-badge.suspicion-medium {
  color: color-mix(in srgb, var(--error) 50%, var(--muted));
}

.suspicion-badge small {
  display: block;
  margin-top: 4px;
  font-size: 9px;
  font-weight: 400;
  color: var(--muted);
  max-width: 100px;
}

.candidate-order--flagged {
  opacity: 0.85;
}

.candidate-order--flagged:hover {
  opacity: 1;
}

/* Trust / privacy copy */
.trust-note {
  margin: 0 0 10px;
  padding: 0;
  color: var(--muted);
  font-size: 9.5px;
  line-height: 1.5;
}

.trust-note strong {
  color: var(--ink);
  font-weight: 600;
}

/* --- upload / manual ----------------------------------------------------- */

.upload-zone {
  display: flex;
  min-height: 132px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  padding: 20px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface-soft);
  text-align: center;
  transition: border-color var(--transition), background var(--transition);
}

.upload-zone:hover {
  border-color: var(--ink);
  background: #f1f1ed;
}

.upload-icon {
  display: grid;
  width: 34px;
  height: 34px;
  margin-bottom: 9px;
  place-items: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: #fff;
  font-size: 16px;
}

.upload-zone strong {
  font-size: 12px;
}

.upload-zone small {
  margin-top: 5px;
  color: var(--muted);
  font-size: 9px;
}

.manual-note {
  display: flex;
  gap: 12px;
  padding: 15px;
  border: 1px solid #d8e5dc;
  border-radius: var(--radius);
  background: var(--green-soft);
}

.manual-note > span {
  color: var(--green);
}

.manual-note strong,
.manual-note p {
  font-size: 11px;
}

.manual-note p {
  margin: 4px 0 0;
  color: #50635a;
}

.notice-block {
  padding: 13px 15px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-soft);
  color: var(--muted);
  font-size: 11px;
  line-height: 1.5;
}

.notice-block strong {
  color: var(--ink);
}

.notice-block.warn {
  border-color: #ecd6c4;
  background: #fdf4ec;
  color: #7d4a1e;
}

.notice-block.warn strong {
  color: #6b3d16;
}

/* --- logo ---------------------------------------------------------------- */

.logo-field {
  display: flex;
  align-items: center;
  gap: 13px;
  margin-top: 18px;
}

.logo-upload,
.logo-upload span {
  display: grid;
  width: 50px;
  height: 50px;
  flex: 0 0 auto;
  place-items: center;
  overflow: hidden;
  border-radius: 50%;
}

.logo-upload {
  border: 1px dashed var(--line-strong);
  cursor: pointer;
}

.logo-upload input {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  opacity: 0;
}

.logo-upload span {
  border: 5px solid #fff;
  background: var(--ink);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 10px;
}

.logo-upload img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.logo-field strong,
.logo-field p {
  font-size: 11px;
}

.logo-field p {
  margin: 3px 0 0;
  color: var(--muted);
}

.logo-field button {
  margin-top: 5px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--error);
  font-size: 10px;
  text-decoration: underline;
}

/* --- statement presets --------------------------------------------------- */

.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 12px;
}

.chip {
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--muted);
  font-size: 10px;
}

.chip.active {
  border-color: var(--ink);
  background: var(--ink);
  color: #fff;
}

/* --- switches ------------------------------------------------------------ */

.switch-row {
  display: flex;
  min-height: 54px;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
  cursor: pointer;
}

.switch-row > span strong,
.switch-row > span small {
  display: block;
}

.switch-row > span strong {
  font-size: 11px;
}

.switch-row > span small {
  margin-top: 2px;
  color: var(--muted);
  font-size: 9px;
}

.switch-row input {
  position: absolute;
  opacity: 0;
}

.switch-row i {
  position: relative;
  width: 38px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 999px;
  background: #cdcdc7;
  transition: background var(--transition);
}

.switch-row i::after {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 3px rgba(17, 17, 15, 0.24);
  content: "";
  transition: transform var(--transition);
}

.switch-row input:checked + i {
  background: var(--green);
}

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

/* --- design pickers ------------------------------------------------------ */

.theme-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  margin-top: 18px;
}

.theme-card {
  display: grid;
  min-height: 89px;
  grid-template-columns: 48px minmax(0, 1fr);
  grid-template-rows: 1fr 1fr;
  column-gap: 10px;
  align-items: end;
  padding: 9px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  text-align: left;
}

.theme-card.active {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

/* A 48x66 stand-in for the sheet. Enough to tell the five families apart at a
   glance, which is all the picker has to do - the real one is on the left. */
.theme-mini {
  display: flex;
  width: 48px;
  height: 66px;
  grid-row: 1 / 3;
  align-items: center;
  justify-content: space-between;
  flex-direction: column;
  padding: 8px 5px;
  background: #171715;
  color: #fff;
}

.theme-mini i {
  display: block;
  width: 74%;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}

.theme-mini b {
  font-size: 17px;
  letter-spacing: -0.08em;
}

.theme-mini-receipt,
.theme-mini-order,
.theme-mini-timestamp {
  border: 1px solid #d6d0c3;
  background: #f4f0e5;
  color: #171715;
}

.theme-mini-receipt b,
.theme-mini-timestamp b {
  font-family: var(--font-mono);
  font-size: 14px;
}

.theme-mini-signal {
  background: #102e21;
}

.theme-card > strong {
  align-self: end;
  font-size: 11px;
}

.theme-card > small {
  align-self: start;
  color: var(--muted);
  font-size: 8px;
  line-height: 1.3;
}

.control-group {
  margin-top: 25px;
}

.stock-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 7px;
}

.stock-choice {
  display: grid;
  padding: 8px 4px 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  gap: 6px;
  justify-items: center;
  color: var(--muted);
  font-size: 9px;
  font-weight: 600;
}

.stock-choice.active {
  border-color: var(--ink);
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.stock-dot {
  width: 26px;
  height: 26px;
  border: 1px solid rgba(17, 17, 15, 0.18);
  border-radius: 50%;
}

.option-stack {
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
}

.choice-row {
  display: flex;
  width: 100%;
  min-height: 52px;
  align-items: center;
  justify-content: space-between;
  padding: 8px 11px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: #fff;
  text-align: left;
}

.choice-row:last-child {
  border-bottom: 0;
}

.choice-row.active {
  background: var(--surface-soft);
  box-shadow: inset 3px 0 var(--ink);
}

.choice-row span strong,
.choice-row span small {
  display: block;
}

.choice-row span strong {
  font-size: 11px;
}

.choice-row span small,
.choice-row em {
  color: var(--muted);
  font-size: 9px;
  font-style: normal;
}

.frame-options {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 7px;
}

.frame-choice {
  display: flex;
  min-height: 62px;
  align-items: center;
  justify-content: center;
  gap: 6px;
  flex-direction: column;
  padding: 7px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  font-size: 9px;
}

.frame-choice.active {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.frame-swatch {
  display: block;
  width: 27px;
  height: 30px;
  border: 4px solid;
  background: #f4f0e5;
  box-shadow: inset 0 0 0 1px #d6d0c3;
}

.frame-swatch-none {
  border: 1px dashed #8d8d86;
}

.frame-swatch-black {
  border-color: #1b1b19;
}

.frame-swatch-timber {
  border-color: #af7c42;
}

.frame-swatch-white {
  border-color: #e2e2dc;
  box-shadow: 0 0 0 1px #bdbdb7, inset 0 0 0 1px #d6d0c3;
}

.segmented-control {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
}

.segmented-control button {
  min-height: 56px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: #fff;
  text-align: left;
}

.segmented-control.three {
  grid-template-columns: repeat(3, 1fr);
}

.segmented-control button.active {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}

.segmented-control strong,
.segmented-control small {
  display: block;
}

.segmented-control strong {
  font-size: 10px;
}

.segmented-control small {
  margin-top: 3px;
  color: var(--muted);
  font-size: 8px;
}

/* --- summary ------------------------------------------------------------- */

.summary {
  display: grid;
  gap: 9px;
  margin-top: 18px;
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface-soft);
}

.summary-line {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 12px;
}

.summary-line span:first-child {
  color: var(--muted);
}

.summary-total {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: 15px;
  font-weight: 700;
}

.free-tag {
  color: var(--green);
  font-weight: 600;
}

.builder-trust {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  padding: 18px 24px 40px;
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 7px;
  text-align: center;
}

.builder-trust span {
  padding: 0 6px;
  border-right: 1px solid var(--line);
}

.builder-trust span:last-child {
  border-right: 0;
}

/* --- sticky footer ------------------------------------------------------- */

.builder-footer {
  display: grid;
  flex: 0 0 auto;
  grid-template-columns: minmax(0, 1fr) 158px;
  gap: 14px;
  align-items: center;
  padding: 15px 20px;
  border-top: 1px solid var(--line);
  background: rgba(255, 255, 255, 0.96);
  box-shadow: 0 -10px 26px rgba(17, 17, 15, 0.05);
  backdrop-filter: blur(12px);
}

.price-block span,
.price-block strong,
.price-block small {
  display: block;
}

.price-block span,
.price-block small {
  color: var(--muted);
  font-size: 9px;
}

.price-block strong {
  margin: 1px 0;
  font-size: 16px;
}

.save-button {
  display: flex;
  min-height: 48px;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 14px;
  border: 1px solid var(--ink);
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.save-button i {
  font-style: normal;
}

.save-button.ghost {
  background: #fff;
  color: var(--ink);
}

.save-button[disabled] {
  cursor: not-allowed;
  opacity: 0.56;
}

.footer-actions {
  display: grid;
  gap: 8px;
  grid-auto-flow: column;
}

/* ==========================================================================
   Narrow screens - the wall stops being a side-by-side and becomes a header
   ========================================================================== */

@media (max-width: 1060px) {
  .builder {
    height: auto;
    grid-template-columns: minmax(0, 1fr);
    overflow: visible;
  }

  .preview-stage {
    grid-template-rows: auto auto auto;
    min-height: 76vh;
  }

  .wall-scene {
    padding: 12px 20px 24px;
  }

  .preview-scale,
  .preview-scale.is-landscape,
  .preview-scale.is-square {
    width: min(78vw, 380px);
    min-width: 0;
  }

  .builder-panel {
    height: auto;
    box-shadow: none;
  }

  .builder-footer {
    position: sticky;
    bottom: 0;
  }
}

@media (max-width: 520px) {
  .preview-header,
  .preview-caption {
    padding: 14px 18px;
  }

  .form-section {
    padding: 22px 18px 24px;
  }

  .builder-header {
    padding: 20px 18px 16px;
  }

  .platform-grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .step-tab {
    font-size: 11px;
    gap: 5px;
  }

  .builder-footer {
    grid-template-columns: minmax(0, 1fr) 132px;
    padding: 13px 16px;
  }
}
