:root {
	--pt-bg: #faf9f6;
	--pt-surface: #ffffff;
	--pt-surface-soft: #f5f3ef;
	--pt-gold: #c6a66a;
	--pt-gold-dark: #8a6a37;
	--pt-beige: #e8ded0;
	--pt-text: #25282b;
	--pt-text-soft: #5c6064;
	--pt-navy: #273a4a;
	--pt-border: #e5e7e8;
	--pt-success: #36745b;
}

body.ptl-runtime {
	margin: 0;
	background: var(--pt-bg);
	color: var(--pt-text);
	font-family: 'Be Vietnam Pro', 'Segoe UI', Roboto, system-ui, -apple-system, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

.ptl-runtime a {
	color: inherit;
}

.ptl-shell {
	width: min(1400px, calc(100% - 36px));
	margin: 0 auto;
}

.ptl-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: rgba(255, 255, 255, .94);
	border-bottom: 1px solid var(--pt-border);
	backdrop-filter: blur(14px);
}

.ptl-header__inner {
	display: grid;
	grid-template-columns: auto 1fr auto;
	gap: 22px;
	align-items: center;
	min-height: 74px;
}

.ptl-brand {
	display: inline-flex;
	gap: 12px;
	align-items: center;
	text-decoration: none;
}

.ptl-brand__mark {
	display: grid;
	place-items: center;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: var(--pt-navy);
	color: #fff;
	font-weight: 800;
}

.ptl-brand strong,
.ptl-brand small {
	display: block;
	letter-spacing: 0;
}

.ptl-brand small {
	color: var(--pt-text-soft);
	font-size: 12px;
}

.ptl-brand__logo {
	display: block;
	height: 54px;
	width: auto;
}

.ptl-brand small.ptl-brand__tagline {
	display: none;
}

@media (min-width: 700px) {
	.ptl-brand small.ptl-brand__tagline {
		display: block;
	}
}

.ptl-menu {
	display: flex;
	gap: 18px;
	justify-content: center;
	align-items: center;
	margin: 0;
	padding: 0;
	list-style: none;
	font-size: 14px;
}

.ptl-menu a,
.ptl-header-cta,
.ptl-button,
.ptl-search button,
.ptl-filter button,
.ptl-lead-form button {
	text-decoration: none;
}

.ptl-header-cta,
.ptl-button,
.ptl-search button,
.ptl-filter button,
.ptl-lead-form button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-height: 44px;
	padding: 0 20px;
	border: 0;
	border-radius: 8px;
	background: var(--pt-gold-dark);
	color: #fff;
	font-weight: 700;
	text-align: center;
	overflow-wrap: anywhere;
}

.ptl-button--ghost {
	background: transparent;
	color: var(--pt-navy);
	border: 1px solid var(--pt-border);
}

.ptl-hamburger {
	display: none;
}

.ptl-site h1,
.ptl-site h2,
.ptl-site h3,
.ptl-footer h2,
.ptl-footer h3 {
	margin-top: 0;
	font-family: 'Be Vietnam Pro', 'Segoe UI', Roboto, system-ui, -apple-system, Arial, sans-serif;
	font-weight: 700;
	letter-spacing: -.01em;
	text-wrap: balance;
	color: var(--pt-text);
}

.ptl-hero {
	padding: 86px 0 70px;
	background: linear-gradient(135deg, #faf9f6 0%, #ffffff 48%, #f0ece4 100%);
}

.ptl-hero__grid,
.ptl-two-col,
.ptl-single-grid,
.ptl-single-content {
	display: grid;
	grid-template-columns: minmax(0, 1fr) minmax(320px, .72fr);
	gap: 44px;
	align-items: center;
}

.ptl-eyebrow {
	margin: 0 0 10px;
	color: var(--pt-gold-dark);
	font-size: 12.5px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: .02em;
}

.ptl-hero h1,
.ptl-archive-hero h1,
.ptl-single-hero h1 {
	max-width: 900px;
	margin: 0;
	font-size: clamp(40px, 5.6vw, 78px);
	line-height: 1.04;
}

.ptl-lead,
.ptl-archive-hero p,
.ptl-profile-card p,
.ptl-empty p,
.ptl-footer p,
.ptl-muted {
	color: var(--pt-text-soft);
	line-height: 1.7;
}

.ptl-lead {
	max-width: 720px;
	font-size: 20px;
}

.ptl-actions {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
	margin-top: 26px;
}

.ptl-profile-card,
.ptl-empty,
.ptl-sticky-box,
.ptl-room-card,
.ptl-value-list div,
.ptl-steps li {
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: var(--pt-surface);
	box-shadow: 0 14px 38px rgba(39, 58, 74, .08);
}

.ptl-profile-card {
	padding: 24px;
}

.ptl-photo-placeholder,
.ptl-room-placeholder,
.ptl-room-card__media {
	display: grid;
	place-items: center;
	min-height: 260px;
	border: 1px dashed var(--pt-gold);
	border-radius: 8px;
	background: var(--pt-surface-soft);
	color: var(--pt-gold-dark);
	text-align: center;
	font-weight: 800;
}

.ptl-profile-card ul {
	margin: 16px 0 0;
	padding-left: 18px;
	color: var(--pt-text-soft);
	line-height: 1.7;
}

.ptl-section {
	padding: 64px 0;
}

.ptl-section--raised {
	margin-top: -26px;
	padding-top: 0;
}

.ptl-section--soft,
.ptl-archive-hero,
.ptl-single-hero {
	background: var(--pt-surface-soft);
}

.ptl-section-head {
	display: flex;
	gap: 20px;
	justify-content: space-between;
	align-items: end;
	margin-bottom: 24px;
}

.ptl-section-head h2,
.ptl-two-col h2,
.ptl-cta h2 {
	margin: 0;
	font-size: clamp(30px, 3vw, 48px);
	line-height: 1.16;
}

.ptl-search,
.ptl-filter {
	display: grid;
	grid-template-columns: 1.2fr .8fr .8fr .8fr auto;
	gap: 12px;
	padding: 16px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: rgba(255, 255, 255, .96);
	box-shadow: 0 18px 48px rgba(39, 58, 74, .12);
}

.ptl-filter {
	grid-template-columns: repeat(6, minmax(140px, 1fr));
	margin-bottom: 24px;
}

.ptl-search label,
.ptl-filter label {
	display: grid;
	gap: 6px;
	font-size: 13px;
	color: var(--pt-text-soft);
}

.ptl-filter__checks {
	display: grid;
	grid-template-columns: repeat(2, minmax(0, 1fr));
	gap: 8px 12px;
	align-content: end;
}

.ptl-search input,
.ptl-search select,
.ptl-filter input,
.ptl-filter select,
.ptl-lead-form input,
.ptl-lead-form textarea {
	width: 100%;
	min-height: 44px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
	color: var(--pt-text);
}

.ptl-card-grid,
.ptl-value-list,
.ptl-steps {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 18px;
}

.ptl-empty {
	padding: 28px;
}

.ptl-room-card {
	overflow: hidden;
}

.ptl-room-card--da-thue {
	opacity: .78;
}

.ptl-room-card__media {
	min-height: 220px;
	text-decoration: none;
	border-radius: 0;
	border-width: 0 0 1px;
}

.ptl-room-card__media img,
.ptl-room-placeholder img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	display: block;
}

.ptl-room-card__body,
.ptl-value-list div,
.ptl-steps li,
.ptl-sticky-box {
	padding: 22px;
}

.ptl-card-meta {
	margin: 0 0 8px;
	color: var(--pt-text-soft);
	font-size: 13px;
	font-weight: 400;
}

.ptl-badge-row {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 10px;
}

.ptl-status,
.ptl-featured,
.ptl-demo {
	display: inline-flex;
	align-items: center;
	min-height: 26px;
	padding: 5px 9px;
	border-radius: 999px;
	font-size: 12px;
	font-weight: 800;
	line-height: 1;
}

.ptl-status {
	background: #eff7f1;
	color: #22603d;
}

.ptl-featured {
	background: #fff6dc;
	color: var(--pt-gold-dark);
}

.ptl-demo {
	background: #eef2f5;
	color: var(--pt-text);
}

.ptl-room-card h3 {
	margin-bottom: 10px;
	font-size: 19px;
	line-height: 1.3;
}

.ptl-room-card a {
	text-decoration: none;
}

.ptl-room-card strong {
	display: block;
	margin-bottom: 8px;
	color: var(--pt-success);
	font-size: 18px;
}

.ptl-room-card__body > span {
	color: var(--pt-text-soft);
	font-size: 13px;
}

.ptl-steps {
	margin: 0;
	padding: 0;
	list-style: none;
	counter-reset: steps;
}

.ptl-steps li {
	counter-increment: steps;
	position: relative;
}

.ptl-steps li::before {
	content: counter(steps);
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	margin-bottom: 14px;
	border-radius: 50%;
	background: var(--pt-navy);
	color: #fff;
	font-weight: 800;
}

/* Process directional flow (Homepage Visual/UX Polish Gate): a connector
   line through the existing numbered circles - horizontal between columns
   on desktop, vertical between stacked steps once .ptl-steps wraps to 1
   column at the existing 980px breakpoint. CSS-only, no new markup. */
.ptl-steps li:not(:last-child)::after {
	content: "";
	position: absolute;
	top: 39px;
	right: -18px;
	width: 18px;
	height: 3px;
	background: rgba(111, 115, 119, .4);
}

@media (max-width: 980px) {
	.ptl-steps li:not(:last-child)::after {
		top: auto;
		right: auto;
		left: 39px;
		bottom: -18px;
		width: 2px;
		height: 18px;
	}
}

.ptl-cta {
	padding: 66px 0;
	background: var(--pt-navy);
	color: #fff;
}

/* Lead conversion form should read as the focal point of this section, not
   an equal-width afterthought next to the message - flips the shared
   .ptl-two-col ratio (message-heavier by default) to form-heavier here
   only (~44/56). Scoped to .ptl-cta, which is homepage-only - the Contact
   page's own lead form uses plain .ptl-two-col without this class. */
.ptl-cta .ptl-two-col {
	grid-template-columns: .8fr 1fr;
}

.ptl-cta h2,
.ptl-cta p,
.ptl-footer h2,
.ptl-footer h3 {
	color: #fff;
}

.ptl-lead-form {
	display: grid;
	gap: 18px;
}

.ptl-lead-form__group {
	display: grid;
	gap: 12px;
	padding: 16px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: var(--pt-surface-soft);
}

.ptl-cta .ptl-lead-form__group {
	border-color: rgba(255, 255, 255, .14);
	background: rgba(255, 255, 255, .04);
}

.ptl-lead-form__group-title {
	margin: 0;
	color: inherit;
	opacity: .65;
	font-size: 12px;
	font-weight: 800;
	text-transform: uppercase;
	letter-spacing: .04em;
}

.ptl-lead-form label {
	display: grid;
	gap: 6px;
	font-size: 13px;
}

.ptl-check {
	display: flex !important;
	grid-template-columns: none !important;
	align-items: center;
	gap: 8px !important;
	color: var(--pt-text);
}

.ptl-check input {
	width: auto;
	min-height: 0;
}

.ptl-hp {
	position: absolute;
	left: -9999px;
	width: 1px;
	height: 1px;
	overflow: hidden;
}

.ptl-form-message {
	padding: 12px 14px;
	border-radius: 8px;
	font-weight: 800;
}

.ptl-form-message--success {
	background: #eaf7ee;
	color: #23623d;
}

.ptl-form-message--error {
	background: #fff0f0;
	color: #9c2020;
}

.ptl-breadcrumb {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin-bottom: 14px;
	font-size: 13px;
	font-weight: 800;
}

.ptl-breadcrumb a {
	color: var(--pt-gold-dark);
	text-decoration: none;
}

.ptl-archive-hero,
.ptl-single-hero {
	padding: 60px 0;
}

.ptl-facts,
.ptl-amenities {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 22px;
}

.ptl-fact,
.ptl-amenities span {
	padding: 10px 12px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
}

.ptl-fact span {
	display: block;
	color: var(--pt-text-soft);
	font-size: 12px;
}

/* Single Room Visual + Conversion Polish Gate: price is the strongest
   signal on the page, so it gets its own large display line instead of
   sitting as one dashboard tile among seven equal-weight ones. The
   remaining facts move to a lighter, secondary style (.ptl-facts--secondary
   below) and the room code becomes a quiet tertiary line - same
   information, clearer hierarchy, no data removed. */
.ptl-single-price {
	margin: 18px 0 0;
	font-size: clamp(26px, 2.6vw, 34px);
	font-weight: 800;
	color: var(--pt-navy);
}

.ptl-facts--secondary {
	margin-top: 12px;
	gap: 8px 20px;
}

.ptl-facts--secondary .ptl-fact {
	padding: 0;
	border: 0;
	border-radius: 0;
	background: none;
}

.ptl-facts--secondary .ptl-fact span {
	font-size: 11px;
	text-transform: uppercase;
	letter-spacing: .03em;
}

.ptl-facts--secondary .ptl-fact strong {
	font-size: 14px;
	font-weight: 600;
	color: var(--pt-text);
}

.ptl-single-room-code {
	margin: 10px 0 0;
	color: var(--pt-text-soft);
	font-size: 12px;
}

.ptl-single-cta-row {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin-top: 22px;
}

/* Comfortable reading line-length for the room description prose - no
   content change, presentation only. */
.ptl-single-description {
	max-width: 640px;
}

.ptl-single-description p {
	margin: 0 0 16px;
	line-height: 1.75;
}

.ptl-single-description p:last-child {
	margin-bottom: 0;
}

/* Sticky sidebar's own price/status header - the sidebar acts as an
   independent "sticky conversion card" once the user scrolls past the
   description, so it repeats price/status/CTA rather than assuming the
   Hero's copy is still in view. */
.ptl-sticky-box__price {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin-bottom: 6px;
}

.ptl-sticky-box__price strong {
	font-size: 22px;
	font-weight: 800;
	color: var(--pt-navy);
}

.ptl-sticky-box h2 {
	margin-top: 22px;
}

.ptl-faq details {
	margin-bottom: 10px;
	padding: 18px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
}

.ptl-faq summary {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	cursor: pointer;
	list-style: none;
	font-weight: 700;
	color: var(--pt-text);
}

.ptl-faq summary::-webkit-details-marker {
	display: none;
}

.ptl-faq summary::after {
	content: "+";
	flex: 0 0 auto;
	font-size: 20px;
	font-weight: 400;
	color: var(--pt-gold-dark);
	transition: transform .15s ease;
}

.ptl-faq details[open] summary::after {
	transform: rotate(45deg);
}

.ptl-faq details p {
	margin: 12px 0 0;
	color: var(--pt-text-soft);
	line-height: 1.6;
}

.ptl-mobile-cta {
	display: none;
}

.ptl-footer {
	padding: 48px 0 24px;
	background: #1f2f3c;
	color: #fff;
}

.ptl-footer__grid {
	display: grid;
	grid-template-columns: 1.2fr repeat(3, minmax(160px, .6fr));
	gap: 28px;
}

/* .ptl-footer p inherits --pt-text-soft from the shared muted-text rule
   earlier in this file, which is tuned for light backgrounds (contrast
   fails badly against this section's dark navy background) - lighten it
   here specifically instead of changing --pt-text-soft's light-background
   value used everywhere else. */
.ptl-footer p {
	color: #a7b0b8;
}

.ptl-footer a {
	display: block;
	margin: 10px 0;
	color: rgba(255, 255, 255, .82);
	text-decoration: none;
}

.ptl-footer__bottom {
	display: flex;
	justify-content: space-between;
	gap: 18px;
	margin-top: 28px;
	padding-top: 18px;
	border-top: 1px solid rgba(255, 255, 255, .16);
	color: rgba(255, 255, 255, .72);
	font-size: 13px;
}

@media (max-width: 980px) {
	.ptl-header__inner,
	.ptl-hero__grid,
	.ptl-two-col,
	.ptl-single-grid,
	.ptl-single-content,
	.ptl-footer__grid {
		grid-template-columns: 1fr;
	}

	.ptl-header__inner {
		display: flex;
		justify-content: space-between;
	}

	.ptl-hamburger {
		display: grid;
		gap: 5px;
		width: 42px;
		padding: 10px;
		cursor: pointer;
		border: 0;
		background: none;
		appearance: none;
	}

	.ptl-hamburger span {
		display: block;
		height: 2px;
		background: var(--pt-text);
	}

	.ptl-nav,
	.ptl-header-cta {
		display: none;
	}

	.ptl-hamburger[aria-expanded="true"] ~ .ptl-nav,
	.ptl-hamburger[aria-expanded="true"] ~ .ptl-header-cta {
		display: block;
		position: absolute;
		left: 18px;
		right: 18px;
		top: 74px;
		padding: 18px;
		border: 1px solid var(--pt-border);
		border-radius: 8px;
		background: #fff;
		box-shadow: 0 16px 38px rgba(39, 58, 74, .16);
	}

	.ptl-hamburger[aria-expanded="true"] ~ .ptl-header-cta {
		top: auto;
		margin-top: 330px;
		text-align: center;
	}

	.ptl-menu {
		display: grid;
		justify-content: start;
	}

	.ptl-search,
	.ptl-filter,
	.ptl-card-grid,
	.ptl-value-list,
	.ptl-steps {
		grid-template-columns: 1fr;
	}

	.ptl-section-head,
	.ptl-footer__bottom {
		display: grid;
	}

	.ptl-mobile-cta {
		display: block;
		position: sticky;
		bottom: 0;
		z-index: 60;
		padding: 10px 18px;
		background: #fff;
		border-top: 1px solid var(--pt-border);
	}

	/* The floating bar above already puts a contact CTA within reach at all
	   times on mobile - the Hero/sidebar CTA rows would just be a 2nd and
	   3rd copy of the same action stacked on the page. */
	.ptl-single-cta-row {
		display: none;
	}

	.ptl-mobile-cta a {
		display: flex;
		justify-content: center;
		align-items: center;
		padding: 13px;
		border-radius: 8px;
		background: var(--pt-gold-dark);
		color: #fff;
		text-decoration: none;
		font-weight: 800;
		line-height: 1.25;
	}
}

@media (max-width: 520px) {
	.ptl-shell {
		width: min(100% - 24px, 1400px);
	}

	.ptl-hero {
		padding: 48px 0;
	}

	.ptl-hero h1,
	.ptl-archive-hero h1,
	.ptl-single-hero h1 {
		font-size: 38px;
	}
}

.ptl-blog-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: 24px;
	margin-top: 8px;
}

.ptl-blog-card {
	overflow: hidden;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: var(--pt-surface);
	box-shadow: 0 14px 38px rgba(39, 58, 74, .08);
}

.ptl-blog-card__thumb {
	display: block;
	min-height: 190px;
	background: var(--pt-surface-soft);
}

.ptl-blog-card__thumb img {
	width: 100%;
	height: 190px;
	object-fit: cover;
	display: block;
}

.ptl-blog-card__body {
	padding: 20px;
}

.ptl-blog-card__body h2,
.ptl-blog-card__body h3 {
	margin: 0 0 10px;
	font-size: 19px;
	line-height: 1.35;
}

.ptl-blog-card__body h2 a,
.ptl-blog-card__body h3 a {
	text-decoration: none;
	color: var(--pt-text);
}

.ptl-blog-card__body p {
	margin: 0 0 14px;
	color: var(--pt-text-soft);
	line-height: 1.6;
}

@media (max-width: 900px) {
	.ptl-blog-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 620px) {
	.ptl-blog-grid {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   Phase 5 — Homepage above-the-fold rebuild (Hero image, trust chips, search
   overlap, relocated profile card). Appended rather than edited in place so
   the diff stays reviewable and nothing above this line changed.

   NOTE on --pt-* tokens declared at the top of this file: this is the
   CURRENT UI COLOR SYSTEM, reused here as-is. Status: temporary until the
   official Phương Trinh Lighthouse ADN (palette/typography/visual identity)
   is confirmed - not treated as a final brand palette.

   .ptl-hero__grid is redeclared below instead of edited at its original
   definition, because that definition is SHARED with .ptl-two-col /
   .ptl-single-grid / .ptl-single-content (used on other templates) - editing
   it in place would leak Hero-only layout changes into those.
   ========================================================================== */

.ptl-hero__grid {
	grid-template-columns: 1.05fr .95fr;
	gap: 48px;
}

.ptl-hero--no-image .ptl-hero__grid {
	grid-template-columns: 1fr;
}

.ptl-hero--no-image .ptl-hero__content {
	max-width: 960px;
	margin: 0 auto;
	text-align: center;
}

.ptl-hero--no-image .ptl-hero__content .ptl-actions,
.ptl-hero--no-image .ptl-hero__content .ptl-trust {
	justify-content: center;
}

.ptl-hero--no-image .ptl-hero__content h1,
.ptl-hero--no-image .ptl-hero__content .ptl-lead {
	max-width: none;
	margin-left: auto;
	margin-right: auto;
}

.ptl-hero__content h1 {
	max-width: 600px;
	font-size: clamp(40px, 4.2vw, 60px);
	line-height: 1.1;
}

.ptl-hero__content .ptl-lead {
	max-width: 560px;
	font-size: 17px;
	line-height: 1.6;
}

.ptl-hero {
	padding: 68px 0 56px;
}

.ptl-hero__media {
	border-radius: 16px;
	overflow: hidden;
	box-shadow: 0 24px 60px rgba(39, 58, 74, .16);
}

.ptl-hero__media picture,
.ptl-hero__media img {
	display: block;
	width: 100%;
}

.ptl-hero__media img {
	aspect-ratio: 4 / 3;
	object-fit: cover;
}

.ptl-trust {
	display: flex;
	flex-wrap: wrap;
	gap: 10px 20px;
	margin: 22px 0 0;
	padding: 0;
	list-style: none;
}

.ptl-trust li {
	position: relative;
	padding-left: 18px;
	color: var(--pt-text-soft);
	font-size: 14px;
}

.ptl-trust li::before {
	content: "";
	position: absolute;
	left: 0;
	top: 7px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--pt-success);
}

.ptl-home-search {
	position: relative;
	z-index: 5;
	margin-top: -34px;
	padding: 0 0 56px;
}

.ptl-home-search .ptl-search {
	box-shadow: 0 20px 50px rgba(39, 58, 74, .14);
}

.ptl-section--why .ptl-profile-card {
	margin: 0;
}

/* Real photo (added once the business supplied one - was a dashed-border
   text placeholder before). Fixed height + object-fit:cover keeps the
   card's proportions the same regardless of the source photo's own
   aspect ratio. Height raised from an earlier 220px and object-position
   biased toward the top: the source is a tall portrait shot (trophy held
   up, then face, then certificate lower down), and the original short
   220px letterbox crop was centering on the vertical middle, which cut
   the trophy out of frame entirely. */
.ptl-profile-card__photo {
	display: block;
	width: 100%;
	height: 360px;
	object-fit: cover;
	object-position: center 26%;
	border-radius: 8px;
	margin-bottom: 16px;
}

.ptl-section--why .ptl-value-list {
	margin-top: 20px;
}

/* ==========================================================================
   Room Archive UX Correction Gate. Archive is a task page, not a marketing
   Hero - scoped via [data-ptl-template="archive-phong"] so Homepage/Single
   Room (which share .ptl-archive-hero's H1 rule and .ptl-room-card) are
   untouched.
   ========================================================================== */

[data-ptl-template="archive-phong"] .ptl-archive-hero h1 {
	font-size: clamp(32px, 3.4vw, 46px);
	line-height: 1.15;
}

[data-ptl-template="archive-phong"] .ptl-archive-hero p:not(.ptl-eyebrow) {
	font-size: 15px;
	max-width: 640px;
}

[data-ptl-template="archive-phong"] .ptl-archive-hero {
	padding: 48px 0;
}

/* ==========================================================================
   LAUNCH-A — Single Room Visual Acceptance. Scoped via
   [data-ptl-template="single-phong"] so Homepage/Archive (which share
   .ptl-single-hero's H1 rule and .ptl-room-card) are untouched.
   ========================================================================== */

[data-ptl-template="single-phong"] .ptl-single-room h1 {
	font-size: clamp(30px, 3.4vw, 44px);
	line-height: 1.18;
}

/* Gallery main image was governing the whole Hero section's height (858px
   at 1366x768, pushing the contact/price sticky sidebar entirely below the
   fold - 0px visible in the first viewport, live-measured). object-fit:cover
   already guarantees no distortion regardless of container height. */
[data-ptl-template="single-phong"] .ptl-room-gallery__main {
	height: 360px;
}

[data-ptl-template="single-phong"] .ptl-section-head h2 {
	font-size: clamp(26px, 2.3vw, 33px);
}

.ptl-filter select,
.ptl-filter input {
	font-size: 14.5px;
}

.ptl-filter__checks-label {
	margin: 0 0 6px;
	font-size: 12.5px;
	font-weight: 700;
	color: var(--pt-text-soft);
}

.ptl-result-sort {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	margin-left: auto;
	font-size: 13px;
	color: var(--pt-text-soft);
}

.ptl-result-sort select {
	min-height: 36px;
	padding: 0 8px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
	color: var(--pt-text);
	font-size: 13.5px;
}

/* Archive is a browse page, not a homepage showcase - trim the Room Card's
   image height ~12% here only (object-fit:cover already guarantees no
   distortion regardless of container height, so this is safe without
   forking the shared card). Homepage/Related keep their existing height. */
[data-ptl-template="archive-phong"] .ptl-room-card__media {
	height: 280px;
}

/* Pagination previously had zero custom styling - native <a>/<span> text
   with no padding or tap-target sizing, current page visually identical to
   any other link. */
.ptl-pagination {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin-top: 8px;
}

.ptl-pagination .page-numbers {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 40px;
	min-height: 40px;
	padding: 0 12px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
	color: var(--pt-text);
	font-size: 14.5px;
	text-decoration: none;
}

.ptl-pagination .page-numbers.dots {
	min-width: auto;
	border-color: transparent;
	background: transparent;
	padding: 0 4px;
}

.ptl-pagination .page-numbers.current {
	border-color: var(--pt-navy);
	background: var(--pt-navy);
	color: #fff;
	font-weight: 700;
}

.ptl-pagination a.page-numbers:hover,
.ptl-pagination a.page-numbers:focus-visible {
	border-color: var(--pt-gold);
}

.ptl-pagination .page-numbers.prev,
.ptl-pagination .page-numbers.next {
	padding: 0 16px;
	font-weight: 700;
}

/* Homepage-only H2 visual tiering (Homepage Final Visual Polish V2): same
   semantic <h2> everywhere, three subtle size tiers so Featured Rooms reads
   strongest, Area/Intent are a step lighter, and Why/Process/Articles are
   the lightest - without touching the shared .ptl-section-head/.ptl-two-col
   h2 rule that Lead (.ptl-cta) also relies on for its own prominence. */
[data-ptl-template="front-page"] .ptl-home-featured .ptl-section-head h2 {
	font-size: clamp(28px, 2.6vw, 36px);
}

[data-ptl-template="front-page"] #pt-khu-vuc .ptl-section-head h2,
[data-ptl-template="front-page"] #pt-nhu-cau .ptl-section-head h2 {
	font-size: clamp(26px, 2.3vw, 33px);
}

[data-ptl-template="front-page"] .ptl-section--why h2,
[data-ptl-template="front-page"] .ptl-section--process .ptl-section-head h2,
[data-ptl-template="front-page"] .ptl-home-articles .ptl-section-head h2 {
	font-size: clamp(24px, 2vw, 30px);
}

/* Homepage-only section rhythm - scoped via the front-page template wrapper
   (data-ptl-template, already set in front-page.php) rather than editing the
   shared .ptl-section rule directly, since that class is also used sitewide
   on Archive/Single/Contact pages (out of scope for this polish gate). */
[data-ptl-template="front-page"] .ptl-section {
	padding: 80px 0;
}

@media (max-width: 980px) {
	[data-ptl-template="front-page"] .ptl-section {
		padding: 64px 0;
	}
}

@media (max-width: 520px) {
	[data-ptl-template="front-page"] .ptl-section {
		padding: 52px 0;
	}
}

/* Tighten only the Area->Intent, Intent->Why, Why->Process transitions
   (~10% off the combined gap) - Hero/Search and Lead/Footer spacing is
   intentionally left untouched per the polish gate's explicit instruction. */
[data-ptl-template="front-page"] #pt-nhu-cau,
[data-ptl-template="front-page"] .ptl-section--why,
[data-ptl-template="front-page"] .ptl-section--process {
	padding-top: 64px;
}

@media (max-width: 980px) {
	[data-ptl-template="front-page"] #pt-nhu-cau,
	[data-ptl-template="front-page"] .ptl-section--why,
	[data-ptl-template="front-page"] .ptl-section--process {
		padding-top: 52px;
	}
}

@media (max-width: 520px) {
	[data-ptl-template="front-page"] #pt-nhu-cau,
	[data-ptl-template="front-page"] .ptl-section--why,
	[data-ptl-template="front-page"] .ptl-section--process {
		padding-top: 44px;
	}
}

/* Homepage Articles: .ptl-blog-card is shared with the /bai-viet/ blog index
   (home.php) - scope the thumbnail-height reduction to the homepage only so
   the blog index itself is untouched. */
[data-ptl-template="front-page"] .ptl-blog-card__thumb {
	min-height: 160px;
}

[data-ptl-template="front-page"] .ptl-blog-card__thumb img {
	height: 160px;
}

/* Mobile tap target for the hamburger: bump from ~42px toward the ~44px
   accessible minimum without changing its open/close mechanism. */
.ptl-hamburger {
	width: 44px;
	height: 44px;
	padding: 11px;
	box-sizing: border-box;
}

@media (max-width: 980px) {
	/* Re-assert stacking for the Hero-only grid override above - this rule
	   must come after the unconditional .ptl-hero__grid rule so it still
	   wins at mobile widths. */
	.ptl-hero__grid {
		grid-template-columns: 1fr;
		gap: 32px;
	}

	.ptl-hero__content h1,
	.ptl-hero__content .ptl-lead {
		max-width: none;
	}

	.ptl-hero__media img {
		aspect-ratio: 16 / 10;
	}

	/* Prefer no/low overlap on mobile (thin margin only, not the full
	   desktop overlap) so the search bar never collides with Hero content. */
	.ptl-home-search {
		margin-top: -12px;
		padding-bottom: 40px;
	}
}

@media (max-width: 520px) {
	.ptl-hero__media img {
		aspect-ratio: 4 / 3;
	}

	.ptl-home-search {
		margin-top: 0;
	}
}

/* ==========================================================================
   Phase 6 — Room Discovery System (Featured Rooms amenity badges, Area
   Explorer cards, Rental Intent Explorer cards). Appended, not interleaved,
   same convention as the Phase 5 block above. Reuses Phase 5 design tokens
   and grid/breakpoint conventions - no second token system, no new
   breakpoints.
   ========================================================================== */

.ptl-room-card__amenities {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	margin: 10px 0 0;
	padding: 0;
	list-style: none;
}

.ptl-room-card__amenities li {
	padding: 3px 9px;
	border: 1px solid var(--pt-border);
	border-radius: 999px;
	background: var(--pt-surface-soft);
	color: var(--pt-text-soft);
	font-size: 12px;
}

.ptl-area-grid,
.ptl-intent-grid {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 14px;
}

.ptl-area-card,
.ptl-intent-card {
	display: flex;
	flex-direction: column;
	gap: 4px;
	min-height: 44px;
	padding: 16px 18px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	background: #fff;
	text-decoration: none;
	transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}

.ptl-area-card:hover,
.ptl-intent-card:hover {
	border-color: var(--pt-gold);
	box-shadow: 0 10px 24px rgba(39, 58, 74, .1);
}

.ptl-area-card__name,
.ptl-intent-card__label {
	font-size: 15.5px;
	font-weight: 600;
	color: var(--pt-text);
}

.ptl-area-card__count,
.ptl-intent-card__count {
	font-size: 13px;
	color: var(--pt-text-soft);
}

/* Area vs Intent differentiation (Homepage Visual/UX Polish Gate): same base
   card shape, distinct affordance - Area stays compact/typography-led with a
   directional arrow cue, Intent gets an icon + slightly larger padding so
   the two explorers read as different tools, not the same card twice. */
.ptl-area-card {
	position: relative;
	padding-right: 34px;
}

.ptl-area-card__arrow {
	position: absolute;
	right: 16px;
	top: 50%;
	transform: translate(0, -50%);
	color: var(--pt-gold-dark);
	opacity: .5;
	transition: transform .15s ease, opacity .15s ease;
}

.ptl-area-card:hover .ptl-area-card__arrow,
.ptl-area-card:focus-visible .ptl-area-card__arrow {
	opacity: 1;
	transform: translate(4px, -50%);
}

.ptl-intent-card {
	padding: 20px;
	gap: 10px;
	background: var(--pt-surface-soft);
}

.ptl-intent-card__icon {
	display: inline-flex;
	color: var(--pt-gold-dark);
}

@media (max-width: 980px) {
	.ptl-area-grid,
	.ptl-intent-grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
	}
}

@media (max-width: 520px) {
	.ptl-area-grid,
	.ptl-intent-grid {
		grid-template-columns: 1fr;
	}
}

/* ==========================================================================
   Phase 7 — Homepage conversion completion (Why/Process grid fixes, Promo
   Banner, blog-card <h3> handled above). Appended, same convention as
   Phase 5/6 blocks. Reuses existing tokens/breakpoints.

   .ptl-value-list / .ptl-steps are redeclared here (not edited at their
   original definition) for the same reason .ptl-hero__grid was in Phase 5:
   that definition is SHARED with .ptl-card-grid (Featured Rooms, blog grid
   context, etc.) which must keep its 3-column behavior. Why/Process both
   have 4 real items (not 3), so the shared 3-col rule produced an awkward
   3-plus-1 wrap - these overrides fix that for these two sections only.
   ========================================================================== */

.ptl-value-list {
	grid-template-columns: repeat(2, minmax(0, 1fr));
}

.ptl-steps {
	grid-template-columns: repeat(4, minmax(0, 1fr));
}

@media (max-width: 980px) {
	.ptl-value-list,
	.ptl-steps {
		grid-template-columns: 1fr;
	}
}

.ptl-promo-banner {
	position: relative;
	padding: 64px 0;
	overflow: hidden;
}

.ptl-promo-banner--no-image {
	background: var(--pt-navy);
}

.ptl-promo-banner__media {
	position: absolute;
	inset: 0;
	z-index: 0;
}

.ptl-promo-banner__media picture,
.ptl-promo-banner__media img {
	display: block;
	width: 100%;
	height: 100%;
}

.ptl-promo-banner__media img {
	object-fit: cover;
}

.ptl-promo-banner__overlay {
	position: absolute;
	inset: 0;
	background: rgba(0, 0, 0, calc(var(--ptl-banner-overlay, 0) / 100));
}

.ptl-promo-banner:not(.ptl-promo-banner--no-image) {
	min-height: 380px;
	display: flex;
	align-items: center;
}

.ptl-promo-banner .ptl-shell {
	position: relative;
	z-index: 1;
	width: 100%;
}

.ptl-promo-banner__content {
	max-width: 560px;
	padding: 24px 28px;
	border-radius: 8px;
	background: rgba(20, 26, 31, .38);
	color: #fff;
}

.ptl-promo-banner--no-image .ptl-promo-banner__content {
	padding: 0;
	background: transparent;
}

.ptl-promo-banner__content h2 {
	margin: 0 0 12px;
	color: #fff;
}

.ptl-promo-banner__content p {
	margin: 0 0 20px;
	line-height: 1.6;
}

.ptl-promo-banner__content .ptl-button {
	margin: 0;
}

@media (max-width: 520px) {
	.ptl-promo-banner:not(.ptl-promo-banner--no-image) {
		min-height: 320px;
	}

	.ptl-promo-banner__content {
		max-width: none;
	}
}

/* ==========================================================================
   Phase 10 — visually-hidden utility (screen-reader-only text, standard
   clip pattern). Used to restore correct heading hierarchy without
   changing visual layout.
   ========================================================================== */

.ptl-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;
}

/* ==========================================================================
   Phase 8 — Room Archive / Search experience (result count + active-filter
   chips - new UI, the archive previously had neither). Appended, same
   convention as Phase 5/6/7 blocks. Reuses existing tokens.
   ========================================================================== */

.ptl-room-results-header {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 10px 16px;
	margin: 18px 0 20px;
}

.ptl-room-results-count {
	margin: 0;
	font-weight: 700;
	color: var(--pt-text);
}

.ptl-room-filter-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	align-items: center;
}

.ptl-filter-chip {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	min-height: 32px;
	padding: 4px 10px;
	border: 1px solid var(--pt-border);
	border-radius: 999px;
	background: var(--pt-surface-soft);
	color: var(--pt-text);
	font-size: 13px;
	text-decoration: none;
}

.ptl-filter-chip span {
	color: var(--pt-text-soft);
	font-weight: 800;
}

.ptl-filter-reset {
	font-size: 13px;
	font-weight: 700;
	color: var(--pt-gold-dark);
	text-decoration: underline;
}

@media (max-width: 520px) {
	.ptl-room-results-header {
		flex-direction: column;
		align-items: flex-start;
	}
}

/* ==========================================================================
   Phase 9 — Single Room conversion page (Gallery, sticky contact sidebar).
   Appended, same convention as Phase 5/6/7/8 blocks. Reuses existing tokens.
   ========================================================================== */

.ptl-room-gallery {
	display: grid;
	gap: 10px;
	border: 0;
	background: none;
	box-shadow: none;
	padding: 0;
	/* This element also carries .ptl-room-placeholder (shared with the
	   no-image text-fallback state, which legitimately wants
	   place-items:center to center its message). That shared rule's
	   justify-items:center leaks into this real-gallery state too, where it
	   stops both the main image and the thumbnail grid from stretching to
	   the column width - the thumbnail grid's repeat(auto-fill, ...) then
	   has no definite width to wrap against and collapses to a single
	   76px-wide column, turning an 11-photo gallery into one tall narrow
	   strip instead of a compact multi-column grid. Reset back to stretch
	   here, scoped to the real-gallery class only. */
	justify-items: stretch;
}

.ptl-room-gallery__main {
	min-height: 260px;
	border: 1px solid var(--pt-border);
	border-radius: 8px;
	overflow: hidden;
	background: var(--pt-surface-soft);
}

.ptl-room-gallery__main img {
	display: block;
	width: 100%;
	height: 100%;
	max-height: 480px;
	object-fit: cover;
}

.ptl-room-gallery__thumbs {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
	gap: 8px;
	/* Rooms with large galleries (20+ photos) turned this into a very tall,
	   noisy block. Cap the visible height and let it scroll - every photo
	   stays reachable, nothing is removed from the gallery. */
	max-height: 250px;
	overflow-y: auto;
	padding-right: 2px;
}

.ptl-room-gallery__thumb {
	padding: 0;
	border: 2px solid transparent;
	border-radius: 6px;
	overflow: hidden;
	cursor: pointer;
	background: none;
	line-height: 0;
}

.ptl-room-gallery__thumb img {
	display: block;
	width: 100%;
	height: 72px;
	object-fit: cover;
	/* Images are natively draggable by default (browser's own "drag to save/
	   copy image" gesture). A real click almost always has a hair of mouse
	   movement between press and release, which some browsers interpret as
	   the start of that native drag instead of a click - suppressing the
	   click event entirely. draggable="false" on the <img> (gallery.php)
	   handles this in most browsers; -webkit-user-drag is the WebKit/Blink-
	   specific backup for the same thing. */
	-webkit-user-drag: none;
	user-select: none;
}

.ptl-room-gallery__thumb.is-active {
	border-color: var(--pt-gold-dark);
}

/* Sticky contact/cost sidebar on the single room page - the class name
   already implied this, but position:sticky was never actually applied.
   Offset accounts for the sitewide sticky header (~75px). Desktop only -
   removed below 980px where the layout stacks to a single column anyway. */
.ptl-single-content .ptl-sticky-box {
	position: sticky;
	top: 92px;
	align-self: start;
}

@media (max-width: 980px) {
	.ptl-single-content .ptl-sticky-box {
		position: static;
	}
}
