:root {
  --primary: #4a3427;
  --accent: #b88a58;
  --accent-soft: #e8d8c8;
  --olive: #5c6b4d;
  --bg-main: #fcfaf7;
  --bg-card: #ffffff;
  --text: #2c2926;
  --text-light: #615c56;
  --white: #ffffff;
  --shadow-sm: 0 4px 20px rgba(0,0,0,0.04);
  --shadow-md: 0 12px 35px rgba(0,0,0,0.08);
  --transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}

* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
}

body {
  font-family: 'Montserrat', sans-serif;
  background-color: var(--bg-main);
  color: var(--text);
  line-height: 1.7;
  text-align: center;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ============ TIPOGRAFIA (FONTES ORIGINAIS) ============ */
h1, h2, h3, .section-subtitle, .detail-card h3, footer h2 {
  font-family: 'Alex Brush', cursive;
  font-weight: normal;
}

.font-pinyon, .ampersand, .photo-caption, .modal-content h3 {
  font-family: 'Pinyon Script', cursive;
  font-weight: normal;
}

.ampersand {
  font-size: 1.3em;
  padding: 0 8px;
  display: inline-block;
  vertical-align: middle;
  color: var(--accent);
}

/* ============ NAVBAR (COM A CORREÇÃO DA LOGO) ============ */
.navbar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  background: rgba(252, 250, 247, 0.95);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: 0 1px 15px rgba(0,0,0,0.05);
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 28px;
  padding: 18px 20px;
  z-index: 1000;
  transition: var(--transition);
}

/* CÓDIGO NOVO: FAZ O QUADRICULADO SUMIR E DEIXA APENAS A LOGO */
.navbar img {
  height: 45px; 
  margin-right: 10px;
  filter: contrast(500%) brightness(0);
  mix-blend-mode: multiply;
}

.navbar a {
  text-decoration: none;
  color: var(--text);
  font-weight: 600;
  font-size: 0.8rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  position: relative;
  padding-bottom: 4px;
  transition: var(--transition);
}

.navbar a::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  width: 0;
  height: 1.5px;
  background: var(--accent);
  transition: var(--transition);
  transform: translateX(-50%);
}

.navbar a:hover {
  color: var(--primary);
}

.navbar a:hover::after {
  width: 100%;
}

/* ============ HERO ============ */
header {
  position: relative;
  min-height: 92vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: var(--white);
  padding: 80px 20px;
  /* `../` porque url() no CSS resolve a partir do ARQUIVO .css, não da página que o importa.
     Esta folha agora mora em frontend/css/, um nível abaixo de assets/: sem o `../` o navegador
     pediria frontend/css/assets/... e receberia 404 — o hero perderia a foto e ficaria só com o
     gradiente escuro, que parece "escolha de design" e não erro. Mesma convenção da folha do
     projeto, que já vivia neste diretório. */
  background: linear-gradient(180deg, rgba(30, 20, 15, 0.5) 0%, rgba(30, 20, 15, 0.7) 100%),
              url('../assets/images/rayssa-samuel/fundo-header.jpeg') no-repeat center center/cover;
  background-attachment: fixed;
}

.hero-content {
  max-width: 800px;
  animation: fadeIn 1.2s ease-out;
}

.hero-subtitle {
  letter-spacing: 5px;
  font-size: 0.85rem;
  font-weight: 600;
  text-transform: uppercase;
  margin-bottom: 15px;
  color: rgba(255,255,255,0.95);
  text-shadow: 0 2px 4px rgba(0,0,0,0.3);
}

.names {
  font-size: clamp(3.5rem, 8vw, 6rem);
  line-height: 1.1;
  margin-bottom: 15px;
  text-shadow: 0 4px 20px rgba(0,0,0,0.5);
  letter-spacing: 2px;
}

.wedding-date {
  font-size: 1.15rem;
  letter-spacing: 4px;
  margin-bottom: 35px;
  font-weight: 500;
  color: var(--accent-soft);
  text-shadow: 0 2px 4px rgba(0,0,0,0.3);
}

.verse {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 1.3rem;
  max-width: 650px;
  margin: 0 auto;
  line-height: 1.6;
  font-weight: 500;
  color: rgba(255,255,255,0.96);
  text-shadow: 0 2px 6px rgba(0,0,0,0.4);
}

.verse span {
  display: block;
  margin-top: 8px;
  font-weight: 700;
  font-family: 'Montserrat', sans-serif;
  font-style: normal;
  font-size: 0.9rem;
  letter-spacing: 1px;
  color: var(--accent-soft);
}

/* ============ CONTADOR ============ */
.countdown-wrapper {
  margin-top: -50px;
  position: relative;
  z-index: 10;
  padding: 0 20px;
}

.countdown-container {
  background: var(--bg-card);
  color: var(--primary);
  padding: 35px 40px;
  border-radius: 16px;
  display: inline-block;
  max-width: 850px;
  width: 100%;
  box-shadow: var(--shadow-md);
  border: 1px solid rgba(184, 138, 88, 0.25);
}

#timer {
  display: flex;
  justify-content: center;
  gap: 30px;
  flex-wrap: wrap;
}

.time-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 80px;
}

.time-box span {
  font-size: 3rem;
  font-weight: 700;
  line-height: 1;
  color: var(--primary);
}

.time-box label {
  font-size: 0.75rem;
  letter-spacing: 2px;
  text-transform: uppercase;
  margin-top: 8px;
  color: var(--text-light);
  font-weight: 600;
}

/* ============ SEÇÕES ============ */
section {
  padding: 90px 20px;
  max-width: 1100px;
  margin: 0 auto;
}

.section-header {
  margin-bottom: 45px;
}

.section-subtitle {
  font-size: 3.2rem;
  color: var(--accent);
  margin-bottom: -10px;
  line-height: 1.2;
}

.section-title {
  font-size: 3.5rem;
  color: var(--primary);
  letter-spacing: 1px;
}

.section-title::after {
  content: '✦';
  display: block;
  font-size: 0.9rem;
  color: var(--accent);
  margin-top: 8px;
}

.section-desc {
  color: var(--text-light);
  max-width: 680px;
  margin: 20px auto 0;
  font-size: 1.05rem;
}

/* ============ HISTÓRIA ============ */
.story-card {
  background: var(--bg-card);
  padding: 45px;
  border-radius: 16px;
  box-shadow: var(--shadow-sm);
  border: 1px solid rgba(0,0,0,0.04);
}

.story-card p {
  font-size: 1.1rem;
  line-height: 1.85;
}

/* A história virou cinco parágrafos. Sem esta regra eles encostam um no outro
   e o bloco vira um paredão de texto — o reset zera a margem de <p>. */
.story-card p + p {
  margin-top: 1.1em;
}

/* Foto de abertura da história. Mesmo raio e sombra dos cards, para ela ler
   como parte do mesmo bloco, e não como imagem solta no meio da seção.
   `display:block` mata o espaço fantasma que o <img> inline deixa embaixo. */
.story-photo {
  max-width: 700px;
  margin: 0 auto 25px;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.story-photo img {
  display: block;
  width: 100%;
  height: auto;
}

/* ============ GALERIA ============ */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 25px;
}

.photo-card, .detail-card, .gift-card {
  background: var(--bg-card);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: var(--transition);
  position: relative;
  border: 1px solid rgba(0,0,0,0.04);
}

.photo-card:hover, .detail-card:hover, .gift-card:hover {
  transform: translateY(-8px);
  box-shadow: var(--shadow-md);
}

.photo-img-wrapper, .detail-img-wrapper, .gift-img-wrapper {
  position: relative;
  overflow: hidden;
  width: 100%;
}

.photo-img-wrapper {
  padding-top: 120%;
}

.detail-img-wrapper, .gift-img-wrapper {
  padding-top: 75%;
}

.photo-card img, .detail-img, .gift-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.photo-card:hover img, .detail-card:hover .detail-img, .gift-card:hover .gift-img {
  transform: scale(1.05);
}

.photo-caption {
  padding: 20px;
  font-size: 1.8rem;
  color: var(--primary);
}

/* ============ DETALHES ============ */
.event-details-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 30px;
  margin-bottom: 40px;
}

.detail-card {
  display: flex;
  flex-direction: column;
  text-align: center;
}

.detail-content {
  padding: 30px 25px;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  justify-content: space-between;
}

.detail-card h3 {
  color: var(--primary);
  font-size: 2.5rem;
  margin-bottom: 15px;
}

.detail-card p {
  margin-bottom: 8px;
  color: var(--text-light);
  font-size: 1rem;
}

.detail-card p strong {
  color: var(--text);
  font-weight: 600;
}

/* ============ BOTÕES ============ */
.maps-btn, .gift-btn, .submit-btn {
  display: inline-block;
  border: none;
  border-radius: 30px;
  cursor: pointer;
  font-weight: 700;
  text-decoration: none;
  text-transform: uppercase;
  transition: var(--transition);
  font-family: 'Montserrat', sans-serif;
}

.maps-btn {
  margin-top: 20px;
  background-color: var(--primary);
  color: var(--white);
  padding: 12px 28px;
  font-size: 0.85rem;
  letter-spacing: 1px;
  box-shadow: 0 4px 15px rgba(74, 52, 39, 0.2);
}

.maps-btn:hover {
  background-color: var(--accent);
  transform: translateY(-2px);
}

/* ============ DRESS CODE ============ */
.dress-code-box {
  background: linear-gradient(135deg, #f7efe6 0%, #f1e5d7 100%);
  padding: 45px;
  border-radius: 16px;
  border: 1px solid var(--accent-soft);
  box-shadow: var(--shadow-sm);
}

.dress-code-box h3 {
  color: var(--primary);
  font-size: 2.5rem;
  margin-bottom: 12px;
}

.dress-code-box > p {
  color: var(--text);
  font-size: 1.08rem;
  margin-bottom: 30px;
}

.color-palette {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 30px;
  margin: 10px 0 30px;
}

.color-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.swatch-circle {
  width: 62px;
  height: 62px;
  border-radius: 50%;
  box-shadow: 0 4px 14px rgba(0,0,0,0.15), inset 0 0 0 1px rgba(0,0,0,0.06);
  transition: var(--transition);
}

.color-swatch:hover .swatch-circle {
  transform: translateY(-5px) scale(1.08);
  box-shadow: 0 8px 20px rgba(0,0,0,0.2);
}

.swatch-label {
  font-size: 0.78rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--text-light);
}

.swatch-marrom { background: #4a3427; }
.swatch-bege { background: #d8c3a5; }
.swatch-amarelo { background: #e8c547; }
.swatch-manteiga { background: #f3e2ab; }
.swatch-branco { background: #ffffff; border: 1px solid rgba(0,0,0,0.1); }

.dress-code-notes {
  max-width: 560px;
  margin: 0 auto;
}

.small-note {
  font-size: 0.9rem !important;
  color: var(--text-light) !important;
  margin-top: 8px;
  font-style: italic;
}

/* ============ PRESENTES ============ */
.custom-cotas-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 25px;
  margin-bottom: 35px;
}

.filter-buttons {
  margin-bottom: 35px;
  display: flex;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}

.filter-btn {
  background: var(--bg-card);
  border: 1px solid rgba(0,0,0,0.1);
  padding: 10px 22px;
  border-radius: 30px;
  cursor: pointer;
  color: var(--text-light);
  font-weight: 600;
  font-size: 0.85rem;
  transition: var(--transition);
  font-family: 'Montserrat', sans-serif;
}

.filter-btn:hover, .filter-btn.active {
  background: var(--primary);
  color: var(--white);
  border-color: var(--primary);
  box-shadow: 0 4px 12px rgba(74, 52, 39, 0.2);
}

.gifts-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 25px;
}

.gift-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

.gift-content {
  padding: 22px;
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  justify-content: space-between;
  gap: 16px;
}

.gift-title {
  font-weight: 600;
  margin-bottom: 6px;
  font-size: 1.1rem;
  color: var(--primary);
  font-family: 'Montserrat', sans-serif;
}

.gift-desc {
  color: var(--text-light);
  font-size: 0.88rem;
  line-height: 1.5;
  margin-bottom: 14px;
}

.gift-price {
  color: var(--primary);
  font-weight: 700;
  margin-bottom: 12px;
  font-size: 1.15rem;
  font-family: 'Montserrat', sans-serif;
}

.gift-status {
  display: inline-block;
  background: #f1ece4;
  color: #a8a095;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  padding: 6px 16px;
  border-radius: 30px;
}

.gift-btn, .submit-btn {
  background: var(--primary);
  color: var(--white);
  padding: 12px 20px;
  width: 100%;
  font-size: 0.85rem;
  letter-spacing: 1px;
  box-shadow: 0 4px 12px rgba(74, 52, 39, 0.15);
}

.gift-btn:hover, .submit-btn:hover {
  background: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(184, 138, 88, 0.3);
}

.hidden-gift {
  display: none;
}

.load-more-wrapper {
  margin-top: 40px;
  text-align: center;
}

.load-more-btn {
  background: transparent;
  border: 1.5px solid var(--primary);
  color: var(--primary);
  padding: 12px 30px;
  border-radius: 30px;
  cursor: pointer;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  transition: var(--transition);
  font-family: 'Montserrat', sans-serif;
}

.load-more-btn:hover {
  background: var(--primary);
  color: var(--white);
  transform: translateY(-2px);
}

.load-more-btn.all-loaded {
  display: none;
}

/* ============ RSVP ============ */
.rsvp-card {
  background: var(--bg-card);
  padding: 45px 35px;
  border-radius: 16px;
  max-width: 550px;
  margin: 0 auto;
  box-shadow: var(--shadow-md);
  border-top: 5px solid var(--olive);
}

.rsvp-card form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.rsvp-card input, .rsvp-card select, .rsvp-card textarea {
  width: 100%;
  padding: 14px 18px;
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 10px;
  font-family: 'Montserrat', sans-serif;
  font-size: 1rem;
  background: #faf8f5;
  outline: none;
  transition: var(--transition);
  color: var(--text);
}

.rsvp-card input:focus, .rsvp-card select:focus, .rsvp-card textarea:focus {
  border-color: var(--accent);
  background: var(--white);
  box-shadow: 0 0 0 3px rgba(184, 138, 88, 0.15);
}

.rsvp-card input::placeholder, .rsvp-card textarea::placeholder {
  color: #8c857b;
}

/* ============ MODAL ============ */
.modal {
  display: none;
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(30, 20, 15, 0.65);
  backdrop-filter: blur(6px);
  justify-content: center;
  align-items: center;
  z-index: 2000;
  animation: fadeIn 0.3s ease;
}

.modal-content {
  background: var(--bg-card);
  padding: 40px;
  border-radius: 20px;
  max-width: 440px;
  width: 90%;
  position: relative;
  box-shadow: 0 20px 50px rgba(0,0,0,0.2);
}

.close-btn {
  position: absolute;
  top: 15px;
  right: 20px;
  font-size: 1.8rem;
  cursor: pointer;
  color: var(--text-light);
  transition: var(--transition);
  background: none;
  border: none;
  font-family: 'Montserrat', sans-serif;
}

.close-btn:hover {
  color: var(--primary);
}

.pix-box {
  background: #faf6f0;
  padding: 20px;
  border: 1.5px dashed var(--accent);
  margin: 20px 0;
  border-radius: 12px;
}

#pixKey {
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--primary);
  word-break: break-all;
  margin: 8px 0;
}

.pix-owner {
  font-size: 0.9rem;
  color: var(--text-light);
  font-weight: 500;
}

/* ============ FOOTER ============ */
footer {
  background: var(--primary);
  color: var(--white);
  padding: 60px 20px;
}

footer h2 {
  font-size: 4rem;
  margin-bottom: 10px;
}

footer p {
  font-size: 1.05rem;
}

.footer-date {
  font-size: 0.9rem;
  margin-top: 15px;
  opacity: 0.85;
  letter-spacing: 2px;
  font-weight: 500;
}

/* ============ ANIMAÇÕES ============ */
@keyframes fadeIn {
  from { opacity: 0; transform: translateY(15px); }
  to { opacity: 1; transform: translateY(0); }
}

.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: all 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}

.reveal.active {
  opacity: 1;
  transform: translateY(0);
}

/* ============ RESPONSIVIDADE ============ */
@media (max-width: 768px) {
  .navbar {
    gap: 15px;
    padding: 15px 10px;
    overflow-x: auto;
    justify-content: flex-start;
    -webkit-overflow-scrolling: touch;
  }

  /* Deixa a logo menor no celular */
  .navbar img {
    height: 30px;
    margin-right: 5px;
  }

  .navbar a {
    font-size: 0.7rem;
    letter-spacing: 1px;
    white-space: nowrap;
  }

  header {
    background-attachment: scroll;
    min-height: 80vh;
  }

  .names {
    font-size: clamp(2.5rem, 10vw, 4rem);
  }

  .section-title {
    font-size: 2.5rem;
  }

  .section-subtitle {
    font-size: 2.5rem;
  }

  .countdown-container {
    padding: 25px 20px;
  }

  .time-box span {
    font-size: 2rem;
  }

  .time-box {
    min-width: 60px;
  }

  #timer {
    gap: 15px;
  }

  section {
    padding: 60px 15px;
  }

  .story-card, .dress-code-box {
    padding: 25px;
  }

  .rsvp-card {
    padding: 30px 20px;
  }

  .modal-content {
    padding: 30px 20px;
  }
}

@media (max-width: 480px) {
  .navbar a {
    font-size: 0.65rem;
    letter-spacing: 0.5px;
  }

  .gifts-grid,
  .custom-cotas-grid,
  .event-details-grid {
    grid-template-columns: 1fr;
  }
}

/* ========================================================= */
/* ============ BOTÕES DE PAGAMENTO ============ */
/* O nome antigo destas regras era "(INFINITEPAY)". InfinitePay não existe neste
   stack: o botão primário leva ao Checkout Pro do Mercado Pago e o secundário ao
   PIX direto. Nome de gateway numa classe é convite para alguém pôr o logo de
   quem não recebe o dinheiro; o slot agora se chama pelo papel (primário). */
/* ========================================================= */
.payment-buttons {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 10px;
}

.pay-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 14px;
  border-radius: 8px;
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  transition: var(--transition);
  cursor: pointer;
  font-family: 'Montserrat', sans-serif;
  border: none;
  line-height: 1;
}

.pay-btn-primary {
  background-color: #80916c;
  color: #ffffff;
  border: 1px solid #80916c;
  box-shadow: 0 4px 12px rgba(128, 145, 108, 0.2);
}

.pay-btn-primary:hover {
  background-color: #6c7d58;
  transform: translateY(-3px);
  box-shadow: 0 8px 16px rgba(128, 145, 108, 0.3);
}

.pay-btn-pix {
  background-color: #ffffff;
  color: #4a3427;
  border: 1px solid #d1d1d1;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.pay-btn-pix:hover {
  background-color: #f9f9f9;
  border-color: #a0a0a0;
  transform: translateY(-3px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

.pay-icon {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.pay-icon-primary {
  fill: #ffffff;
}

.pay-icon-pix {
  fill: #32BCAD;
}

/* ============ RSVP: elementos que a folha ainda não cobria ============
   A regra `.rsvp-card input` acima aplica width:100% e padding a TODO input,
   inclusive radio e checkbox — o que os deixava esticados. Estes overrides
   devolvem o tamanho nativo. Tudo aqui usa as variáveis do tema. */

.rsvp-card input[type="radio"],
.rsvp-card input[type="checkbox"] {
  width: auto;
  padding: 0;
  margin: 0 10px 0 0;
  accent-color: var(--olive);
  flex-shrink: 0;
}

.rsvp-card .form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.rsvp-card label {
  font-size: 0.95rem;
  color: var(--text);
}

.rsvp-radio-group {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.rsvp-card .radio-label {
  display: flex;
  align-items: center;
  cursor: pointer;
  padding: 12px 16px;
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 10px;
  background: #faf8f5;
  transition: var(--transition);
}

.rsvp-card .radio-label:hover {
  border-color: var(--accent);
  background: var(--white);
}

/* Caixa com o nome do convidado, preenchida depois que o telefone confere. */
.guest-info-box {
  background: var(--accent-soft);
  border-radius: 10px;
  padding: 14px 18px;
  margin-bottom: 18px;
  color: var(--primary);
  font-size: 0.95rem;
}

.guest-info-box:empty { display: none; }

#companions-checkboxes {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.rsvp-total {
  font-size: 0.9rem;
  color: var(--text-light);
  font-style: italic;
}

.form-actions {
  display: flex;
  gap: 12px;
}

.form-actions .submit-btn { flex: 1; }

/* Voltar é ação secundária: mesma forma do botão principal, peso visual menor. */
.submit-btn.btn-secondary {
  background: transparent;
  color: var(--text-light);
  border: 1px solid rgba(0,0,0,0.15);
}

.form-error {
  color: #a4442f;
  font-size: 0.9rem;
  min-height: 1em;
}

.form-message {
  margin-top: 14px;
  padding: 12px 16px;
  border-radius: 10px;
  font-size: 0.95rem;
}

.form-message:empty { display: none; }
.form-message.sucesso { background: rgba(92,107,77,0.12); color: var(--olive); }
.form-message.erro    { background: rgba(164,68,47,0.10); color: #a4442f; }

/* ============================================================================
   PRESENTES, PAGAMENTO E MODAL DO PIX: o que a folha ainda não cobria
   ----------------------------------------------------------------------------
   O JS do projeto é intocável (63 testes Cypress em cima dele) e ele monta os
   cards de presente com um vocabulário de classes próprio. Então a ponte entre
   os dois desenhos é feita AQUI, no CSS: nenhuma regra acima foi alterada — o
   que existe abaixo ou é nome novo, ou repete a declaração do tema sob o nome
   que o JS emite. Tudo com as variáveis do tema.
   ============================================================================ */

/* O feedback de "✓ Copiado!" é pintado por estilo inline pelo JS, com os nomes
   var(--color-primary) e var(--color-white) escritos literalmente no script.
   Como o script não pode mudar, os dois nomes passam a existir aqui apontando
   para o tema — sem isso o botão fica sem contraste no instante do clique. */
:root {
  --color-primary: var(--primary);
  --color-white: var(--white);
}

/* O JS esconde elementos pelo atributo `hidden` (botão "carregar mais" no fim
   da lista, QR quando a rota falha). `hidden` vale display:none da folha do
   navegador — a especificidade mais fraca que existe, que QUALQUER regra de
   autor com `display` derruba em silêncio. Esta linha blinda os dois casos. */
[hidden] { display: none !important; }

/* Alvo vazio do retorno do gateway: não ocupa espaço, só existe como âncora. */
.ancora-retorno-pagamento { height: 0; }

/* O tema chama de .section-desc; o JS emite .section-description no caminho de
   erro do carrossel ("Não foi possível carregar as fotos agora."). Sem esta
   linha aquela mensagem sai crua, sem a cor apagada nem a largura máxima. */
.section-description {
  color: var(--text-light);
  max-width: 680px;
  margin: 20px auto 0;
  font-size: 1.05rem;
}

/* Texto só para leitor de tela. Fora da tela em vez de display:none, porque
   conteúdo com display:none não é lido por leitor nenhum. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- Bloco da contribuição com valor livre ---------- */
/* Um card só, centralizado — a grade de cotas do rascunho tinha dois. */
.pix-section {
  max-width: 560px;
  margin: 0 auto 40px;
}

/* ---------- Cards que o JS monta dentro do #gifts-grid ---------- */
/* O template do JS é PLANO: .gift-card recebe direto ícone, imagem, título,
   descrição, valor, status e botões — não existe o .gift-content que embrulha
   os cards escritos à mão. Sem isto o card sai sem respiro nenhum. */
#gifts-grid > .gift-card {
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* A foto estoura o padding do card para colar na borda, como no desenho
   original (lá quem fazia isso era o .gift-img-wrapper, que o JS não gera).
   O recorte 4:3 vem de aspect-ratio em vez do truque padding-top + absolute,
   porque a imagem agora é filha direta do card. As fotos vêm em proporções
   diferentes; sem caixa uniforme o grid desalinha. */
#gifts-grid > .gift-card > .gift-image {
  width: calc(100% + 44px);
  max-width: none;
  margin: -22px -22px 4px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}

/* O zoom lento ao passar o mouse é uma das interações-assinatura do desenho do
   Samuel — `.photo-card:hover img`, `.detail-card:hover .detail-img` e
   `.gift-card:hover .gift-img` compartilham a mesma escala. Como o JS emite
   `.gift-image` (e `.gift-img` ficou com zero usos), a regra irmã precisa
   existir por este nome, senão o efeito some justamente dos cards de presente.
   A transition mora na imagem, não no :hover, para valer também na saída. */
.gift-image {
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

.gift-card:hover .gift-image {
  transform: scale(1.05);
}

/* Card presenteado não sobe nem dá zoom: sem promessa de interação. */
.gift-card-presenteado:hover .gift-image {
  transform: none;
}

/* O ícone 🎁 só aparece quando o presente não tem foto. O JS emite a div de
   qualquer jeito, vazia — sem o :empty sobraria um buraco acima de toda foto. */
.gift-icon {
  font-size: 2.6rem;
  line-height: 1;
}

.gift-icon:empty { display: none; }

/* .gift-description é o nome que o JS emite; .gift-desc é o do tema. Mesmas
   declarações, sem a margem: o gap do card já separa. */
.gift-description {
  color: var(--text-light);
  font-size: 0.88rem;
  line-height: 1.5;
}

/* Idem para o preço. O margin-top:auto ancora preço, status e botões no rodapé
   do card, para que títulos de tamanhos diferentes não desalinhem a linha. */
.gift-valor {
  color: var(--primary);
  font-weight: 700;
  font-size: 1.15rem;
  font-family: 'Montserrat', sans-serif;
  margin-top: auto;
}

/* A pílula de status é inline-block, mas dentro de um flex column ela seria
   esticada até a largura toda do card. */
.gift-card > .gift-status { align-self: center; }

/* Os dois estados que o JS emite e que a folha não distinguia: "Disponível" e
   "Presenteado 💚" saíam com o mesmo bege apagado. O verde vem do --olive (o
   mesmo par já usado em .form-message.sucesso); o presenteado fica no tom
   quente do tema, apagado de propósito. */
.gift-status.disponivel {
  background: rgba(92, 107, 77, 0.12);
  color: var(--olive);
}

.gift-status.reservado {
  background: var(--accent-soft);
  color: var(--accent);
}

/* "Riscado da lista": o convidado continua vendo o item (para não escolher o
   mesmo presente duas vezes) mas sem promessa de interação — sem botão, sem
   hover que sobe. O line-through no título é verificado por teste E2E. */
.gift-card-presenteado { opacity: 0.72; }

.gift-card-presenteado:hover {
  transform: none;
  box-shadow: var(--shadow-sm);
}

.gift-card-presenteado .gift-title,
.gift-card-presenteado .gift-valor { text-decoration: line-through; }

.gift-card-presenteado .gift-image,
.gift-card-presenteado .gift-icon { filter: grayscale(1); }

/* Card de espera, trocado pelo JS assim que a API responde. */
.loading-card {
  align-items: center;
  justify-content: center;
  min-height: 200px;
  color: var(--text-light);
}

/* ---------- Botões de pagamento gerados pelo JS ---------- */
/* Mesmas declarações de .pay-btn / .pay-btn-primary / .pay-btn-pix, sob os
   nomes que o JS emite. O Mercado Pago herda o slot visual do botão primário e
   o PIX direto o do secundário, mantendo a hierarquia do desenho original. */
.gift-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 10px;
}

.btn-presentear {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 14px;
  border-radius: 8px;
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  transition: var(--transition);
  cursor: pointer;
  font-family: 'Montserrat', sans-serif;
  border: none;
  line-height: 1;
}

.btn-pay-mp {
  background-color: #80916c;
  color: #ffffff;
  border: 1px solid #80916c;
  box-shadow: 0 4px 12px rgba(128, 145, 108, 0.2);
}

.btn-pay-mp:hover {
  background-color: #6c7d58;
  transform: translateY(-3px);
  box-shadow: 0 8px 16px rgba(128, 145, 108, 0.3);
}

.btn-pay-pix {
  background-color: #ffffff;
  color: var(--primary);
  border: 1px solid #d1d1d1;
  box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.btn-pay-pix:hover {
  background-color: #f9f9f9;
  border-color: #a0a0a0;
  transform: translateY(-3px);
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
}

/* ---------- Modais ---------- */
/* A regra mais importante do arquivo. O .modal do tema já nasce display:none
   com justify/align prontos, mas ninguém trouxe a metade que acende a luz: o
   JS abre e fecha por classList.add/remove('active'). Sem esta linha os dois
   modais nunca aparecem, com o JS funcionando perfeitamente. */
.modal.active { display: flex; }

/* O .modal do tema era regra morta (o rascunho usava .modal-overlay), então
   estas duas adições não mudam nada do que já existia na tela. O formulário de
   pagamento tem quatro blocos e estoura a tela do celular — coisa que os
   modais curtos do rascunho não sofriam. */
.modal {
  padding: 20px;
  overflow-y: auto;
}

.modal-content {
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

/* A regra global de tipografia manda todo h3 dentro de .modal-content para
   Pinyon Script; o rascunho mostrava Alex Brush no título do modal. Fica a
   fonte que o Samuel via. */
.modal-content .modal-title {
  font-family: 'Alex Brush', cursive;
  font-weight: 400;
  font-size: 2.4rem;
  line-height: 1.1;
  color: var(--primary);
  margin-bottom: 6px;
}

.gp-subtitle {
  color: var(--text-light);
  font-size: 0.9rem;
  margin-bottom: 18px;
}

.gp-fixed-value {
  font-size: 1.05rem;
  color: var(--primary);
}

/* Mesma língua de campo do .rsvp-card, que já está integrado — reaproveitar o
   padrão do formulário de RSVP sai mais barato que inventar outro. */
.modal-content form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}

.modal-content .form-group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.form-label {
  font-size: 0.95rem;
  color: var(--text);
}

.form-input {
  width: 100%;
  padding: 14px 18px;
  border: 1px solid rgba(0,0,0,0.15);
  border-radius: 10px;
  font-family: 'Montserrat', sans-serif;
  font-size: 1rem;
  background: #faf8f5;
  outline: none;
  transition: var(--transition);
  color: var(--text);
}

.form-input:focus {
  border-color: var(--accent);
  background: var(--white);
  box-shadow: 0 0 0 3px rgba(184, 138, 88, 0.15);
}

.form-input::placeholder { color: #8c857b; }

.form-textarea {
  resize: vertical;
  min-height: 90px;
}

/* ---------- Modal do PIX ---------- */
.pix-info { margin-top: 6px; }

.pix-text {
  color: var(--text-light);
  font-size: 0.9rem;
  line-height: 1.6;
}

/* Fundo branco atrás do QR: o bege do .pix-box baixa o contraste, e leitor
   barato de celular depende dele. */
.pix-qr {
  display: block;
  margin: 18px auto;
  background: var(--white);
  padding: 10px;
  border-radius: 12px;
  border: 1px solid var(--accent-soft);
}

.pix-label {
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--text-light);
}

/* O dado copiável. O word-break existe porque a chave e o Copia e Cola são
   strings longas sem espaço: sem ele estouram a largura do modal. (A folha só
   tinha isso na regra por id #pixKey, que não alcança os ids novos.) */
.pix-value {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--primary);
  word-break: break-all;
  margin: 8px 0 12px;
}

/* O Copia e Cola tem ~110 caracteres. Mostrar tudo viraria um paredão de
   letrinhas dentro do modal — quem copia usa o botão, não os olhos. */
.pix-payload {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 0.75rem;
  font-weight: 500;
  word-break: normal;
}

/* Estado "sem destino confirmado". O #pix-payload e o #pix-key nascem VAZIOS no
   HTML de propósito: quem os preenche é o GET /api/settings, para que não exista
   no markup uma credencial capaz de sobreviver à troca da chave no painel. Isso
   cria um estado novo — o da API fora do ar — e ele é tratado aqui, sem tocar no
   JS (que é intocável). A caixa se explica em vez de aparecer vazia, e o botão de
   copiar some: copiar string vazia e ainda responder "✓ Copiado!" seria mentir em
   cima de uma falha, e o convidado colaria nada no app do banco. */
.pix-value:empty {
  white-space: normal;
  overflow: visible;
}

.pix-value:empty::before {
  content: 'Indisponível no momento — atualize a página ou peça a chave aos noivos.';
  display: block;
  font-size: 0.85rem;
  font-weight: 400;
  color: var(--text-light);
}

.pix-value:empty ~ .copy-btn,
.pix-value:empty ~ .pix-dica { display: none; }

.pix-dica {
  font-size: 0.8rem;
  color: var(--text-light);
  margin-top: 12px;
}

/* Pílula de "Copiar" no tamanho do modal (a base vem do .load-more-btn). */
.copy-btn {
  padding: 10px 24px;
  font-size: 0.75rem;
}

/* ---------- Toast do retorno do gateway ---------- */
/* O JS reescreve o className inteiro ("toast toast-success show"), então cada
   variante precisa existir por nome. */
.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  max-width: min(90vw, 420px);
  padding: 14px 22px;
  border-radius: 12px;
  background: var(--bg-card);
  color: var(--text);
  box-shadow: var(--shadow-md);
  font-size: 0.92rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  z-index: 3000;
}

.toast.show { opacity: 1; }

.toast-success { background: rgba(92, 107, 77, 0.95); color: var(--white); }
.toast-error   { background: rgba(164, 68, 47, 0.95); color: var(--white); }
.toast-info    { background: var(--primary); color: var(--white); }
