/**
* Theme Name: Captura Child
* Description: Child theme cho Memoirs of Love. Bảng màu ivory + mực đen + nhấn đồng, tiêu đề Cormorant Garamond, thân bài Inter.
* Author: <a href="https://neuronthemes.com">NeuronThemes</a>
* Template: captura
* Version: 1.2.2
*/

/* =========================================================================
   1. Design tokens — chốt ở mốc 1.7 (2026-08-21)
   Sửa màu/font toàn site thì sửa ở đây, đừng rải giá trị cứng xuống dưới.
   ========================================================================= */

:root {
	/* Màu */
	--mol-bg:            #FAF8F4; /* ivory ấm — nền chính */
	--mol-bg-alt:        #F2EEE7; /* ivory đậm hơn — dải xen kẽ */
	--mol-ink:           #1A1815; /* mực đen — chữ chính */
	--mol-ink-soft:      #6B6560; /* xám ấm — chữ phụ, caption */
	--mol-accent:        #A8804F; /* đồng — link, nhấn */
	--mol-accent-dark:   #8A683D; /* đồng đậm — trạng thái hover */
	--mol-border:        #E5DFD6; /* viền mảnh */

	/* Font */
	--mol-font-display:  'Cormorant Garamond', 'Times New Roman', Georgia, serif;
	--mol-font-body:     'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

	/* Nhịp dọc */
	--mol-space-xs:      0.5rem;
	--mol-space-sm:      1rem;
	--mol-space-md:      2rem;
	--mol-space-lg:      4rem;
	--mol-space-xl:      7rem;  /* khoảng nghỉ giữa các section */
}

/* =========================================================================
   2. Nền tảng typography
   ========================================================================= */

body {
	background-color: var(--mol-bg);
	color: var(--mol-ink);
	font-family: var(--mol-font-body);
	font-size: 17px;
	line-height: 1.75;
	font-weight: 400;
}

h1, h2, h3, h4,
.h1, .h2, .h3, .h4 {
	font-family: var(--mol-font-display);
	color: var(--mol-ink);
	font-weight: 300;
	line-height: 1.15;
	letter-spacing: -0.01em;
}

/* clamp() để tiêu đề co giãn theo màn hình mà không cần media query */
h1, .h1 { font-size: clamp(2.5rem, 6vw, 4.5rem); }
h2, .h2 { font-size: clamp(2rem, 4.5vw, 3.25rem); font-weight: 400; }
h3, .h3 { font-size: clamp(1.5rem, 3vw, 2.25rem); font-weight: 400; }
h4, .h4 { font-size: clamp(1.25rem, 2vw, 1.5rem);  font-weight: 500; }

a {
	color: var(--mol-accent);
	text-decoration: none;
	transition: color 0.2s ease;
}

a:hover,
a:focus {
	color: var(--mol-accent-dark);
}

/* Nhãn nhỏ in hoa — dùng cho 'Chapter One', 'Melbourne, 2024'… */
.mol-label {
	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--mol-ink-soft);
}

/* =========================================================================
   3. Logo typography — placeholder tới khi khách gửi file (A5)
   ========================================================================= */

.mol-logo,
.site-title,
.n-site-header .site-title a {
	font-family: var(--mol-font-display);
	font-weight: 400;
	font-size: clamp(1.25rem, 2.2vw, 1.75rem);
	letter-spacing: 0.06em;
	color: var(--mol-ink);
	text-transform: none;
}

/* =========================================================================
   4. Footer — 3 dòng thương hiệu (việc 1.5)
   ========================================================================= */

.mol-footer {
	background-color: var(--mol-bg);
	border-top: 1px solid var(--mol-border);
	text-align: center;
	padding-top: var(--mol-space-lg);
	padding-bottom: var(--mol-space-md);
}

.mol-footer__brand {
	margin-bottom: var(--mol-space-md);
}

.mol-footer__name {
	font-family: var(--mol-font-display);
	font-size: clamp(1.5rem, 3vw, 2rem);
	font-weight: 400;
	letter-spacing: 0.06em;
	color: var(--mol-ink);
	margin: 0 0 var(--mol-space-xs);
}

.mol-footer__tagline {
	font-family: var(--mol-font-display);
	font-size: clamp(1rem, 1.6vw, 1.15rem);
	font-style: italic;
	color: var(--mol-ink-soft);
	margin: 0 0 var(--mol-space-sm);
}

.mol-footer__locations {
	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--mol-ink-soft);
	margin: 0;
}

/* Ghi đè padding mặc định của theme cha cho dòng copyright */
.mol-footer .mol-footer__copyright {
	padding: var(--mol-space-md) 0 0;
	border-top: 1px solid var(--mol-border);
	font-family: var(--mol-font-body);
	font-size: 13px;
	color: var(--mol-ink-soft);
}

/* Mobile: bó hẹp danh sách chi nhánh cho dễ đọc */
@media (max-width: 600px) {
	.mol-footer__locations {
		max-width: 22ch;
		margin-inline: auto;
		line-height: 2;
	}
}

/* =========================================================================
   5. Living Archive — story card (spec §4.2: ảnh + tên phim + địa điểm)
   =========================================================================
   Cấu trúc widget neuron-portfolio:

     article
       └─ .m-neuron-post__thumbnail--link   ← giữ tỉ lệ bằng padding-bottom:63%
            ├─ .m-neuron-portfolio__thumbnail   ← height:0, ảnh nằm absolute
            └─ .m-neuron-portfolio__overlay     ← absolute, phủ ảnh, opacity:0

   Mặc định chữ đè lên ảnh và chỉ hiện khi hover — mobile không có hover nên
   mất chữ. Khách muốn card LUÔN hiện tên phim + địa điểm.

   Cách xử lý: kéo overlay RA NGOÀI khối giữ tỉ lệ bằng `position:absolute`
   + `top:100%`, tức đặt ngay dưới đáy ảnh. Không đổi overlay sang `static`
   được — thumbnail bên trong cao 0 nên chữ sẽ rơi lên đè lên ảnh.
   ========================================================================= */

/* Specificity phải thắng `.elementor-element .m-neuron-post__thumbnail--link`
   của plugin (cùng 0,2,0 nhưng plugin nạp sau) → thêm .elementor-element. */
.elementor-element.elementor-widget-neuron-portfolio .m-neuron-post__thumbnail--link {
	overflow: visible;      /* cho overlay tràn xuống dưới */
}

/* Ảnh vẫn cắt gọn trong khung tỉ lệ */
.elementor-widget-neuron-portfolio .m-neuron-portfolio__thumbnail {
	position: absolute;
	inset: 0;
	overflow: hidden;
}

.elementor-widget-neuron-portfolio .m-neuron-portfolio__overlay {
	position: absolute;
	top: 100%;              /* ngay dưới đáy ảnh */
	right: auto;
	bottom: auto;
	left: 0;
	width: 100%;
	height: auto;
	opacity: 1;
	visibility: visible;
	background: none;
	display: block;
	text-align: left;
	padding: var(--mol-space-sm) 0 0;
}

/* Chỗ cho khối chữ dưới ảnh KHÔNG đặt ở đây — Elementor sinh CSS
   `.elementor-5862 .elementor-element-xxx .l-neuron-grid__item` với
   specificity rất cao từ setting `row_gap`. Sửa row_gap trong settings
   widget (scripts/build-archive.php) thay vì đấu CSS. */

.elementor-widget-neuron-portfolio .m-neuron-portfolio__thumbnail img {
	transition: transform 0.6s ease;
}

.elementor-widget-neuron-portfolio article:hover .m-neuron-portfolio__thumbnail img {
	transform: scale(1.03);
}

/* Tên phim */
.elementor-widget-neuron-portfolio .m-neuron-portfolio__title {
	font-family: var(--mol-font-display);
	font-weight: 400;
	font-size: 26px;
	line-height: 1.25;
	color: var(--mol-ink);
	margin: 0 0 6px;
	/* Theme cha in hoa mọi tiêu đề card. Tên phim là danh từ riêng
	   ("Lessons from Emily"), in hoa hết trông như nhãn hệ thống. */
	text-transform: none;
}

/* Địa điểm — lấy từ taxonomy portfolio_tag */
.elementor-widget-neuron-portfolio .m-neuron-portfolio__category {
	display: block;
	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--mol-ink-soft);
}

/* 5.1 — Hover hiện chữ "Watch Story" (spec §1.3)

   Widget neuron-portfolio KHÔNG có ô nhập text tuỳ ý cho overlay — repeater
   `content_order` chỉ nhận title/category/price/cart (xem
   neuron-builder/core/helpers/portfolio.php). Nên chữ này phải sinh bằng CSS.

   KHÔNG gắn được vào `.m-neuron-portfolio__overlay`: khối đó đã bị kéo xuống
   DƯỚI ảnh ở mục 5 để tên phim luôn hiện trên mobile. Gắn vào đó thì
   "Watch Story" sẽ nằm dưới ảnh và hiện thường trực, sai ý "hover reveals".

   Thay vào đó phủ một lớp lên `.m-neuron-portfolio__thumbnail` — khối này
   absolute inset:0 và có overflow:hidden, tức đúng bằng khung ảnh. */

.elementor-widget-neuron-portfolio .m-neuron-portfolio__thumbnail::after {
	content: 'Watch Story';
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;

	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.18em;
	text-transform: uppercase;
	color: #FFFFFF;

	/* Nền tối mờ để chữ trắng đọc được trên mọi ảnh cover. */
	background-color: rgba(26, 24, 21, 0.45);

	opacity: 0;
	transition: opacity 0.45s ease;

	/* Thẻ <a> phủ toàn card nằm DƯỚI lớp này trong cây DOM. Không tắt
	   pointer-events thì lớp phủ nuốt cú bấm và card mất link. */
	pointer-events: none;
}

.elementor-widget-neuron-portfolio article:hover .m-neuron-portfolio__thumbnail::after {
	opacity: 1;
}

/* Thiết bị cảm ứng không có hover — lớp phủ sẽ hoặc không bao giờ hiện, hoặc
   kẹt lại sau cú chạm. Tắt hẳn; tên phim + địa điểm dưới ảnh đã đủ thông tin. */
@media (hover: none) {
	.elementor-widget-neuron-portfolio .m-neuron-portfolio__thumbnail::after {
		content: none;
	}
}

/* 5.2 — Story chưa có ảnh cover: che ảnh placeholder của theme.

   Story 01 (Emily) và 03 (Santa) khách chưa gửi ảnh cover. Widget
   neuron-portfolio rơi về `NEURON_BUILDER_PLACEHOLDER` — file tĩnh
   `captura/assets/images/placeholder.png` in chữ "Placeholder Image" giữa
   khung. Đây là hằng PHP, không có filter WP nào chặn được, nên phải che
   ở tầng CSS.

   Chọn theo `src` bằng attribute selector: chỉ ảnh placeholder mới trúng,
   card có cover thật không bị đụng. Khi khách gửi cover, gán featured image
   là luật này tự hết tác dụng — không phải gỡ CSS. */
.elementor-widget-neuron-portfolio img[src*="placeholder.png"] {
	/* Không dùng display:none — thumbnail giữ tỉ lệ bằng padding-bottom, gỡ
	   ảnh đi thì khung vẫn còn nhưng trình duyệt vẽ icon ảnh vỡ. */
	opacity: 0;
}

.elementor-widget-neuron-portfolio article:has( img[src*="placeholder.png"] ) .m-neuron-portfolio__thumbnail {
	background-color: var(--mol-ink, #1A1815);
}

/* Nhãn thay cho ảnh — cho khách biết chỗ này đang chờ ảnh, thay vì tưởng
   card bị lỗi. Đặt trên ::before vì ::after đã dùng cho "Watch Story" (5.1). */
.elementor-widget-neuron-portfolio article:has( img[src*="placeholder.png"] ) .m-neuron-portfolio__thumbnail::before {
	content: 'Memoirs of Love';
	position: absolute;
	inset: 0;
	display: flex;
	align-items: center;
	justify-content: center;

	font-family: var(--mol-font-display);
	font-size: 22px;
	font-weight: 300;
	letter-spacing: 0.06em;
	color: rgba(255, 255, 255, 0.62);
	pointer-events: none;
}

/* Thanh lọc category */
.elementor-widget-neuron-portfolio .m-neuron-filters__item {
	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--mol-ink-soft);
	cursor: pointer;
	transition: color 0.2s ease;
}

.elementor-widget-neuron-portfolio .m-neuron-filters__item:hover,
.elementor-widget-neuron-portfolio .m-neuron-filters__item.active {
	color: var(--mol-accent);
}

/* =========================================================================
   6. Vá bug Neuron Builder — media query mobile hỏng
   =========================================================================
   Trong `neuron-builder/assets/styles/static/frontend.css` có một media
   query chưa được thay placeholder khi build:

       @media(max-width: ELEMENTOR_SCREEN_SM_MAX) { … }

   Giá trị đáng ra là 767px. Trình duyệt không hiểu chuỗi này nên bỏ qua
   TOÀN BỘ khối — trong đó có quy tắc chia cột mobile của grid
   (`l-neuron-grid-wrapper-mobile--columns__*`). Hậu quả: Living Archive
   trên điện thoại vẫn hiện 3 cột (card rộng ~133px) và tràn ngang.

   Không sửa file plugin vì bản cập nhật sau sẽ ghi đè. Chép lại đúng
   những quy tắc bị mất, đặt trong media query hợp lệ.
   ========================================================================= */

@media (max-width: 767px) {
	/* Quy tắc desktop của plugin cũng là `body .…--columns__3` (0,2,0) và nạp
	   sau, nên bản vá phải mạnh hơn — thêm html để lên (0,2,1). */
	html body .l-neuron-grid-wrapper-mobile--columns__1 .l-neuron-grid__item {
		flex: 0 0 100%;
		max-width: 100%;
	}

	html body .l-neuron-grid-wrapper-mobile--columns__2 .l-neuron-grid__item {
		flex: 0 0 50%;
		max-width: 50%;
	}

	html body .l-neuron-grid-wrapper-mobile--columns__3 .l-neuron-grid__item {
		flex: 0 0 33.3333%;
		max-width: 33.3333%;
	}

	/* Một cột thì không cần chừa nhiều chỗ như desktop */
	.elementor-widget-neuron-portfolio .l-neuron-grid__item {
		margin-bottom: 96px;
	}
}

/* --- Bổ sung GĐ 3B: bug ĐÓ CŨNG có ở breakpoint TABLET ---
   Mục 6 ở trên mới vá `ELEMENTOR_SCREEN_SM_MAX` (mobile). Nhưng plugin còn 8
   khối `@media(max-width: ELEMENTOR_SCREEN_MD_MAX)` cũng chưa thay placeholder,
   trong đó có quy tắc `l-neuron-grid-wrapper-tablet--columns__*`.

   Hậu quả: đặt `columns_tablet = 2` trong widget không có tác dụng — ở 768px
   grid vẫn giữ 3 cột của desktop, mỗi card teo còn ~249px.
   Đo được ở §3 Home; Living Archive cũng dính (chỉ chưa lộ vì card ở đó to hơn).

   Elementor mặc định tablet = 1025px trở xuống, nên chặn dưới đặt 768px để
   không giẫm lên quy tắc mobile ở trên. */
@media (min-width: 768px) and (max-width: 1024px) {
	html body .l-neuron-grid-wrapper-tablet--columns__1 .l-neuron-grid__item {
		flex: 0 0 100%;
		max-width: 100%;
	}

	html body .l-neuron-grid-wrapper-tablet--columns__2 .l-neuron-grid__item {
		flex: 0 0 50%;
		max-width: 50%;
	}

	html body .l-neuron-grid-wrapper-tablet--columns__3 .l-neuron-grid__item {
		flex: 0 0 33.3333%;
		max-width: 33.3333%;
	}
}

/* Grid dùng padding âm hai bên để bù gutter; container phải cắt phần thừa,
   nếu không trang tràn ngang vài pixel. */
.elementor-widget-neuron-portfolio {
	overflow-x: clip;
}

/* =========================================================================
   7. Home (GĐ 3B)
   ========================================================================= */

/* 7.1 — Theme cha ép `text-transform: uppercase` cho h3 (chỉ h3, h1/h2/h4
   thì không). Hậu quả: tiêu đề dịch vụ và các bước Our Process ra
   "CINEMATIC VIDEOGRAPHY" trong khi h2 ngay trên vẫn chữ thường —
   phá typography đã chốt ở 1.7 (Cormorant Garamond dáng editorial).

   Chừa lại h3 nằm trong widget Neuron (card story ở Living Archive dùng h3
   và đang uppercase có chủ đích), nên chỉ nhắm h3 của widget heading. */
.elementor-widget-heading h3.elementor-heading-title {
	text-transform: none;
	letter-spacing: normal;
}

/* 7.2 — Video nền hero: chặn chrome của YouTube.
   Elementor đã nhúng với `controls=0`, nhưng YouTube vẫn tự vẽ tiêu đề video
   ("Big Buck Bunny…"), nút pause giữa khung và thẻ "More videos" khi con trỏ
   đi qua iframe. Với video NỀN thì đó là rác — người xem không điều khiển gì.

   Phủ một lớp trong suốt lên đúng khung video để nuốt mọi sự kiện chuột;
   YouTube không thấy hover nên không hiện overlay, và chữ/nút phía trên vẫn
   bấm được vì chúng nằm ở lớp nội dung cao hơn (z-index 1 của Elementor). */
.elementor-section .elementor-background-video-container::after {
	content: "";
	position: absolute;
	inset: 0;
	z-index: 1;
}

.elementor-section .elementor-background-video-container {
	pointer-events: none;
}

/* 7.2b — Che MÀN CHỜ của YouTube.

   `pointer-events: none` ở 7.2 chỉ chặn overlay do HOVER. Nhưng YouTube còn vẽ
   sẵn thumbnail + TIÊU ĐỀ VIDEO + tên kênh + nút pause + watermark ngay khi
   iframe vừa dựng — không liên quan chuột nên 7.2 không chặn được. Với film
   khách gửi thì tiêu đề đó ghi rõ "(Do not share)", hiện đè lên chữ hero.

   ⚠️ BẢN VÁ ĐẦU (phủ nền mực rồi mờ đi sau 2.2s) SAI Ở CA QUAN TRỌNG NHẤT.
   Đo thật bằng puppeteer:
     · mạng thường / Fast 3G / Slow 3G → đều sạch, lớp che tan sau khi video chạy
     · autoplay BỊ CHẶN (Safari/iOS, trình duyệt tiết kiệm pin) → video KHÔNG
       BAO GIỜ phát, lớp che tan lúc 2.2s rồi màn chờ lộ VĨNH VIỄN.
   Che theo thời gian là ĐOÁN; phải che theo TRẠNG THÁI.

   Cách đúng: giấu hẳn iframe, chỉ hiện khi `inc/hero-video.js` xác nhận video
   đã phát thật (nó gắn `.mol-video-playing` lên section). Dưới iframe đã có sẵn
   ảnh poster `background_video_fallback` in ngay trên section — nên lúc iframe
   còn ẩn, người xem thấy poster chứ không phải khoảng trống.

   Không có JS (hoặc JS lỗi) → iframe ở nguyên trạng thái ẩn, hero thành ảnh
   tĩnh. Xấu hơn video nhưng KHÔNG BAO GIỜ lộ "(Do not share)" — đúng hướng an
   toàn cần chọn khi buộc phải hỏng. */
.elementor-section .elementor-background-video-container iframe {
	opacity: 0;
	transition: opacity 0.6s ease-out;
}

.elementor-section.mol-video-playing .elementor-background-video-container iframe {
	opacity: 1;
}

/* 7.3 — Phụ đề hero phải căn giữa.

   `_element_custom_width: 620px` bó chiều rộng đúng ý nhưng KHÔNG căn giữa ô:
   ô 620px dính mép trái cột 1392px, nên `text-align: center` chỉ căn giữa chữ
   BÊN TRONG ô đã lệch — nhìn ra là phụ đề lệch trái và dòng 2 thụt vào giữa
   một cách vô lý.

   Hai cách đã thử và ĐỀU THUA — ghi lại để khỏi làm lại:

   1. `_margin` với `left/right => 'auto'` ở setting: Elementor chỉ nhận SỐ cho
      ô margin, `auto` bị bỏ qua IM LẶNG. Đo lại vẫn `left: 24px`.

   2. `.elementor-element.mol-hero-sub { margin: auto }` (0,2,0): thua luật
      Elementor tự sinh trong `post-5859.css`:
        .elementor-5859 .elementor-element.elementor-element-065db11 {
            margin: 0px 0px calc(...) 0px }
      Đó là (0,3,0) VÀ là `margin` SHORTHAND nên nó đặt lại cả 4 cạnh, xoá
      luôn `margin-left/right: auto`.

   3. `align-self: center`: cha là flex `row` nên `align-self` tác động TRỤC
      DỌC — đo lại vẫn `left: 24px`. (Các widget xếp dọc là do wrap, không phải
      vì cha là `column` — đừng nhìn layout mà suy ra trục.)

   Cách chạy: `margin-inline: auto` kèm `!important`. Ở đây `!important` là
   đúng chỗ chứ không phải lười: đối thủ là `margin` SHORTHAND do Elementor tự
   sinh theo ID, nâng specificity bao nhiêu cũng vẫn bị nó đặt lại cả 4 cạnh
   mỗi lần build lại CSS. Chỉ ghi đè trục ngang, `margin-bottom: 40px` ở
   setting vẫn giữ nguyên. */
.elementor-element.mol-hero-sub {
	margin-inline: auto !important;
}

/* =========================================================================
   8. Our Philosophy (GĐ 3C)
   ========================================================================= */

/* 8.1 — Chân dung team ĐEN TRẮNG.
   Spec §2.4: khách chỉ định rõ ảnh chân dung phải đen trắng. Ảnh placeholder
   trong demo là ảnh màu, và ảnh thật khách gửi (A4) cũng chưa chắc đã xử lý.

   Ép bằng CSS thay vì sửa file ảnh: khách upload ảnh màu vẫn ra đúng, và nếu
   sau này khách đổi ý muốn ảnh màu thì gỡ một khối CSS là xong — không phải
   đi tìm lại ảnh gốc. */
.mol-team-portrait img {
	filter: grayscale(1);
	transition: filter 0.5s ease;

	/* Ép cùng tỉ lệ 4:5 cho cả ba chân dung.
	   Ảnh gốc mỗi tấm một tỉ lệ (742x984, 866x1000, 866x1080) nên nếu để tự do,
	   ba ảnh cao khác nhau và khối chữ dưới bị lệch bậc thang — trông cẩu thả.
	   `object-fit: cover` cắt bớt chứ không bóp méo mặt người.

	   Càng cần thiết khi khách gửi ảnh thật (A4): ảnh chụp từ nhiều nguồn gần
	   như chắc chắn lệch tỉ lệ, và khách sẽ không tự crop trước khi upload. */
	aspect-ratio: 4 / 5;
	object-fit: cover;
	width: 100%;
}

/* Ảnh hiện màu khi rê chuột — một nhịp nhỏ cho thấy đây là người thật.
   Bỏ trên thiết bị cảm ứng vì ở đó không có hover, ảnh sẽ kẹt ở trạng thái
   nào tuỳ trình duyệt. */
@media (hover: hover) {
	.mol-team-portrait img:hover {
		filter: grayscale(0);
	}
}

/* 8.1b — Ô CHỜ ẢNH — mẫu dùng chung toàn site (chốt 2026-08-24)

   Chỗ nào cần ảnh mà khách chưa gửi thì để một ô nền mực có chữ
   "Memoirs of Love", KHÔNG mượn ảnh demo. Lý do: ảnh demo trông như ảnh thật
   — người xem tưởng đó là mặt founder, là ảnh gia đình mình, hoặc là ảnh
   trong phim. Ô mực nói rõ "chỗ này đang chờ ảnh" mà vẫn giữ được nhịp
   layout, không để khoảng trắng vỡ hàng.

   Cùng ngôn ngữ với card Living Archive thiếu cover (mục 5.2) — chỗ đó phải
   che bằng attribute selector vì ảnh do PHP của theme in ra, không chặn được;
   chỗ này script chủ động dựng nên gắn class thẳng.

   Khách gửi ảnh → import với đúng slug → `mol_img_id()` trả về ID thật và
   script tự chuyển sang widget image. Không phải gỡ CSS này. */
/* ⚠️ Elementor 3.24 BỎ `.elementor-widget-container` cho text-editor — `<span>`
   là con TRỰC TIẾP của wrapper mang `_css_classes`. Nên flex đặt thẳng ở đây.
   Đừng chép luật `> .elementor-widget-container` từ widget khác sang: selector
   không trúng gì cả và chữ rơi lên mép trên (đã thấy thật). Kiểm bằng
   `outerHTML` trước khi viết selector con, đừng đoán theo widget khác. */
/* ⚠️ Phải khai kèm `.elementor-element` để lên (0,2,0).
   Elementor có HAI luật cùng (0,1,0) đánh vào đúng chỗ này:
     .elementor-element { --align-items: initial }
     .elementor-element:where(.e-con-full, .elementor-widget) {
         align-items: var(--align-items) }
   (`:where()` tính 0 nên luật thứ hai vẫn là 0,1,0.) Class đơn của child
   theme BẰNG điểm mà nạp TRƯỚC → thua cả hai: đo ra `align-items: normal`,
   `<span>` bị kéo cao hết ô và chữ dính mép trên. Đặt qua biến cũng vô ích
   vì `--align-items: initial` cũng thắng nốt.
   (Bẫy specificity plugin-thắng-child-theme, lần thứ 4 — xem mục 3.9.) */
.elementor-element.mol-photo-pending {
	display: flex;
	align-items: center;
	justify-content: center;

	background-color: var(--mol-ink);

	/* Chữ phải khai trên chính <span> bên trong: script đặt typography cho
	   widget text-editor, và Elementor sinh luật `.elementor-element-<id>`
	   (0,1,0 + inline id) đè lên class thường — đo ra 17px thay vì 22px.
	   Nhắm vào <span> thì không có luật nào của Elementor tranh chấp. */
	text-align: center;
}

.mol-photo-pending p {
	margin: 0;
}

.mol-photo-pending span {
	font-family: var(--mol-font-display);
	font-size: 22px;
	font-weight: 300;
	letter-spacing: 0.06em;
	color: rgba(255, 255, 255, 0.62);
	line-height: 1.4;
}

/* Chân dung team: cùng tỉ lệ 4:5 với `.mol-team-portrait` để hai cột không
   lệch bậc thang khi một người có ảnh còn một người chưa. */
.mol-photo-pending--portrait {
	aspect-ratio: 4 / 5;
	width: 100%;
}

/* Ảnh ngang (Home §4 "What We Make"). 3:2 là tỉ lệ hai ảnh dịch vụ cũ, giữ
   nguyên để khối chữ bên dưới không nhảy bậc khi khách gửi được một bên. */
.mol-photo-pending--landscape {
	aspect-ratio: 3 / 2;
	width: 100%;
}

/* Băng ngang cho ảnh chương Memory Box (18 chương trên 3 story).

   Dùng `min-height` cố định chứ KHÔNG `aspect-ratio`: ảnh chương là full-width,
   3:2 ở 1440px ra ~950px mỗi ô — 18 ô như vậy làm trang story dài gấp ba và
   biến Memory Box thành dãy ô đen liên tiếp. 220px đủ để nhận ra "chỗ này chờ
   ảnh" mà vẫn giữ được nhịp đọc.

   Ảnh thật khách gửi vẫn full-width bình thường — luật này chỉ áp cho ô chờ. */
.mol-photo-pending--band {
	min-height: 220px;
	width: 100%;
}

@media (max-width: 767px) {
	.mol-photo-pending--band {
		min-height: 150px;
	}
}

/* MÃ ẢNH trên ô chờ (vd `S1-MB2`).

   Để khách gửi ảnh không phải mô tả bằng lời "ảnh chương thứ hai của story
   Emily" — chỉ cần đặt tên file đúng mã in trên ô. Mã cũng CHÍNH LÀ slug
   `_mol_src` khi import (chữ thường), nên gửi `S1-MB2.jpg` → import slug
   `s1-mb2` → ô chờ tự thành ảnh, không phải sửa script.

   Hai <span> nên phải đổi ô chứa sang `flex-direction: column` (mặc định là
   `row`, hai span sẽ nằm cạnh nhau trên một dòng). */
.elementor-element.mol-photo-pending:has(.mol-photo-code) {
	flex-direction: column;
	gap: 10px;
}

.mol-photo-pending .mol-photo-code {
	font-family: var(--mol-font-body);
	font-size: 12px;
	font-weight: 500;
	letter-spacing: 0.16em;
	/* Màu đồng của bảng màu — đủ nổi để đọc, đủ nhạt để không tranh chấp với
	   tên chương ngay bên dưới ô. */
	color: rgba(168, 128, 79, 0.9);
	border: 1px solid rgba(168, 128, 79, 0.42);
	border-radius: 2px;
	padding: 4px 12px;
	line-height: 1;
}

/* Ô hẹp thì chữ 22px tràn ngang. Trên mobile cột co lại còn ~330px, và ở
   tablet 2 cột còn hẹp hơn nữa. */
@media (max-width: 1024px) {
	.mol-photo-pending span {
		font-size: 18px;
	}
}

/* 8.2 — Our Values: 5 khối phải xuống hàng (3 + 2)

   Khách gửi 5 value (2026-08-24) thay cho 3 khối Authentic/Cinematic/Timeless.
   Mỗi cột đặt `_inline_size: 33.33` để thành lưới 3 cột, NHƯNG Elementor để
   `.elementor-container` ở `flex-wrap: nowrap` → cả 5 cột bị ép vào một hàng,
   mỗi cột teo còn 200px ở 1440px (đo thật bằng verify/phi-values.js).
   `_inline_size` KHÔNG tự bật wrap — phải mở bằng CSS.

   Chỉ mở wrap cho đúng section này, không đụng section khác: nhiều section
   2 cột trong site đang DỰA vào nowrap để ảnh và chữ nằm cạnh nhau. */
.mol-values-grid > .elementor-container {
	flex-wrap: wrap;
}

/* Hàng cuối chỉ có 2 khối → căn giữa cho cân, thay vì dồn trái chừa
   khoảng trống lệch bên phải. */
.mol-values-grid > .elementor-container {
	justify-content: center;
}

/* =========================================================================
   9. The Experience (GĐ 3D)
   ========================================================================= */

/* 9.1 — Câu hỏi FAQ bị ép CHỮ HOA.
   Cùng gốc với 7.1 (theme cha đặt `text-transform: uppercase` cho h3), nhưng
   bản vá 7.1 chỉ nhắm `.elementor-widget-heading h3` nên không phủ được
   accordion: widget nested-accordion bọc tiêu đề trong thẻ do `title_tag`
   quyết định, và ở đây là h3.

   Hậu quả trước khi vá: "HOW LONG DOES FILMING TAKE?" — chữ hoa Cormorant
   Garamond trông như tiêu đề bảng giá, đúng thứ khách bỏ đi có chủ đích
   (spec 3.6 ghi rõ FAQ dựng "instead of pricing").

   Nhắm cả thẻ tiêu đề lẫn phần tử chữ bên trong: nếu sau này đổi `title_tag`
   sang h2/h4 thì luật vẫn đúng, khỏi phải nhớ quay lại sửa CSS. */
.elementor-widget-n-accordion .e-n-accordion-item-title,
.elementor-widget-n-accordion .e-n-accordion-item-title-text,
.elementor-widget-n-accordion .e-n-accordion-item-title-header,
.elementor-widget-n-accordion .e-n-accordion-item-title-header > * {
	text-transform: none;
	letter-spacing: normal;
}

/* 9.2 — Con trỏ tay trên cả dòng câu hỏi.
   Mặc định chỉ vùng chữ mới báo là bấm được, trong khi cả dòng (rộng hết
   820px) đều mở accordion. Người dùng rê vào khoảng trắng giữa chữ và dấu +
   không thấy tín hiệu gì nên tưởng phải bấm trúng chữ. */
.elementor-widget-n-accordion .e-n-accordion-item-title {
	cursor: pointer;
}

/* 9.3 — Màu tiêu đề FAQ lệch khỏi token 1.7.
   Widget nested-accordion tô màu bằng biến RIÊNG của nó
   (`--n-accordion-title-normal-color`), mặc định `#1F2124` — không phải mực
   đen `#1A1815` đã chốt. Lệch nhẹ nên mắt thường khó bắt, nhưng đặt cạnh h2
   ngay trên (đúng token) thì hai sắc đen không khớp nhau.

   Sửa bằng cách gán lại chính biến của widget, KHÔNG ghi đè `color` —
   làm vậy thì trạng thái hover/active của widget vẫn chạy bình thường,
   khỏi phải viết lại cả ba trạng thái.

   ⚠️ Phải tăng specificity: luật gốc là `.elementor-widget-n-accordion`
   (0,1,0) nằm trong CSS plugin, mà CSS plugin nạp SAU style.css của child
   theme — cùng trọng số thì file sau thắng. Viết
   `html body .elementor-widget.elementor-widget-n-accordion` (0,3,2) để
   thắng chắc. Cùng bẫy đã gặp ở 3A với media query của Neuron. */
html body .elementor-widget.elementor-widget-n-accordion {
	--n-accordion-title-normal-color: var(--mol-ink);
	--n-accordion-title-hover-color:  var(--mol-accent);
	--n-accordion-title-active-color: var(--mol-ink);
	--n-accordion-icon-normal-color:  var(--mol-ink-soft);
	--n-accordion-icon-hover-color:   var(--mol-accent);
	--n-accordion-icon-active-color:  var(--mol-accent);
}

/* =========================================================================
   10. Begin Your Story (GĐ 3E) — form
   ========================================================================= */

/* Widget form của Neuron ra giao diện mặc định của PLUGIN, không theo design
   token đã chốt ở 1.7: nút Send màu xanh lá, nhãn Inter xám, dấu * đỏ gắt,
   checkbox/radio dính sát nhau. Trên trang mà khách yêu cầu "Simple. Elegant.
   Large whitespace." thì đó là thứ phá hỏng cả trang.

   Style lại toàn bộ ở đây thay vì nhồi setting vào script build: widget này
   có hàng trăm control style, đặt qua JSON thì script phình ra và sau này
   muốn chỉnh một chi tiết lại phải chạy lại script. CSS sửa trực tiếp,
   thấy ngay. */

/* 10.1 — Nhãn trường */
.mol-form .m-neuron-form__label {
	font-family: var(--mol-font-body);
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.02em;
	color: var(--mol-ink);
	margin-bottom: 10px;
	display: block;
}

/* Dấu * bắt buộc: dùng màu đồng thay vì đỏ. Vẫn đủ để nhận ra, nhưng không
   biến form thành bảng cảnh báo — người điền đang kể chuyện gia đình. */
.mol-form .m-neuron-form__field-group--mark-required .m-neuron-form__label:after {
	color: var(--mol-accent);
}

/* 10.2 — Ô nhập
   Chỉ một vạch dưới thay vì khung hộp: nhẹ hơn, hợp với trang nhiều khoảng
   trắng, và giống mạch vạch mảnh dùng ở FAQ và Our Values. */
.mol-form .m-neuron-form__field,
.mol-form input.m-neuron-form__field,
.mol-form textarea.m-neuron-form__field {
	font-family: var(--mol-font-body);
	font-size: 16px;
	color: var(--mol-ink);
	background: transparent;
	border: 0;
	border-bottom: 1px solid var(--mol-border);
	border-radius: 0;
	padding: 12px 2px;
	box-shadow: none;
	transition: border-color 0.25s ease;
}

.mol-form .m-neuron-form__field:focus,
.mol-form input.m-neuron-form__field:focus,
.mol-form textarea.m-neuron-form__field:focus {
	outline: none;
	border-bottom-color: var(--mol-accent);
	box-shadow: none;
}

.mol-form .m-neuron-form__field::placeholder {
	color: var(--mol-ink-soft);
	opacity: 0.65;
}

.mol-form textarea.m-neuron-form__field {
	resize: vertical;
	min-height: 120px;
	line-height: 1.7;
}

/* 10.3 — Khoảng cách giữa các trường.
   "Large whitespace" là chữ của khách, không phải gu riêng. */
.mol-form .m-neuron-form__field-group {
	margin-bottom: 34px;
}

/* 10.4 — Checkbox và radio
   `inline_list` của Neuron render ra class LITERAL là "yes" (đúng như giá
   trị setting) chứ không kèm CSS nào — tức bật setting xong vẫn phải tự
   xếp hàng ngang. Không có luật dưới đây thì 6 lựa chọn milestone dính
   thành một khối chữ liền, không thấy đâu là ô tick. */
.mol-form .m-neuron-form__subgroup {
	display: flex;
	flex-wrap: wrap;
	gap: 14px 28px;
	margin-top: 6px;
}

.mol-form .m-neuron-form__option {
	display: flex;
	align-items: center;
	gap: 9px;
	font-family: var(--mol-font-body);
	font-size: 15px;
	color: var(--mol-ink);
	cursor: pointer;
}

/* Ô tick to hơn mặc định — trên mobile ngón tay phải bấm trúng. */
.mol-form .m-neuron-form__option input[type="checkbox"],
.mol-form .m-neuron-form__option input[type="radio"] {
	width: 17px;
	height: 17px;
	margin: 0;
	accent-color: var(--mol-accent);
	flex: none;
	cursor: pointer;
}

/* 10.5 — Nút Send
   ⚠️ Màu nền và font của nút KHÔNG đặt được ở đây — xem `build-begin.php`.

   Nền nút do group control `button_background` của widget sinh ra, mặc định
   lấy Global Color ACCENT của Elementor Kit (xanh lá còn sót từ demo
   Captura). Elementor ghi luật vào `post-5864.css`, nạp SAU style.css này
   với cùng trọng số → luật ở đây thua ở đúng `background` và `font-family`,
   trong khi các thuộc tính khác vẫn thắng. Triệu chứng dễ nhầm: CSS trông
   như "ăn một nửa".

   Đã chuyển màu/font nút sang setting của widget trong build-begin.php.
   Chỉ giữ lại ở đây phần Elementor không đụng tới. */

/* Nút trải hết bề ngang trên mobile — dễ bấm hơn nút hẹp giữa màn hình. */
@media (max-width: 767px) {
	.mol-form .m-neuron-form__submit-button {
		width: 100%;
	}
}

/* 10.6 — Thông báo sau khi gửi */
.mol-form .m-neuron-message,
.mol-form [class*="m-neuron-form__messages"] {
	font-family: var(--mol-font-body);
	font-size: 15px;
	line-height: 1.7;
	margin-top: 18px;
}

/* ============================================================
   10.7 — Ghi đè CSS plugin & Elementor cho form (mol-form)
   ------------------------------------------------------------
   ⚠️ Bẫy đã mất công truy: `_css_classes = mol-form` của Elementor gắn lên
   DIV WRAPPER của widget, KHÔNG gắn lên thẻ <form>. Wrapper đó là:
       <div class="elementor-element ... mol-form elementor-widget-neuron-form">
   tức `.mol-form` và `.elementor-widget-neuron-form` là CÙNG MỘT phần tử.
   Viết `.elementor-widget-neuron-form .mol-form` (dấu cách) thì không phần tử
   nào khớp và cả block im lặng không ăn — phải nối bằng dấu chấm.
   Thẻ <form> bên trong mới mang class `m-neuron-form`.

   Mục 10.1–10.6 ở trên viết đúng class nhưng THUA ở 5 thuộc tính, vì
   `neuron-builder/frontend.css` và `post-5864.css` đều nạp SAU style.css:

     - `.elementor-5864 .elementor-element.elementor-element-0f5188c
       .m-neuron-form__field-group` (0,4,0) đè margin-bottom 34px về 10px.
     - `.m-neuron-form__subgroup { flex-direction:column }` của plugin không
       bị luật nào ở trên phủ (10.4 không khai flex-direction) → checkbox và
       radio xếp DỌC dù đã bật inline_list.
     - `post-5864.css` gán font Global Kit cho `.m-neuron-form__subgroup label`
       → label option lệch font so với label trường.
     - Plugin vẽ lại radio bằng :before/:after border #000 → radio đen trong
       khi checkbox ăn accent-color đồng.

   Nên phần này bám thang specificity của đối thủ bằng cách chồng class trên
   cùng một phần tử, KHÔNG dùng !important.
   ============================================================ */

/* Plugin đặt align-items:flex-end → hai trường Name/Email cùng hàng bị dóng
   theo đáy, lệch khi một bên xuống dòng. Dóng theo đầu mới đều.
   Gộp luôn margin-bottom âm 10px Elementor đặt trên <form> để bù khuôn:
   trường cuối đã có 34px nên phần âm đó kéo nút dính lên. */
.elementor-widget-neuron-form.mol-form .m-neuron-form {
	align-items: flex-start;
	margin-bottom: 0;
}

/* Khoảng cách giữa các trường.
   Đối thủ là `.elementor-5864 .elementor-element.elementor-element-0f5188c
   .m-neuron-form__field-group` = (0,4,0). Bám bằng cách lặp class widget và
   class group trên cùng phần tử → (0,5,0), không cần !important.
   Elementor cũng đặt padding 5px hai bên (khuôn 10px của widget); giữ nguyên
   chiều ngang, chỉ chỉnh chiều dọc. */
.elementor-widget-neuron-form.mol-form.elementor-widget-neuron-form .m-neuron-form__field-group.m-neuron-form__field-group {
	margin-bottom: 34px;
}

/* Trường cuối không cần khoảng thừa trước nút */
.elementor-widget-neuron-form.mol-form.elementor-widget-neuron-form .m-neuron-form__field-group.m-neuron-form__button {
	margin-top: 8px;
	margin-bottom: 0;
}

/* Xếp ngang checkbox/radio: phải khai flex-direction, bật inline_list không đủ */
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup {
	flex-direction: row;
	flex-wrap: wrap;
	gap: 14px 28px;
	margin-top: 10px;
}

/* Plugin thêm margin-right:10px cho mọi option trừ cái cuối; để nguyên thì
   khoảng cách ngang thành 28+10, không đều với khoảng cách dọc. */
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup .m-neuron-form__option:not(:last-of-type) {
	margin-right: 0;
}

/* Label của option: post-5864.css gán font Global Kit ở đây, nên phải khai
   lại cả font-family lẫn weight mới về đúng Inter của trang. */
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup label,
.elementor-widget-neuron-form.mol-form .m-neuron-form__option label {
	font-family: var(--mol-font-body);
	font-size: 15px;
	font-weight: 400;
	line-height: 1.5;
	color: var(--mol-ink);
	margin-bottom: 0;
	cursor: pointer;
}

/* Radio: plugin ẩn input gốc rồi vẽ vòng tròn bằng :before/:after viền đen.
   Tắt hẳn lớp vẽ đó và trả về control gốc, để radio và checkbox cùng một
   hình dáng + cùng màu accent. */
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup .m-neuron-form__option input[type="radio"]:before,
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup .m-neuron-form__option input[type="radio"]:after {
	content: none;
	display: none;
}

.elementor-widget-neuron-form.mol-form .m-neuron-form__option input[type="checkbox"],
.elementor-widget-neuron-form.mol-form .m-neuron-form__subgroup .m-neuron-form__option input[type="radio"] {
	width: 17px;
	height: 17px;
	min-height: 0;
	margin: 0 9px 0 0;
	padding: 0;
	visibility: visible;
	position: static;
	accent-color: var(--mol-accent);
	flex: none;
	cursor: pointer;
}

/* Ô nhập: .h-neuron-size--md của plugin ép min-height 48px + padding 6px 16px,
   đẩy chữ thụt vào giữa vạch dưới. Trả về padding của mục 10.2. */
.elementor-widget-neuron-form.mol-form .m-neuron-form__field,
.elementor-widget-neuron-form.mol-form input.m-neuron-form__field,
.elementor-widget-neuron-form.mol-form textarea.m-neuron-form__field {
	min-height: 0;
	padding: 12px 2px;
	border: 0;
	border-bottom: 1px solid var(--mol-border);
	border-radius: 0;
	background: transparent;
	font-family: var(--mol-font-body);
	font-size: 16px;
	line-height: 1.6;
	color: var(--mol-ink);
}

.elementor-widget-neuron-form.mol-form textarea.m-neuron-form__field {
	min-height: 120px;
	line-height: 1.7;
	resize: vertical;
}

/* Label trường: post-5864.css gán font Kit + padding-bottom 0 */
.elementor-widget-neuron-form.mol-form .m-neuron-form__field-group > label.m-neuron-form__label {
	font-family: var(--mol-font-body);
	font-size: 14px;
	font-weight: 500;
	letter-spacing: 0.02em;
	line-height: 1.5;
	color: var(--mol-ink);
	margin-bottom: 10px;
	padding-bottom: 0;
	display: block;
}

/* Dấu * — plugin hard-code color:red ở luật (0,3,0), phải khai đủ nặng */
.elementor-widget-neuron-form.mol-form .m-neuron-form__field-group--required.m-neuron-form__field-group--mark-required > label:after {
	color: var(--mol-accent);
}

/* ============================================================
   10.8 — FAQ accordion (widget nested-accordion, trang The Experience)
   ------------------------------------------------------------
   Triệu chứng: phần TRẢ LỜI bị bọc một khung xám 4 cạnh, màu #d5d8dc —
   không khớp vạch #E5DFD6 dùng khắp trang.

   Vì sao setting của widget không chữa được: ô "Border" trong panel widget
   chỉ sinh luật cho SUMMARY (`> .e-n-accordion-item-title`), xem
   `post-5861.css`. Còn khung quanh nội dung do luật mặc định của Elementor vẽ:

     :where(.elementor-widget-n-accordion .e-n-accordion-item > .e-con) {
       border: var(--n-accordion-border-width) var(--n-accordion-border-style)
               var(--n-accordion-border-color);
     }

   với default `1px solid #d5d8dc` khai trên `.elementor-widget-n-accordion`.
   Tức chỉnh trong Elementor bao nhiêu cũng không tới được panel này.

   Sửa ở gốc — đặt lại biến trên widget thay vì ghi đè `border`, để nếu sau
   này có bật viền thật thì chỉ cần đổi màu một chỗ.

   Lưu ý specificity: biến mặc định khai ở `.elementor-widget-n-accordion`
   (0,1,0) trong `widget-nested-accordion.min.css` — file này nạp SAU
   style.css, nên viết đúng một class là HÒA rồi thua. Lặp class để lên
   (0,2,0). (Luật `:where(...)` dùng biến thì specificity 0, không phải vấn đề.) */
.elementor-widget-n-accordion.elementor-widget-n-accordion {
	--n-accordion-border-width: 0;
	--n-accordion-border-color: var(--mol-border);
}

/* Vạch ngăn giữa các câu hỏi vẫn phải còn — biến ở trên đã tắt cả viền của
   summary, nên trả lại đúng một vạch dưới.
   Đối thủ ở đây là post-5861.css (0,4,0: `.elementor-5861 .elementor-element...
   > .e-n-accordion > .e-n-accordion-item > .e-n-accordion-item-title`), nên
   cần đủ nặng mới đổi được. */
.elementor-widget-n-accordion.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item > .e-n-accordion-item-title {
	border-width: 0 0 1px 0;
	border-style: solid;
	border-color: var(--mol-border);
}

/* Khi một mục đang MỞ, vạch phải chạy dưới câu trả lời chứ không nằm giữa
   câu hỏi và câu trả lời — nếu không, vạch cắt đôi đúng cặp Q&A mà nó lẽ ra
   phải gom lại. Chuyển vạch từ summary xuống chính <details>. */
.elementor-widget-n-accordion.elementor-widget-n-accordion .e-n-accordion.e-n-accordion .e-n-accordion-item[open] > .e-n-accordion-item-title {
	border-bottom-color: transparent;
}

.elementor-widget-n-accordion.elementor-widget-n-accordion .e-n-accordion .e-n-accordion-item[open] {
	border-bottom: 1px solid var(--mol-border);
}

/* ============================================================
   10.9 — Vá hai font "ma" còn sót của theme cha Captura
   ------------------------------------------------------------
   Theme cha khai hai họ font mà TRANG KHÔNG HỀ NẠP:

     - `"Cormorant"` (KHÁC `Cormorant Garamond`) cho h1/h3/h4/h6 và logo
       `.n-site-branding a`.
     - `"Author"` cho ô tìm kiếm và một số control.

   Kiểm bằng `document.fonts`: chỉ có @font-face cho Cormorant Garamond,
   Inter, Montserrat — không có Cormorant thuần, không có Author.

   Vì sao dễ bỏ lọt: máy dev đã cài sẵn họ Cormorant nên logo trông vẫn đẹp,
   trong khi khách không có font sẽ rơi về serif hệ thống (Times) — lệch hẳn
   với H1 Cormorant Garamond ngay bên dưới. Lỗi chỉ lộ trên máy người khác.

   Mục 2 (h1–h4) đã phủ headings rồi; ở đây vá nốt hai chỗ còn sót. */
.n-site-branding a,
.site-title a,
.site-title {
	font-family: var(--mol-font-display);
}

/* `Author` không tồn tại → rơi về Helvetica, lệch với Inter của cả trang.
   Đối thủ là `.n-site-search__overlay form input` (0,2,1) trong theme cha,
   nên `input[type=search]` (0,1,1) không đủ. */
.n-site-search__overlay form input,
.n-site-searchform input,
input[type="search"],
.search-field {
	font-family: var(--mol-font-body);
}

/* ============================================================
   11 — Journal: kéo typography về hệ thống của site
   ------------------------------------------------------------
   Journal là trang duy nhất chưa qua pass typography, nên vẫn còn nguyên
   số đo mặc định của theme cha Captura. Đo bằng CDP
   `CSS.getPlatformFontsForNode` (font THẬT vẽ glyph, không phải font khai)
   trên /journal/ + 2 bài đơn, đối chiếu Home & Our Philosophy.
   ============================================================ */

/* 11.1 — H1 bài đơn: 2.8rem (=28px) là mặc định theme cha
   (captura/style.css:4680). Cỡ đó khiến TIÊU ĐỀ BÀI nhỏ ngang H3 của card
   story ở Home (28px) — sai thứ bậc, bài viết trông như một card.
   Hero các trang khác: Home 76px/300, Philosophy 64px/300. Chọn 48px/300:
   thấp hơn hero landing (bài đọc không cần hét to) nhưng giữ đúng ngôn ngữ
   weight 300 + uppercase của hệ thống. */
.n-blog-archive--single .n-blog-archive__title {
	font-size: 48px;
	font-weight: 300;
	line-height: 1.15;
}

@media (max-width: 1024px) {
	.n-blog-archive--single .n-blog-archive__title {
		font-size: 38px;
	}
}

@media (max-width: 767px) {
	.n-blog-archive--single .n-blog-archive__title {
		font-size: 30px;
	}
}

/* 11.2 — Title trên trang danh sách: theme cha để 22px
   (captura/style.css:1724). Card Journal và card story ở Home là cùng một
   loại thành phần (ảnh + tiêu đề + mô tả) nên phải cùng cỡ chữ — H3 card
   Home là 28px/400. */
.n-blog-archive__title,
.n-blog-archive__title a {
	font-size: 28px;
	line-height: 1.3;
}

@media (max-width: 767px) {
	.n-blog-archive__title,
	.n-blog-archive__title a {
		font-size: 24px;
	}
}

/* 11.3 — Tiêu đề sidebar ("Recent Posts", "Categories") khai font `"Author"`
   ở captura/style.css:4367 — họ font site KHÔNG nạp, nên rơi về Times hệ
   thống. Cùng lỗi font "ma" đã vá ở 10.9, chỗ này còn sót vì selector khác.
   Chúng là tiêu đề khối → thuộc nhóm display như mọi heading khác.

   Luật cha có `font-size: 22px !important` nên phải `!important` mới đấu
   được cỡ chữ; selector nhân đôi class để vượt (0,1,1) của cha. */
.m-ntheme-widget.m-ntheme-widget h2,
.m-ntheme-widget.m-ntheme-widget h5,
.m-ntheme-widget.m-ntheme-widget .m-ntheme-widget__title,
.m-ntheme-widget.m-ntheme-widget .wp-block-search__label {
	font-family: var(--mol-font-display);
	font-size: 26px !important;
	line-height: 1.3;
}

/* 11.4 — Thân bài Journal: kéo về đúng nhịp đọc của site
   ------------------------------------------------------------
   Đo bằng CDP trên /journal/ + bài đơn, đối chiếu Home & Our Philosophy
   (2026-08-25). Ba số đo lệch, đều do theme cha:

     đoạn thân   trang chuẩn        Journal (theme cha)
     màu         #6B6560 xám ấm     #1A1815 mực đen
     cỡ / dòng   17px / 1.75        18px / 1.5
     bề rộng     470–620px          900px (bài đơn không giới hạn)

   Thủ phạm cỡ chữ là `.n-blog-archive p { font-size: 18px !important;
   line-height: 1.5em }` (captura/style.css:1512) — có `!important` nên
   phải `!important` mới đấu lại.

   Màu: thân bài dùng `--mol-ink-soft` như mọi trang khác, KHÔNG phải
   `--mol-ink`. Mực đen để dành cho tiêu đề; dùng cho cả đoạn văn dài thì
   trang đọc gắt hẳn lên so với phần còn lại của site. */
.n-blog-archive p,
.n-blog-archive__excerpt p,
.n-blog-archive__content p {
	color: var(--mol-ink-soft);
	font-size: 17px !important;
	line-height: 1.75;
}

/* Bề rộng cột bài đơn. Theme cha không chặn bề rộng nên đoạn văn kéo hết
   900px. Site dùng HAI cấp cột, đo 2026-08-25: đoạn dẫn rộng (Philosophy
   860px, Experience 820px) và đoạn phụ hẹp (448–470px). Thân bài Journal
   thuộc cấp rộng — 820px, khớp The Experience. */
.n-blog-archive--single .n-blog-archive__content {
	max-width: 820px;
	margin-left: auto;
	margin-right: auto;
}

/* 11.5 — Sidebar Journal: kéo màu + nhịp dòng về token của site
   ------------------------------------------------------------
   Sidebar dựng bằng block WordPress (Search / Latest Posts / Categories),
   không qua Elementor nên giữ nguyên mặc định của block: chữ đen TUYỆT ĐỐI
   `rgb(0,0,0)` — không phải token nào của site (mực đen là #1A1815).
   Đen thuần cạnh nền ivory ấm #FAF8F4 tạo tương phản gắt hơn phần còn lại.

   Link cũng đang đen, trong khi luật nền (mục 2) đã đặt link màu đồng.
   Block ghi đè bằng selector riêng nên phải chỉ đích danh. Kèm `:visited`:
   không có nó thì bài đã đọc rơi về đen, hai link cạnh nhau lệch màu. */
.n-blog-archive__sidebar h2,
.n-blog-archive__sidebar h5,
.n-blog-archive__sidebar .wp-block-search__label {
	color: var(--mol-ink);
}

.n-blog-archive__sidebar a,
.n-blog-archive__sidebar a:visited {
	color: var(--mol-accent);
}

.n-blog-archive__sidebar a:hover,
.n-blog-archive__sidebar a:focus {
	color: var(--mol-accent-dark);
}

/* Link sidebar 17px/24px = 1.41, chật hơn nhịp 1.75 của site. Đây là danh
   sách link ngắn chứ không phải văn xuôi nên không cần trọn 1.75; 1.6 đủ
   thoáng mà vẫn gom mỗi mục thành một khối đọc được. */
.n-blog-archive__sidebar li,
.n-blog-archive__sidebar a {
	line-height: 1.6;
}
