/* ==========================================================================
   Product / purchase page
   Shared by product.html (Casa Ramires) and product-esfera.html (Casa da
   Esfera). Everything here is brand neutral and reads from the palette
   tokens, so the Esfera page picks up its own colours purely by loading
   esfera.css after app.css.
   ========================================================================== */

/* The breadcrumb lives in chrome.css: it is shared with land.html. The land
   section that used to sit on this page is now land.html, which carries its
   own layout CSS in a <style> block rather than a stylesheet here. */

/* ── layout ──────────────────────────────────────────────── */
.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 28px 32px 80px;
  display: grid;
  grid-template-columns: 480px 420px;
  gap: 56px;
  align-items: start;
  justify-content: center;
}

/* Float the live certificate alongside the form so the name updates stay
   visible while you type. Two column layout only: below 1040px the page is a
   single column, where a sticky preview would sit on top of the form.
   Needs .wrap's align-items:start, since a stretched grid item cannot stick. */
@media (min-width: 1041px) {
  .img-stack { position: sticky; top: 80px; align-self: start; }
}

/* A grid item's automatic minimum size is its min-content, and .img-stack's
   min-content is the certificate's true 1056px (see #cert-preview-inner), so
   without this it overflows its own column no matter how the track is sized.
   Fixing the track alone was not enough; this is the other half. */
.img-stack { min-width: 0; }

.cert-caption {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 15px;
  line-height: 1.5;
  color: var(--c-text-muted);
  text-align: center;
  margin: 14px auto 0;
  max-width: 420px;
}

/* Reserve the aspect ratio so the page does not jump before JS rescales.

   `width: 100%` is load bearing next to that aspect-ratio. Sizing runs one way
   only: width comes from the column, height is derived. With no definite width
   and an explicit height (which scaleCertPreview used to set), the ratio ran
   the other way and computed WIDTH from height, so the box latched at 416px
   and pushed the whole page sideways on a phone. Do not set a height here or
   in JS. */
/* BOTH previews, because the couple pack bought as two certificates shows two sheets.
   These were exact id selectors, so the second wrapper got no aspect-ratio and no
   overflow clipping at all: its 1056px inner would have sat unclipped in a 480px column
   and pushed the page sideways, which is the exact failure the note above describes
   being fixed once already. Attribute prefix rather than a second block, so a third
   sheet (a future family pack) is covered without another rule. */
[id^="cert-preview-wrap"] {
  aspect-ratio: 1056 / 816;
  width: 100%;
  position: relative;
  overflow: hidden;
  border: 1px solid var(--c-border);
  border-radius: 3px;
  max-width: 100%;
}
[id^="cert-preview-inner"] { width: 1056px; height: 816px; transform-origin: top left; position: relative; }

/* ── right column ────────────────────────────────────────── */
.product-info { padding-top: 4px; }
.product-info h1 {
  font-family: var(--font-serif);
  font-size: clamp(32px, 4vw, 46px);
  font-weight: 500;
  font-style: italic;
  margin: 0 0 14px;
  line-height: 1.05;
}
.price { font-family: var(--font-serif); font-size: 34px; font-weight: 600; margin: 0 0 4px; }

/* ── form controls ───────────────────────────────────────── */
.field-label {
  display: block;
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  letter-spacing: var(--ls-eyebrow);
  text-transform: uppercase;
  color: var(--c-label);
  margin-bottom: 9px;
}
.field {
  display: block;
  width: 100%;
  padding: 12px 14px;
  border: 1.5px solid var(--c-border);
  border-radius: var(--radius-sm);
  background: var(--c-surface);
  font-size: var(--fs-body);
  font-family: inherit;
  color: var(--c-text);
  margin-bottom: 22px;
  transition: border-color .15s;
}
.field:focus { outline: none; border-color: var(--c-accent); }
.field::placeholder { color: var(--c-placeholder); }

.radio-group { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 22px; }
.radio-opt { cursor: pointer; }
.radio-opt input { display: none; }
.radio-opt span {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 18px 9px 12px;
  border: 1.5px solid var(--c-border);
  border-radius: var(--radius-pill);
  font-size: 13.5px; font-weight: 500;
  color: var(--c-text-body);
  transition: all .15s;
  white-space: nowrap;
}
.radio-opt span::before {
  content: ''; display: block; width: 16px; height: 16px; border-radius: 50%;
  border: 1.5px solid var(--c-border-dot); flex-shrink: 0; transition: all .15s;
}
.radio-opt input:checked ~ span {
  background: var(--c-accent); border-color: var(--c-accent); color: var(--c-cream);
}
.radio-opt input:checked ~ span em { color: var(--c-cream) !important; }
.radio-opt input:checked ~ span::before {
  background: #fff; border-color: #fff; box-shadow: inset 0 0 0 3px var(--c-accent);
}
/* Pickers whose labels differ a lot in length stack one per line below 1040px,
   rather than wrapping raggedly mid-group.

   The pills are NOT stretched to the column width. An earlier version set
   width:100%, which made "Dom" and "1 sq ft" into full width bars several
   hundred pixels wide for a three letter label. Each pill hugs its own text and
   the group is left aligned instead. */
@media (max-width: 1040px) {
  .radio-group--stack {
    display: grid;
    grid-template-columns: max-content;
    justify-items: start;
    gap: var(--sp-2);
  }
  .radio-group--stack .radio-opt span { width: auto; }
}

/* ── validation ──────────────────────────────────────────── */
.err { color: var(--c-accent); font-size: 13px; min-height: 16px; margin-bottom: 8px; }
.field.field--error { border-color: #b0382c; }
.field-err { color: #b0382c; font-size: 13px; line-height: 1.35; margin: -14px 0 12px; display: none; }
.field-err.show { display: block; }

/* ── buy button ──────────────────────────────────────────── */
.buy-btn {
  display: block; width: 100%; padding: 17px;
  background: var(--c-ink); color: var(--c-cream);
  border: 2px solid var(--c-ink); border-radius: var(--radius-sm);
  font-family: inherit; font-weight: 700; font-size: 14px;
  letter-spacing: var(--ls-btn); text-transform: uppercase;
  cursor: pointer; transition: background .15s, border-color .15s; margin-top: 6px;
}
.buy-btn:hover { background: var(--c-accent); border-color: var(--c-accent); }
.buy-btn:disabled { opacity: .55; cursor: not-allowed; }

.gift-toggle { display: flex; align-items: center; gap: 9px; margin: 16px 0 6px; font-size: 14px; color: var(--c-text-body); cursor: pointer; user-select: none; }
.gift-toggle input { width: 16px; height: 16px; }
.guarantee { margin-top: 12px; font-size: 12.5px; color: var(--c-text-muted); text-align: center; }

/* The preview has no checkout behind it. Say so where the click happens
   rather than letting the button look broken. */
.no-checkout {
  margin-top: 14px; padding: 12px 14px;
  border: 1px dashed var(--c-border);
  border-radius: var(--radius-sm);
  font-size: 12.5px; line-height: 1.5;
  color: var(--c-text-muted); text-align: center;
  display: none;
}
.no-checkout.show { display: block; }

/* ── trust strip ─────────────────────────────────────────── */
.trust-strip { border-top: 1px solid var(--c-hairline); margin-top: 28px; padding-top: 16px; display: flex; gap: 28px; flex-wrap: wrap; }
.trust-strip span { font-size: 11px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--c-text-muted); }

/* ── what's included ─────────────────────────────────────── */
.includes { margin-top: 28px; }
.includes h3 { font-family: var(--font-serif); font-size: 19px; font-weight: 500; margin: 0 0 12px; }
.includes ul { margin: 0; padding: 0 0 0 18px; }
.includes li { font-size: 14px; line-height: 1.7; color: var(--c-text-body); padding: 1px 0; }
/* The one way through to land.html from the purchase column. A link, not a
   section: the maps do not belong on the page that takes the money. */
.includes-more { margin: 14px 0 0; font-size: 13.5px; }
.includes-more a { color: var(--c-accent); text-decoration: none; border-bottom: 1px solid rgba(27,74,99,.35); padding-bottom: 1px; }
.includes-more a:hover { border-bottom-color: var(--c-accent); }

/* ── FAQ ─────────────────────────────────────────────────── */
.faq-section { max-width: 1080px; margin: 0 auto; padding: 8px 32px 80px; }
.faq-inner { max-width: 640px; }
.faq-inner h2 { font-family: var(--font-serif); font-size: 30px; font-weight: 500; margin: 0 0 8px; }
.faq-item { border-bottom: 1px solid var(--c-hairline); }
.faq-q {
  width: 100%; background: none; border: none; text-align: left; cursor: pointer;
  padding: 18px 0; font-size: 15px; font-weight: 600; color: var(--c-text);
  font-family: inherit; display: flex; justify-content: space-between; align-items: center;
  gap: 20px; transition: color .15s;
}
.faq-q:hover { color: var(--c-accent); }
/* grid-rows 0fr to 1fr gives a smooth height animation a display toggle cannot */
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .28s ease; }
.faq-a > div { overflow: hidden; font-size: 14px; line-height: 1.7; color: var(--c-text-body); }
.faq-a.open { grid-template-rows: 1fr; }
.faq-a.open > div { padding: 4px 0 20px; }
.faq-chev { transition: transform .25s, color .15s; flex-shrink: 0; color: var(--c-text-muted); }
.faq-q:hover .faq-chev { color: var(--c-accent); }
.faq-chev.open { transform: rotate(180deg); color: var(--c-accent); }

/* ── sticky mobile buy bar ───────────────────────────────── */
.sticky-buy { display: none; }
@media (max-width: 640px) {
  /* 18px, NOT 16px, and it is the one number in here that is not a preference.
     `.wrap`, `.breadcrumb-bar` and `.faq-section` all use an 18px mobile gutter (the
     one CLAUDE.md notes matches the nav), so at 16px the price hung two pixels
     OUTSIDE the page's own left margin and the button's right edge sat two pixels
     past the content above it. Two pixels is not much to argue about in isolation
     and it is very visible on a fixed bar, because the breadcrumb and the price are
     in the same eyeline and neither lines up with anything.

     14px of vertical padding rather than 12px, and 18px of gap rather than 12px: the
     bar is the last thing between a buyer and paying, and it was the tightest
     element on the page. */
  .sticky-buy {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 150;
    align-items: center; justify-content: space-between; gap: 18px;
    padding: 14px 18px calc(14px + env(safe-area-inset-bottom, 0px));
    background: var(--c-bg); border-top: 1px solid var(--c-hairline);
    box-shadow: 0 -6px 24px rgba(0,0,0,.10);
  }
  /* `flex: 0 0 auto` and nowrap so the price keeps its own width and can never be
     squeezed or broken across two lines by the button beside it. */
  .sticky-buy .sp {
    flex: 0 0 auto; white-space: nowrap;
    font-family: var(--font-serif); font-size: 21px; font-weight: 600; color: var(--c-text);
  }
  /* No max-width. It was capped at 62%, which left a dead gap in the middle at every
     width and made the spacing read as accidental rather than chosen. The price takes
     what it needs, the gap is fixed, and the button takes the rest. */
  .sticky-buy button {
    flex: 1 1 auto; min-width: 0; background: var(--c-accent); color: var(--c-cream);
    border: none; border-radius: var(--radius-sm); padding: 14px 16px;
    font-weight: 700; font-size: 13px; letter-spacing: .08em; text-transform: uppercase;
    cursor: pointer; white-space: nowrap;
  }
  body { padding-bottom: 76px; }
}

/* ── responsive ──────────────────────────────────────────── */
@media (max-width: 1040px) {
  /* minmax(0, 1fr), not 1fr. The certificate is authored at its true 1056px
     and only SCALED by a transform, which shrinks what you see and not what
     the layout measures, so .img-stack's min-content is 416px. A plain 1fr
     track cannot go below that, and on a 375px phone it pushed the whole page
     out to 452 and left the site scrolling sideways. */
  .wrap { grid-template-columns: minmax(0, 1fr); gap: 24px; padding: 16px 18px 60px; }
  /* `width: 100%` alongside the auto margins is not redundant. Auto inline
     margins stop a grid item from stretching, so with width:auto the box falls
     back to fit-content and settles on its own 420px cap, which is wider than
     a phone. Definite width first, cap second, then centre. */
  .img-stack { width: 100%; max-width: 420px; margin: 0 auto; }
  .breadcrumb-bar { padding-left: 18px; padding-right: 18px; }
  .faq-section { padding-left: 18px; padding-right: 18px; }
  .trust-strip { gap: 14px; }
  .price { font-size: 28px; }
}
