/* =============================================================
   COMPONENTS — nguyên liệu dùng lại ở nhiều khối
   Nhãn · tiêu đề · khung ảnh · nút · nav · ô nhập · lightbox · toast
   ============================================================= */

/* ---------- NHÃN & TIÊU ĐỀ ----------
   Bố cục dựa trên MỘT cặp đối lập duy nhất: chữ display khổng lồ
   (Playfair) đối trọng bằng nhãn IN HOA cỡ rất nhỏ, giãn rộng.
   Không có bậc thứ ba — thêm bậc là trang bắt đầu loạn. */

.cap {
  font-size: var(--t-cap);
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--track-cap);
  color: var(--gold);
  margin: 0 0 1.4rem;
}
.cap--ink  { color: var(--ink-3); }
.cap--lite { color: var(--gold-lt); }

.disp {
  font-family: var(--f-disp);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.012em;
}
h2.disp { font-size: var(--t-h2); }

.lead { color: var(--ink-2); max-width: 44ch; line-height: 1.85; }

.rule { height: 1px; background: var(--line); border: 0; margin: 0; }

/* Chữ ký viết tay — nhại đúng tấm biển "Save the Date" / "Just
   Married" viết tay trong chính bộ ảnh cưới. CHỈ dùng ở ba chỗ:
   dấu & ở hero, dòng Save the Date, dòng Just Married cuối trang.

   Hai chỉnh số đi kèm khi đổi Allura -> Carattere, cả hai đều là hệ
   quả của việc Carattere viết SÁT hơn:
   · word-spacing — khoảng trắng mặc định hẹp tới mức "Just Married"
     đọc ra "JustMarried".
   · padding-inline — nét vuốt ở chữ cuối tràn ra NGOÀI advance width.
     Khối cha .std có overflow:hidden nên phần vuốt đó bị cắt cụt.
     Đệm bằng em để nó co giãn cùng cỡ chữ. */
.sign {
  font-family: var(--f-sign); font-weight: 400; line-height: 1;
  letter-spacing: 0; word-spacing: .14em; padding-inline: .06em;
}

/* ---------- ÉP NHŨ ----------
   Đồng thau phẳng #A38B63 đọc ra màu mù tạt. Nhũ thật bắt sáng lệch
   một trục: tối ở hai đầu, loé ở giữa. Đúng một dải gradient là đủ,
   KHÔNG thêm chuyển động lấp lánh — nhũ trên giấy không tự nhấp nháy.

   Chỉ gắn vào ba chữ ký cỡ lớn (dấu & ở hero, Save the Date, Just
   Married). Dán lên nhãn 11px giãn chữ thì các nét mảnh cắt ngang
   gradient và ra một vệt bùn.

   Màu nền vẫn phải khai báo trước: nếu font chưa tải xong hoặc trình
   duyệt không có background-clip:text thì chữ vẫn còn màu, không biến
   thành khoảng trắng. */
.foil { color: var(--gold); }
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .foil {
    background-image: var(--foil);
    -webkit-background-clip: text;
            background-clip: text;
    color: transparent;
  }
}
/* Chế độ tương phản cưỡng bức của hệ điều hành bỏ qua ảnh nền nhưng
   GIỮ color:transparent -> chữ tàng hình. Trả lại màu đặc. */
@media (forced-colors: active) {
  .foil { background-image: none; color: var(--gold); forced-color-adjust: none; }
}

/* ---------- CON DẤU MONOGRAM ----------
   Chi tiết đắt nhất của trang và là chi tiết duy nhất kiểu này.

   Vấn đề nó giải: giữa hero và chân trang, trang chạy suốt mà không có
   một điểm nào bắt mắt dừng lại — mọi khối cùng một sức nặng. Vạch
   chuyển chương ở album vốn là chỗ trang đổi chương, nhưng một sợi chỉ
   1px thì không đủ làm một SỰ KIỆN.

   Con dấu đặt chính giữa, ngay dưới vạch: thiệp giấy thật niêm bằng
   dấu si, nên đây là hình ảnh đúng chỗ chứ không phải hoạ tiết đắp
   thêm. Chữ N & T và vòng ngày tháng vẽ bằng <text> chứ không phải
   path — dùng lại đúng ba font của trang, và sửa ngày trong
   content.js là con dấu đổi theo.

   Hai vòng tròn mảnh chứ không một vòng dày: khuôn dấu dập chìm luôn
   để lại hai đường — mép ngoài và mép trong của gờ. */
.seal { width: clamp(96px, 13vw, 132px); height: auto; overflow: visible; }
.seal circle { fill: none; stroke: var(--gold); }
.seal .s-r1  { stroke-opacity: .55; }
.seal .s-r2  { stroke-opacity: .3; }
.seal text   { fill: var(--gold-lt); }
.seal .s-mono {
  font-family: var(--f-disp); font-size: 62px; font-weight: 400;
  text-anchor: middle; dominant-baseline: central;
}
/* Dấu & viết tay. Allura có chiều cao chữ thường rất thấp nên phải
   kéo lên 52px mới không teo lại giữa hai chữ hoa; Carattere cao chữ
   thường lớn hơn hẳn, giữ nguyên 52px thì nó lấn át cả N lẫn T. */
.seal .s-amp  { font-family: var(--f-sign); font-size: 44px; fill: var(--gold); }
.seal .s-date {
  font-family: var(--f-body); font-size: 12.5px; font-weight: 400;
  letter-spacing: 3.2px; text-anchor: middle;
  font-variant-numeric: lining-nums;
  fill: var(--gold); fill-opacity: .8;
}

/* ---------- HOẠ TIẾT SVG ---------- */
.motif { fill: none; stroke: currentColor; color: var(--gold-lt); }

/* ---------- KHUNG ẢNH ----------
   Ảnh thật + một đường viền lệch phía sau: mô phỏng bóng đổ CỨNG
   của ánh sáng rèm cửa trên phông studio ở concept "Our Pure Love".

   Bẫy thứ tự vẽ, đã dính một lần: cho .shot > img z-index 1 thì ảnh
   được vẽ ở bước 9 của thuật toán xếp lớp, tức là TRÊN mọi phần tử
   định vị có z-index:auto (bước 8) — figcaption sẽ biến mất sau ảnh.
   Vì thế figcaption buộc phải có z-index riêng. */

.shot { position: relative; overflow: visible; }
.shot > img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: cover;
}
.shot::before {
  content: ""; position: absolute; inset: 0;
  border: 1px solid var(--line);
  translate: 14px 14px;
  transition: translate var(--dur) var(--ease);
}
.shot--gold::before { border-color: rgba(163, 139, 99, .45); }

/* Rê chuột lên ảnh THẬT: khung lệch trượt về khớp với ảnh, ảnh nhích
   to một chút. Không thêm bóng đổ, không đổi màu — chỉ dùng lại đúng
   cái thiết bị đã có sẵn của thiết kế (bóng cứng lệch), nên nó đọc ra
   như trang đang tự nói tiếp câu của mình.
   Chỉ máy có chuột thật; trên cảm ứng :hover kẹt lại sau khi chạm. */
@media (hover: hover) and (pointer: fine) {
  .shot[data-src] > img { transition: scale var(--dur) var(--ease); }
  .shot[data-src]:hover > img { scale: 1.035; }
  .shot[data-src]:hover::before { translate: 5px 5px; }
}

.shot figcaption {
  position: absolute; left: 0; bottom: 0; z-index: 2;
  background: rgba(35, 40, 34, .72); color: #fff;
  font-size: var(--t-micro); letter-spacing: var(--track-mic); text-transform: uppercase;
  padding: .35rem .6rem;
}

/* Chưa có ảnh -> KHÔNG để ô trống. Nhưng bản trước sai ở chỗ khác:
   MƯỜI BẢY ô giống hệt nhau, cùng một mảng xám, cùng một nhành hoa,
   cùng một dòng "Ảnh sắp có". Lặp mười bảy lần thì không đọc ra tối
   giản, đọc ra trang chưa làm xong.

   Cách sửa không phải thêm hoạ tiết mà là cho mỗi ô một THÔNG TIN
   riêng: số thứ tự chỗ ảnh sẽ nằm. Đó là dữ liệu thật (ô nào là ảnh
   nào), không phải trang trí. Hoạ tiết và dòng chú thích chỉ giữ ở ô
   ĐẦU mỗi nhóm — nói một lần là đủ cho cả nhóm.

   Nền nhạt hơn bản cũ (.035 thay vì .045) vì bây giờ đã có dấu góc
   giữ hình; mảng xám chỉ cần đủ để đọc ra "chỗ này có đặt chỗ". */
.shot--empty {
  background: rgba(35, 40, 34, .035);
  display: grid; place-items: center;
  border: 0;
}
/* Bỏ đường viền lệch: trên một ô rỗng, hai hình chữ nhật chồng nhau
   không đọc ra bóng đổ mà đọc ra lỗi dựng trang. */
.shot--empty::before { display: none; }

/* DẤU GÓC của nhà in — bốn chữ L ở bốn góc thay cho một khung kín.
   Khung kín tạo thêm một hình chữ nhật cạnh cái đã có; dấu góc thì
   giữ được hình mà không vẽ thêm cạnh nào, lại đúng ngôn ngữ "bản
   in đang lên khuôn" của cả thiết kế.

   Dùng ở MỌI ô còn đặt chỗ, không riêng ô ảnh: ô ảnh chưa có và ô mã
   QR chưa có phải nói cùng một câu, nếu không thì trang có hai kiểu
   "chưa xong" khác nhau. Chỉnh cỡ bằng --tick-in (lề) và --t (độ dài
   nét), đổi màu bằng --c. */
.shot--empty::after,
.qr--empty::after {
  content: ""; position: absolute; inset: var(--tick-in, 10px);
  pointer-events: none;
  --c: rgba(163, 139, 99, .5);
  --t: 15px;
  background:
    linear-gradient(var(--c), var(--c)) 0    0    / var(--t) 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 0    0    / 1px var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0    / var(--t) 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 0    / 1px var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) 0    100% / var(--t) 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 0    100% / 1px var(--t) no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / var(--t) 1px no-repeat,
    linear-gradient(var(--c), var(--c)) 100% 100% / 1px var(--t) no-repeat;
}
.shot--empty .motif { width: min(38%, 112px); height: auto; opacity: .8; }
/* Số ô: chữ số thẳng hàng, cỡ nhỏ, nằm trong lòng dấu góc trên-trái. */
.ph-no {
  position: absolute; top: .95rem; left: 1.15rem;
  font-family: var(--f-disp); font-weight: 400; font-size: .8rem;
  letter-spacing: .04em; color: var(--gold); opacity: .75;
}
.shot--empty span {
  position: absolute; left: 0; right: 0; bottom: 1.1rem;
  text-align: center;
  font-size: var(--t-micro); letter-spacing: var(--track-mic); text-transform: uppercase;
  color: var(--ink-3);
}

/* ---------- NÚT — ba bậc rõ ràng ----------
   Bản cũ để mọi nút đều "viền rỗng" nên không nút nào là nút chính. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  font-size: .74rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: var(--track-mic);
  padding: 1.05rem 2.3rem;
  border: 1px solid transparent; border-radius: 0;
  background: none; cursor: pointer;
  transition: background .35s var(--ease), color .35s var(--ease), border-color .35s var(--ease);
}
.btn--solid { background: var(--ink); color: var(--paper); }
.btn--solid:hover { background: var(--moss-d); }
.btn--line  { border-color: var(--ink); color: var(--ink); }
.btn--line:hover { background: var(--ink); color: var(--paper); }
.btn--lite  { border-color: rgba(198, 179, 146, .5); color: var(--cream); }
.btn--lite:hover { background: rgba(198, 179, 146, .16); }
.btn[disabled] { opacity: .5; cursor: default; }

/* ---------- THANH ĐIỀU HƯỚNG ----------
   Trong suốt khi còn nằm trên hero, đổi sang nền giấy mờ khi cuộn
   qua. Không dùng position:sticky vì hero phải chui được xuống dưới. */

.nav {
  position: fixed; inset: 0 0 auto; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 1.15rem var(--edge);
  transition: background .4s var(--ease), box-shadow .4s, padding .4s var(--ease);
}
.nav.stuck {
  background: rgba(251, 250, 247, .92);
  backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--line);
  padding-block: .8rem;
}
/* NAV-LOGO là VÙNG CHẠM, không phải một dòng chữ. Đo ở 390px ra
   57×29 — hụt chuẩn 44px của cả Apple HIG lẫn WCAG 2.5.8, mà đây lại
   đúng là chỗ ngón cái quờ vào để về đầu trang. Nới bằng min-height +
   margin âm bù lại, chứ không tăng cỡ chữ: monogram to lên là chen
   mất chỗ của thanh điều hướng ở màn hẹp. */
.nav-logo {
  font-family: var(--f-disp); font-weight: 500;
  font-size: 1.05rem; letter-spacing: .16em;
  white-space: nowrap;
  display: inline-flex; align-items: center; min-height: 44px;
  margin-block: -.55rem;
}
.nav-links { display: flex; gap: clamp(1rem, 2.4vw, 2.4rem); }
.nav-links a {
  font-size: var(--t-cap); text-transform: uppercase; letter-spacing: var(--track-mic);
  color: var(--ink-2); transition: color .3s;
  /* Vùng chạm 44px cho từng mục nav. padding dọc + margin âm bù lại
     nên chiều cao thanh không đổi. */
  display: inline-flex; align-items: center; min-height: 44px;
  margin-block: -.55rem;
}
.nav-links a:hover,
.nav-links a.active { color: var(--ink); }

/* Điện thoại: bỏ menu chữ, chỉ còn monogram. Thiệp ngắn, cuộn là đủ. */
@media (max-width: 56rem) {
  .nav-links { display: none; }
  .nav { justify-content: center; }
}

/* ---------- Ô NHẬP ---------- */

.fld { margin-bottom: 1.9rem; }
.fld label {
  display: block;
  font-size: var(--t-cap); text-transform: uppercase; letter-spacing: var(--track-mic);
  color: var(--ink-3); margin-bottom: .5rem;
}
.fld input, .fld textarea {
  width: 100%;
  border: 0; border-bottom: 1px solid var(--line);
  background: transparent;
  padding: .65rem 0;
  font-weight: 300;
  border-radius: 0;                 /* iOS tự bo góc input nếu không chặn */
}
.fld input:focus, .fld textarea:focus { outline: 0; border-color: var(--ink); }
.fld textarea { resize: vertical; min-height: 4.5rem; }

.opts { display: flex; gap: 2.2rem; flex-wrap: wrap; padding-top: .2rem; }
.opts label {
  display: inline-flex; align-items: center; gap: .5rem;
  flex: 0 0 auto; white-space: nowrap;
  font-size: 1rem; text-transform: none; letter-spacing: 0;
  color: var(--ink); margin: 0; cursor: pointer;
}
.opts input { accent-color: var(--ink); }

/* ---------- LIGHTBOX ---------- */

.lightbox {
  position: fixed; inset: 0; z-index: 400;
  background: rgba(24, 26, 32, .95);
  display: grid; place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
}
.lightbox[hidden] { display: none; }
.lightbox img { max-width: 100%; max-height: 84vh; object-fit: contain; }
.lightbox figcaption {
  color: rgba(251, 250, 247, .75); text-align: center;
  font-size: var(--t-cap); letter-spacing: var(--track-mic); text-transform: uppercase;
  margin-top: .9rem;
}
.lb-btn {
  position: absolute;
  background: none; border: 1px solid rgba(198, 179, 146, .5);
  color: var(--paper);
  width: 2.9rem; height: 2.9rem;
  font-size: 1.3rem; line-height: 1;
  display: grid; place-items: center;
  border-radius: 50%; cursor: pointer;
  transition: background .3s var(--ease);
}
.lb-btn:hover { background: rgba(198, 179, 146, .2); }
.lb-close { top: clamp(.8rem, 3vw, 1.6rem); right: clamp(.8rem, 3vw, 1.6rem); }
.lb-prev  { left:  clamp(.5rem, 2vw, 1.6rem); top: 50%; transform: translateY(-50%); }
.lb-next  { right: clamp(.5rem, 2vw, 1.6rem); top: 50%; transform: translateY(-50%); }

/* ---------- TOAST ---------- */

.toast {
  position: fixed; left: 50%; bottom: 1.6rem; z-index: 500;
  transform: translate(-50%, 140%);
  background: var(--ink); color: var(--paper);
  padding: .8rem 1.5rem;
  font-size: var(--t-small);
  border-radius: var(--radius);
  transition: transform .45s var(--ease), visibility .45s;
  pointer-events: none;
  visibility: hidden;               /* rỗng thì không được chiếm chỗ */
}
.toast.show { transform: translate(-50%, 0); visibility: visible; }
