/* ===========================================================================
   Helios Design — Style B "Giấy ấm" (warm paper)

   Components for every page that is NOT the homepage deck:
     /du-an/                 project listing
     /du-an/<slug>/          project detail
     /cam-nhan/              testimonials
     /goc-chia-se/           journal listing
     /goc-chia-se/<slug>/    article

   Colour, type, spacing and button shape come from the `.hl-paper` token remap
   in tokens.css — nothing here hardcodes a palette value. This file only adds
   the components the paper pages need and the deck does not.

   Source of truth: prototypes/assets/css/project.css.

   Handle: hl-paper   Depends: hl-core
   ======================================================================== */

body.hl-paper {
	font-size: 17px;
	background-color: var(--hl-ink);
	color: var(--hl-cream-dim);
	/* A single warm bloom from the top-right corner. This is what keeps a large
	   flat paper field from reading as plain #FFF-adjacent grey. */
	background-image: radial-gradient(60% 40% at 100% 0, rgba(168, 92, 50, .05), transparent 60%);
	background-attachment: fixed;
}

@media (max-width: 640px) {
	body.hl-paper { font-size: 16px; }
}

/* This used to carry `font-variation-settings: "SOFT" 30, "WONK" 1` for
   Fraunces. Both declarations are gone with the serif, and not just as tidying:
   `font-variation-settings` INHERITS, and it is the low-level property — left
   in place it would silently apply named-axis values to whatever variable font
   is used next, and reset every axis it does not name. */
.hl-paper :is(h1, h2, h3, h4, .hl-display, .hl-h2, .hl-h3) {
	font-weight: 500;
	letter-spacing: -.018em;
	color: var(--hl-cream);
}
/* The accent word is carried by colour and weight now. A sans italic at display
   size reads as a mistake rather than as emphasis. */
.hl-paper .hl-display em,
.hl-paper .hl-accent-italic {
	font-style: normal;
	font-weight: 600;
	color: var(--hl-sun);
}

.hl-paper .hl-h1 { font-size: clamp(2.3rem, 5.4vw, 4.4rem); line-height: 1.02; }
.hl-paper .hl-h2 { font-size: clamp(1.7rem, 3.4vw, 2.8rem); line-height: 1.1; }
.hl-paper .hl-h3 { font-size: clamp(1.2rem, 1.8vw, 1.55rem); line-height: 1.28; }

.hl-paper .hl-eyebrow {
	margin-bottom: 18px;
	font-size: .7rem;
	font-weight: 600;
	letter-spacing: .26em;
}
.hl-paper .hl-eyebrow::before { width: 30px; opacity: 1; }

.hl-paper .hl-lead {
	max-width: 66ch;
	font-size: clamp(1.02rem, 1.3vw, 1.18rem);
	line-height: 1.8;
}
.hl-paper .hl-tiny { font-size: .8rem; letter-spacing: .1em; }

.hl-paper .hl-section { padding-block: var(--hl-section); }
.hl-paper .hl-section--ink-2 { background: var(--hl-ink-2); }
.hl-paper .hl-section--ink-3 { background: var(--hl-ink-3); }

/* ---------------------------------------------------------------------------
   Dark relief band

   Paper pages punctuate with an INK band (materials, numbers). Inside it the
   tokens flip back to their dark-canvas meaning, so shared components keep
   working without a second set of rules.
   ------------------------------------------------------------------------ */
.hl-paper .hl-band-dark {
	--hl-ink:         #1C1815;
	--hl-ink-2:       #241F1B;
	--hl-ink-3:       #2E2823;
	--hl-cream:       #FBF7F1;
	--hl-cream-dim:   rgba(251, 247, 241, .72);
	--hl-cream-faint: rgba(251, 247, 241, .5);
	--hl-sun:         #E0A86F;
	--hl-sun-hot:     #F0B063;
	--hl-line:        rgba(251, 247, 241, .16);
	--hl-btn-bg:      #E0A86F;
	--hl-btn-fg:      #1C1815;
	--hl-btn-bg-hover: #F0B063;
	--hl-btn-fg-hover: #1C1815;

	background: var(--hl-ink);
	color: var(--hl-cream-dim);
	padding-block: var(--hl-section);
}

/* ---------------------------------------------------------------------------
   Header — sticky, translucent paper, gains a hairline once scrolled
   ------------------------------------------------------------------------ */
.hl-hdr {
	position: sticky;
	top: 0;
	z-index: 50;
	background: color-mix(in srgb, var(--hl-ink) 88%, transparent);
	backdrop-filter: blur(12px) saturate(1.2);
	border-bottom: 1px solid transparent;
	transition: .4s var(--hl-ease);
}
/* Fallback for browsers without color-mix(). */
@supports not (background: color-mix(in srgb, red 50%, blue)) {
	.hl-hdr { background: rgba(251, 247, 241, .88); }
}
/* The border only appears once the page has moved, so the header is invisible
   chrome at rest and a defined edge over content. */
.hl-hdr.is-stuck {
	border-bottom-color: var(--hl-line);
	box-shadow: 0 6px 24px -18px rgba(28, 24, 21, .5);
}

.hl-hdr--static { position: relative; }

/*
 * Elementor wrapper neutralisation for the Theme Builder header/footer.
 *
 * `position: sticky` resolves against the nearest scrolling ancestor, and it is
 * silently cancelled by an ancestor with `overflow: hidden` — which Elementor
 * sections can acquire. Padding on those wrappers is worse: it sits OUTSIDE the
 * sticky element and shows as a gap above the bar once the page scrolls. The
 * widget owns its own padding, so the wrappers must contribute nothing.
 */
.elementor-location-header .elementor-section,
.elementor-location-header .elementor-container,
.elementor-location-header .elementor-column,
.elementor-location-header .elementor-widget-wrap,
.elementor-location-header .elementor-widget,
.elementor-location-header .e-con,
.elementor-location-header .e-con-inner,
.elementor-location-footer .elementor-section,
.elementor-location-footer .elementor-container,
.elementor-location-footer .elementor-column,
.elementor-location-footer .elementor-widget-wrap,
.elementor-location-footer .elementor-widget,
.elementor-location-footer .e-con,
.elementor-location-footer .e-con-inner {
	width: 100%;
	max-width: none;
	margin: 0;
	padding: 0;
	overflow: visible;
}

/* The header location itself must not clip or scroll, or sticky dies. */
.elementor-location-header {
	overflow: visible;
	contain: none;
}

/* ---------------------------------------------------------------------------
   Stock-Elementor chrome, dragged onto the design system
   ---------------------------------------------------------------------------
   The header and footer are meant to be ONE widget each (`helios_site_header` /
   `helios_site_footer`). A Theme Builder template is database content, though,
   so a site seeded by an older build still renders the superseded composition of
   `theme-site-logo` + `nav-menu` + `heading` + `text-editor` + `button` until it
   is re-seeded — and that composition shipped visibly wrong on heliosdesign.vn:
   Elementor's own accent (green) under the active nav item, an unsized logo, and
   heading/body colours inherited from the Elementor kit rather than the tokens.

   These rules are a safety net, not the design. They cost nothing when the
   Helios widgets are in place, because none of these selectors match then.
   ------------------------------------------------------------------------ */

/* The uploaded logo is sized and inverted in theme.css, which loads on BOTH
   style layers — see the "uploaded logo" block there. Nothing to add here. */

/* No logo file: `helios_chrome_replace_site_logo()` swaps in the lockup, which
   needs the same flex row `.hl-logo` gets elsewhere. */
.hl-logo-slot { line-height: 1; }
.hl-logo-slot .hl-logo { display: inline-flex; }

/* Elementor's nav menu, retinted. `--e-global-color-accent` is Elementor's, not
   ours, and it is what drew the green underline. */
.elementor-location-header .elementor-nav-menu a.elementor-item {
	font-family: var(--hl-f-body);
	font-size: .8rem;
	font-weight: 500;
	color: var(--hl-cream-dim);
	fill: var(--hl-cream-dim);
	padding-inline: 0;
}
.elementor-location-header .elementor-nav-menu a.elementor-item:hover,
.elementor-location-header .elementor-nav-menu a.elementor-item.elementor-item-active,
.elementor-location-header .elementor-nav-menu a.elementor-item.highlighted,
.elementor-location-header .elementor-nav-menu a.elementor-item:focus {
	color: var(--hl-sun);
	fill: var(--hl-sun);
}
/* Every pointer style Elementor offers draws from these two properties. */
.elementor-location-header .elementor-nav-menu--main .elementor-item:before,
.elementor-location-header .elementor-nav-menu--main .elementor-item:after {
	background-color: var(--hl-sun);
	border-color: var(--hl-sun);
}
.elementor-location-header .elementor-nav-menu--dropdown a {
	color: var(--hl-cream-dim);
	background: transparent;
}
.elementor-location-header .elementor-nav-menu--dropdown {
	background: var(--hl-ink);
	border: 1px solid var(--hl-line);
}

.elementor-location-header .elementor-heading-title {
	font-family: var(--hl-f-display);
	color: var(--hl-cream);
}
.elementor-location-header .elementor-button {
	font-family: var(--hl-f-body);
	font-size: .78rem;
	font-weight: 600;
	letter-spacing: .04em;
	border-radius: var(--hl-btn-radius);
	background-color: transparent;
	border: 1px solid var(--hl-line);
	color: var(--hl-cream);
}
.elementor-location-header .elementor-button:hover {
	background-color: var(--hl-sun);
	border-color: var(--hl-sun);
	color: var(--hl-btn-ink);
}

/*
 * The footer band is dark on BOTH design languages, so it cannot use the
 * semantic tokens: under `body.hl-paper` they are inverted (`--hl-cream` is the
 * dark ink `#1C1815`), and using them here would paint dark text on the dark
 * band. `.hl-paper .hl-site-footer` hardcodes the same two literals for exactly
 * this reason — keep the three in step.
 */
.elementor-location-footer .elementor-nav-menu a,
.elementor-location-footer .elementor-widget-text-editor,
.elementor-location-footer .elementor-icon-list-text {
	color: rgba(251, 247, 241, .6);
	background: transparent;
}
.elementor-location-footer .elementor-nav-menu a:hover,
.elementor-location-footer .elementor-icon-list-item:hover .elementor-icon-list-text { color: #E0A86F; }
.elementor-location-footer .elementor-nav-menu--main .elementor-item:before,
.elementor-location-footer .elementor-nav-menu--main .elementor-item:after {
	background-color: #E0A86F;
	border-color: #E0A86F;
}
.elementor-location-footer .elementor-heading-title {
	font-family: var(--hl-f-body);
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: #FBF7F1;
}
.elementor-location-footer .elementor-button {
	font-family: var(--hl-f-body);
	font-size: .78rem;
	font-weight: 600;
	letter-spacing: .04em;
	border-radius: var(--hl-btn-radius);
	background-color: transparent;
	border: 1px solid rgba(251, 247, 241, .22);
	color: #FBF7F1;
}
.elementor-location-footer .elementor-button:hover {
	background-color: #E0A86F;
	border-color: #E0A86F;
	color: #1C1815;
}
/* Prefixed with `.hl-paper` on purpose: `.hl-paper .hl-logo b` further down this
   file has the same specificity and would otherwise win on source order, putting
   dark ink type on the dark footer band. */
.hl-paper .elementor-location-footer .hl-logo b { color: #FBF7F1; }
.hl-paper .elementor-location-footer .hl-logo i { color: rgba(251, 247, 241, .5); }

.hl-hdr__in {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 26px;
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: 15px var(--hl-pad);
}

/* Hotline + burger sit together at the end of the bar. */
.hl-hdr__end {
	display: flex;
	align-items: center;
	gap: 14px;
	flex: 0 0 auto;
}

/* The sun mark: a lit disc, not a flat dot. */
.hl-paper .hl-logo { gap: 10px; align-items: center; }
.hl-paper .hl-logo .hl-sun-mark {
	width: 22px;
	height: 22px;
	background: radial-gradient(circle at 32% 30%, #F0B063, var(--hl-sun));
	box-shadow: 0 0 0 4px rgba(168, 92, 50, .12);
	animation: none;
}
.hl-paper .hl-logo b {
	display: block;
	font-family: var(--hl-f-display);
	font-size: 1.28rem;
	font-weight: 600;
	line-height: 1.1;
	color: var(--hl-cream);
	letter-spacing: 0;
	text-transform: none;
}
.hl-paper .hl-logo i {
	display: block;
	font-size: .55rem;
	letter-spacing: .3em;
	text-transform: uppercase;
	color: var(--hl-cream-faint);
	opacity: 1;
}
.hl-paper .hl-logo img { max-height: 40px; }

.hl-hdr__nav ul {
	display: flex;
	gap: 28px;
	margin: 0;
	padding: 0;
	list-style: none;
}
.hl-hdr__nav a {
	position: relative;
	display: block;
	padding-block: 4px;
	font-size: .8rem;
	font-weight: 500;
	color: var(--hl-cream-dim);
}
/* Underline grows from the left rather than fading in — it reads as a deliberate
   mark on paper. */
.hl-hdr__nav a::after {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	bottom: 0;
	width: 0;
	height: 1px;
	background: var(--hl-sun);
	transition: .35s var(--hl-ease);
}
.hl-hdr__nav a:hover::after,
.hl-hdr__nav .current-menu-item > a::after,
.hl-hdr__nav a[aria-current="page"]::after { width: 100%; }
.hl-hdr__nav .current-menu-item > a,
.hl-hdr__nav a[aria-current="page"] { color: var(--hl-sun); }

.hl-hdr__tel {
	display: flex;
	align-items: center;
	gap: 9px;
	white-space: nowrap;
	font-size: .9rem;
	font-weight: 700;
	color: var(--hl-cream);
}
.hl-hdr__tel i {
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--hl-sun);
	animation: hl-blip 2.4s ease-in-out infinite;
}
@keyframes hl-blip { 50% { opacity: .25; } }

.hl-burger {
	display: none;
	place-items: center;
	width: 42px;
	height: 42px;
	border: 1px solid var(--hl-line);
	border-radius: 2px;
	background: none;
	color: var(--hl-cream);
}

@media (max-width: 1080px) {
	.hl-hdr__nav { display: none; }
	.hl-burger { display: grid; }
	.hl-hdr.is-open .hl-hdr__nav {
		position: absolute;
		inset-inline: 0;
		top: 100%;
		display: block;
		padding: 22px var(--hl-pad);
		background: var(--hl-ink);
		border-bottom: 1px solid var(--hl-line);
	}
	.hl-hdr.is-open .hl-hdr__nav ul { flex-direction: column; gap: 14px; }
}

/* ---------------------------------------------------------------------------
   Breadcrumb
   ------------------------------------------------------------------------ */
.hl-paper .hl-crumb {
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: 22px var(--hl-pad) 0;
	font-size: .76rem;
	letter-spacing: 0;
	text-transform: none;
	color: var(--hl-cream-faint);
}
.hl-paper .hl-crumb li + li::before { content: "/"; margin-right: 9px; opacity: .5; }

/* ---------------------------------------------------------------------------
   Listing head + filter chips
   ------------------------------------------------------------------------ */
.hl-idx-head {
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: clamp(30px, 5vw, 60px) var(--hl-pad) clamp(26px, 3vw, 40px);
}
.hl-idx-head .hl-h1 { max-width: 24ch; }
.hl-idx-head .hl-lead { margin-top: 18px; }

.hl-paper .hl-chips { gap: 8px; margin: 26px 0 0; }
.hl-paper .hl-chip {
	padding: 9px 19px;
	font-size: .74rem;
	font-weight: 600;
	letter-spacing: .1em;
	color: var(--hl-cream-faint);
}
.hl-paper .hl-chip:hover { border-color: var(--hl-cream); color: var(--hl-cream); }
.hl-paper .hl-chip[aria-pressed="true"] {
	background: var(--hl-cream);
	border-color: var(--hl-cream);
	color: var(--hl-ink);
}

/* ---------------------------------------------------------------------------
   Project listing — asymmetric 6-column grid

   The asymmetry is the point: a uniform grid of equal tiles is the "gallery
   dump" the client's competitors already do. Cards declare their own span.
   ------------------------------------------------------------------------ */
.hl-idx-grid {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: clamp(16px, 2vw, 28px);
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: 0 var(--hl-pad) var(--hl-section);
}
/* Project listing card — `.hl-projcard`.
   ---------------------------------------------------------------------------
   Unboxed by design: a photo, then the title and meta on the paper canvas under a
   hairline rule. No fill, no border, no radius, no hover lift.

   It was `.hl-pcard` until 2026-09-09, which collided with the JOURNAL card of the
   same name in theme.css — a boxed dark card with
   `background: rgba(20,17,16,.5)`. theme.css loads on every page and paper.css
   only on paper ones, so this card inherited that fill, and over the paper canvas
   50% of #141110 composites to a mid-grey slab. It showed as a grey band behind
   every caption on /du-an/, with the meta text left at barely-readable contrast on
   top of it.

   Both prototypes had independently used `.pcard` for their own card
   (`v1-onepage-slider.html` = post, `du-an/index.html` = project) and the theme
   ported both under one name. Do not merge them back. */
.hl-projcard { grid-column: span 2; }
.hl-projcard--wide { grid-column: span 4; }
.hl-projcard--half { grid-column: span 3; }
.hl-projcard[hidden] { display: none; }

.hl-projcard__ph {
	position: relative;
	overflow: hidden;
	border-radius: var(--hl-radius);
	background: var(--hl-ink-3);
	aspect-ratio: 4 / 3;
}
.hl-projcard--wide .hl-projcard__ph { aspect-ratio: 16 / 9; }
.hl-projcard--half .hl-projcard__ph { aspect-ratio: 5 / 4; }
.hl-projcard__ph img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.1s var(--hl-ease);
}
.hl-projcard a:hover .hl-projcard__ph img { transform: scale(1.06); }

.hl-badge {
	position: absolute;
	top: 14px;
	inset-inline-start: 14px;
	padding: 6px 12px;
	border-radius: 2px;
	background: color-mix(in srgb, var(--hl-ink) 94%, transparent);
	font-size: .62rem;
	font-weight: 700;
	letter-spacing: .16em;
	text-transform: uppercase;
	color: var(--hl-cream);
}
@supports not (background: color-mix(in srgb, red 50%, blue)) {
	.hl-badge { background: rgba(251, 247, 241, .94); }
}

.hl-projcard__view {
	position: absolute;
	inset: 0;
	display: grid;
	place-content: center;
	background: rgba(28, 24, 21, .42);
	opacity: 0;
	transition: .45s var(--hl-ease);
}
.hl-projcard__view span {
	padding: 11px 22px;
	border: 1px solid #FBF7F1;
	border-radius: 999px;
	color: #FBF7F1;
	font-size: .66rem;
	letter-spacing: .2em;
	text-transform: uppercase;
}
.hl-projcard a:hover .hl-projcard__view,
.hl-projcard a:focus-visible .hl-projcard__view { opacity: 1; }

.hl-projcard__cap {
	display: flex;
	justify-content: space-between;
	align-items: baseline;
	gap: 14px;
	margin-top: 14px;
	padding-top: 14px;
	border-top: 1px solid var(--hl-line);
}
.hl-projcard__cap h2,
.hl-projcard__cap h3 { font-size: 1.28rem; line-height: 1.2; margin: 0; }
.hl-projcard__cap p { margin: 4px 0 0; font-size: .8rem; color: var(--hl-cream-faint); }
.hl-projcard__cap b {
	white-space: nowrap;
	font-family: var(--hl-f-display);
	font-size: 1.05rem;
	color: var(--hl-sun);
}

.hl-empty-cell {
	grid-column: 1 / -1;
	padding: 50px 0;
	text-align: center;
	color: var(--hl-cream-faint);
}

/* ---------------------------------------------------------------------------
   Project detail
   ------------------------------------------------------------------------ */
.hl-p-head {
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: clamp(26px, 4vw, 50px) var(--hl-pad) clamp(28px, 4vw, 46px);
}
.hl-p-head .hl-h1 { max-width: 22ch; margin-bottom: 16px; }
.hl-p-head__where {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px 18px;
	margin: 0 0 22px;
	font-size: .9rem;
	color: var(--hl-cream-faint);
}
.hl-p-head__where b {
	font-family: var(--hl-f-display);
	font-size: 1.15rem;
	font-weight: 600;
	color: var(--hl-sun);
}

.hl-paper .hl-cover {
	position: relative;
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding-inline: var(--hl-pad);
}
.hl-paper .hl-cover figure,
.hl-paper .hl-cover__inner {
	position: relative;
	margin: 0;
	overflow: hidden;
	border-radius: var(--hl-radius);
	box-shadow: var(--hl-shadow-card);
	aspect-ratio: 16 / 9;
	background: var(--hl-ink-3);
}
.hl-paper .hl-cover img { width: 100%; height: 100%; object-fit: cover; }
.hl-paper .hl-cover figcaption {
	position: absolute;
	inset-inline: 0;
	bottom: 0;
	padding: 26px;
	background: var(--hl-scrim-card);
	color: #fff;
	font-size: .84rem;
}

/* Fact strip: 1px gaps filled by the container's own background, so the rules
   between cells are the grid gap rather than eleven borders that double up.
   ---------------------------------------------------------------------------
   That technique means an EMPTY grid area paints the line colour as a solid
   slab. The column count was hardcoded `repeat(6, …)` because the prototype
   happened to show six facts, but the strip is built from whichever of eight
   possible facts a project has filled in, plus any editor-added rows. A project
   with four facts therefore rendered four cells and a two-column grey block —
   which is exactly what shipped on /du-an/zurich-1-3315/.

   `--hl-facts-n` is written inline by single-project.php from the real count, and
   the last cell is widened to close a partial row, so there is never an empty
   area for the background to show through. */
.hl-paper .hl-facts {
	display: grid;
	grid-template-columns: repeat(var(--hl-facts-n, 6), minmax(0, 1fr));
	gap: 1px;
	max-width: var(--hl-wrap);
	margin: clamp(28px, 4vw, 48px) auto 0;
	background: var(--hl-line);
	border: 1px solid var(--hl-line);
}
.hl-paper .hl-facts > div {
	padding: 20px 18px;
	border-top: 0;
	background: var(--hl-ink);
}
.hl-paper .hl-facts dt {
	margin-bottom: 6px;
	font-size: .6rem;
	font-weight: 700;
	letter-spacing: .2em;
	text-transform: uppercase;
	color: var(--hl-cream-faint);
}
.hl-paper .hl-facts dd {
	font-family: var(--hl-f-display);
	font-size: 1.15rem;
	line-height: 1.3;
	color: var(--hl-cream);
}

/* Two-column brief / solution */
.hl-story {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(26px, 4vw, 64px);
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding-inline: var(--hl-pad);
}
.hl-story h2 { margin-bottom: 14px; }
.hl-story p { margin: 0 0 16px; }
.hl-story p:last-child { margin-bottom: 0; }

.hl-pull {
	margin: 26px 0;
	padding: 4px 0 4px 22px;
	border-inline-start: 2px solid var(--hl-sun);
	font-family: var(--hl-f-display);
	font-size: clamp(1.15rem, 1.9vw, 1.5rem);
	font-style: italic;
	line-height: 1.45;
	color: var(--hl-cream);
}

/* Solution bullets: a hairline list with the label in ink, rule-led rather than
   dotted — a dot list here reads as a spec sheet, which is what the story band
   is trying not to be. */
.hl-bullets {
	margin: 22px 0 0;
	padding: 0;
	list-style: none;
	border-top: 1px solid var(--hl-line);
}
.hl-bullets li {
	position: relative;
	padding: 13px 0 13px 22px;
	border-bottom: 1px solid var(--hl-line);
	font-size: .92rem;
	line-height: 1.7;
}
.hl-bullets li::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	top: 23px;
	width: 9px;
	height: 1px;
	background: var(--hl-sun);
}
.hl-bullets li b {
	color: var(--hl-cream);
	font-weight: 600;
}

/* Before / after comparison.
 *
 * assets/js/paper.js writes --hl-ba-p onto [data-hl-ba] from the range value.
 * The 50% default is declared HERE as well, not only in JS: without it the
 * clip-path resolves against an invalid value on first paint, the "before" image
 * covers the whole frame, and the control looks inert until someone drags it. */
.hl-ba-fig {
	margin: 0;
	grid-column: span 6;
}
.hl-ba {
	--hl-ba-p: 50%;
	position: relative;
	overflow: hidden;
	border-radius: var(--hl-radius);
	background: var(--hl-ink-2);
}
.hl-ba img {
	display: block;
	width: 100%;
	height: 100%;
	aspect-ratio: 16 / 9;
	object-fit: cover;
}
.hl-ba__before {
	position: absolute;
	inset: 0;
	clip-path: inset(0 calc(100% - var(--hl-ba-p)) 0 0);
}

/* The range fills the frame and is invisible; the visible affordance is the
   .hl-ba__line handle. It stays a real <input type="range"> so it is
   keyboard-operable and announced by a screen reader, which a drag-handler div
   never is. */
.hl-ba__range {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	margin: 0;
	padding: 0;
	-webkit-appearance: none;
	appearance: none;
	background: transparent;
	border: 0;
	cursor: ew-resize;
}
.hl-ba__range::-webkit-slider-runnable-track { height: 100%; background: transparent; }
.hl-ba__range::-webkit-slider-thumb {
	-webkit-appearance: none;
	width: 34px;
	height: 200px;
	background: transparent;
	border: 0;
}
.hl-ba__range::-moz-range-track { height: 100%; background: transparent; border: 0; }
.hl-ba__range::-moz-range-thumb { width: 34px; height: 200px; background: transparent; border: 0; }
.hl-ba__range:focus-visible { outline: 2px solid var(--hl-sun); outline-offset: 3px; }

.hl-ba__line {
	position: absolute;
	top: 0;
	bottom: 0;
	inset-inline-start: var(--hl-ba-p);
	width: 2px;
	background: var(--hl-cream);
	transform: translateX(-1px);
	pointer-events: none;
}
.hl-ba__line::after {
	content: "\2194";
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	display: grid;
	place-items: center;
	width: 44px;
	height: 44px;
	border-radius: 50%;
	background: var(--hl-cream);
	color: var(--hl-ink);
	font-size: 1rem;
	line-height: 1;
}
.hl-ba__tag {
	position: absolute;
	top: 14px;
	z-index: 2;
	padding: 5px 11px;
	border-radius: 999px;
	/* Literal ink, not var(--hl-ink): the tag sits on a photograph, so it needs
	   the dark scrim in BOTH palettes. Under .hl-paper the token inverts to
	   near-white and the label would vanish. */
	background: rgba(11, 9, 8, .74);
	color: #FBF7F1;
	font-size: .62rem;
	font-weight: 700;
	letter-spacing: .14em;
	text-transform: uppercase;
	pointer-events: none;
}
.hl-ba__tag.is-before { inset-inline-start: 14px; }
.hl-ba__tag.is-after { inset-inline-end: 14px; }
.hl-ba-fig figcaption {
	padding-top: 10px;
	font-size: .8rem;
	line-height: 1.6;
	color: var(--hl-cream-faint);
}
.hl-ba-fig figcaption b {
	color: var(--hl-sun);
	font-weight: 700;
}

/* Gallery: same 6-column rhythm as the listing. */
.hl-paper .hl-gallery {
	display: grid;
	grid-template-columns: repeat(6, minmax(0, 1fr));
	gap: clamp(12px, 1.6vw, 22px);
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding-inline: var(--hl-pad);
}
/* The span comes from `--hl-span`, written per figure by single-project.php from
   helios_gallery_spans(). A custom property rather than a class because the
   planner produces any width from 2 to 6, and the three `is-*` classes below
   could only name three of them — which is how the gallery ended up with rows
   that did not add up to 6 and showed gaps.

   The `is-*` classes are kept as a fallback for any markup that still uses them
   (the paper harness, and older cached HTML). They lose to the inline property. */
.hl-paper .hl-gallery figure { margin: 0; grid-column: span var(--hl-span, 3); }
.hl-paper .hl-gallery figure.is-third { grid-column: span var(--hl-span, 2); }
.hl-paper .hl-gallery figure.is-two-thirds { grid-column: span var(--hl-span, 4); }
.hl-paper .hl-gallery figure.is-wide { grid-column: span var(--hl-span, 6); }
.hl-paper .hl-gallery button {
	position: relative;
	width: 100%;
	cursor: zoom-in;
}
.hl-paper .hl-gallery img {
	aspect-ratio: 4 / 3;
	transition: transform 1.1s var(--hl-ease);
}
.hl-paper .hl-gallery figure.is-portrait img { aspect-ratio: 3 / 4; }
/* `is-wide` after `is-portrait` on purpose, and the order is load-bearing.
   helios_gallery_spans() gives an image a full row when its orientation run is
   only one image long, so a lone portrait can end up with BOTH classes. At 3/4
   and 1137px wide that is a 1516px-tall wall; the 16/9 crop below wins on source
   order and keeps it a photograph. Equal specificity, so do not reorder these. */
.hl-paper .hl-gallery figure.is-wide img { aspect-ratio: 16 / 9; }
.hl-paper .hl-gallery button::after {
	content: "⤢";
	position: absolute;
	inset-inline-end: 12px;
	bottom: 12px;
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	border-radius: 50%;
	background: rgba(251, 247, 241, .92);
	color: #1C1815;
	font-size: .85rem;
	opacity: 0;
	transform: translateY(6px);
	transition: .4s var(--hl-ease);
}
.hl-paper .hl-gallery button:hover::after,
.hl-paper .hl-gallery button:focus-visible::after { opacity: 1; transform: none; }
.hl-paper .hl-gallery figcaption {
	padding-top: 10px;
	font-size: .8rem;
	line-height: 1.6;
	color: var(--hl-cream-faint);
}

/* Materials, on the dark relief band */
.hl-mats {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: clamp(14px, 2vw, 26px);
	margin-top: 34px;
}
.hl-mats article {
	padding: 22px;
	border: 1px solid var(--hl-line);
	border-radius: var(--hl-radius);
	transition: .45s var(--hl-ease);
}
.hl-mats article:hover {
	border-color: var(--hl-sun);
	background: rgba(224, 168, 111, .06);
}
.hl-mats h3 { margin-bottom: 8px; font-size: 1.15rem; }
.hl-mats p { margin: 0; font-size: .85rem; line-height: 1.7; }
.hl-mats__sw { display: flex; gap: 6px; margin-top: 14px; }
.hl-mats__sw i {
	width: 24px;
	height: 24px;
	border-radius: 50%;
	border: 1px solid var(--hl-line);
}

/* Owner quote, on paper-2 with rules above and below */
.hl-quote-sec {
	padding-block: var(--hl-section);
	background: var(--hl-ink-2);
	border-block: 1px solid var(--hl-line);
}
.hl-quote-sec figure {
	max-width: 940px;
	margin-inline: auto;
	padding-inline: var(--hl-pad);
	text-align: center;
}
/* line-height .5 pulls the oversized glyph onto the quote's first line. */
.hl-quote-sec__mk {
	display: block;
	margin-bottom: 26px;
	font-family: var(--hl-f-display);
	font-size: 4.4rem;
	line-height: .5;
	color: var(--hl-sun);
	opacity: .42;
}
.hl-quote-sec blockquote {
	font-family: var(--hl-f-display);
	font-size: clamp(1.35rem, 2.6vw, 2.1rem);
	font-style: italic;
	line-height: 1.42;
	color: var(--hl-cream);
}
.hl-quote-sec figcaption { margin-top: 26px; font-size: .8rem; color: var(--hl-cream-faint); }
.hl-quote-sec figcaption b {
	display: block;
	margin-bottom: 4px;
	font-size: .95rem;
	color: var(--hl-cream);
}

/* Next project */
.hl-next {
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: var(--hl-section) var(--hl-pad);
}
.hl-next a {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: clamp(20px, 3vw, 44px);
	align-items: center;
	padding-top: clamp(24px, 3vw, 40px);
	border-top: 1px solid var(--hl-line);
}
.hl-next__ph {
	aspect-ratio: 16 / 10;
	overflow: hidden;
	border-radius: var(--hl-radius);
	background: var(--hl-ink-3);
}
.hl-next__ph img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.1s var(--hl-ease);
}
.hl-next a:hover .hl-next__ph img { transform: scale(1.05); }
.hl-next__k {
	margin: 0 0 12px;
	font-size: .66rem;
	font-weight: 700;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--hl-sun);
}
.hl-next h2 { margin-bottom: 8px; }
.hl-next__m { margin: 0; font-size: .9rem; color: var(--hl-cream-faint); }
.hl-next .hl-go { margin-top: 20px; font-weight: 700; }
.hl-next a:hover .hl-go { gap: 16px; }

/* ---------------------------------------------------------------------------
   CTA band — sand, above the footer
   ------------------------------------------------------------------------ */
.hl-paper .hl-cta-band {
	max-width: none;
	padding: clamp(46px, 6vw, 84px) var(--hl-pad);
	border-top: 1px solid var(--hl-line);
	background: var(--hl-ink-3);
}
.hl-paper .hl-cta-band__in {
	display: grid;
	grid-template-columns: 1.3fr 1fr;
	gap: clamp(22px, 3vw, 50px);
	align-items: center;
	max-width: var(--hl-wrap);
	margin-inline: auto;
}
.hl-paper .hl-cta-band__actions { justify-content: flex-end; }

/* ---------------------------------------------------------------------------
   Testimonials (/cam-nhan/)
   ------------------------------------------------------------------------ */
.hl-t-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(16px, 2vw, 26px);
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: clamp(18px, 2.5vw, 34px) var(--hl-pad) var(--hl-section);
}
.hl-tcard {
	display: flex;
	flex-direction: column;
	margin: 0;
	overflow: hidden;
	border: 1px solid var(--hl-line);
	border-radius: var(--hl-radius);
	background: var(--hl-ink);
	transition: .5s var(--hl-ease);
}
.hl-tcard:hover {
	border-color: var(--hl-sun);
	transform: translateY(-4px);
	box-shadow: var(--hl-shadow-card);
}
.hl-tcard[hidden] { display: none; }
.hl-tcard__body {
	display: flex;
	flex: 1;
	flex-direction: column;
	padding: 22px;
}
.hl-tcard__tag {
	align-self: flex-start;
	margin-bottom: 14px;
	padding: 5px 11px;
	border: 1px solid var(--hl-line);
	border-radius: 999px;
	font-size: .58rem;
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: var(--hl-sun);
}
.hl-tcard blockquote {
	margin: 0;
	font-family: var(--hl-f-display);
	font-size: 1.16rem;
	font-style: italic;
	line-height: 1.42;
	color: var(--hl-cream);
}
.hl-tcard__more { margin: 14px 0 0; font-size: .86rem; line-height: 1.7; color: var(--hl-cream-faint); }
.hl-tcard figcaption {
	margin-top: auto;
	padding-top: 18px;
	font-size: .78rem;
	color: var(--hl-cream-faint);
}
.hl-tcard figcaption b {
	display: block;
	margin-bottom: 3px;
	font-size: .92rem;
	color: var(--hl-cream);
}
.hl-tcard .hl-go { margin-top: 14px; font-weight: 700; }
.hl-tcard .hl-go:hover { gap: 15px; }

/* Video poster + play. Shared with the article author slot. */
.hl-vid {
	position: relative;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	border-radius: var(--hl-radius);
	background: var(--hl-ink-3);
}
.hl-vid img,
.hl-vid iframe {
	display: block;
	width: 100%;
	height: 100%;
	border: 0;
	object-fit: cover;
}
.hl-vid::after {
	content: "";
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(28, 24, 21, .05), rgba(28, 24, 21, .42));
	pointer-events: none;
	transition: .5s var(--hl-ease);
}
.hl-vid.is-playing::after { display: none; }
.hl-vid__play {
	position: absolute;
	inset-inline-start: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	z-index: 2;
	display: grid;
	place-items: center;
	width: 62px;
	height: 62px;
	padding-left: 3px;
	border: 1px solid #FBF7F1;
	border-radius: 50%;
	background: rgba(28, 24, 21, .42);
	color: #FBF7F1;
	font-size: 1rem;
	transition: .4s var(--hl-ease);
}
.hl-vid__play:hover {
	background: #FBF7F1;
	color: #1C1815;
	transform: translate(-50%, -50%) scale(1.07);
}
.hl-vid__label {
	position: absolute;
	inset-inline-start: 14px;
	top: 14px;
	z-index: 2;
	padding: 6px 12px;
	border-radius: 999px;
	background: rgba(28, 24, 21, .6);
	backdrop-filter: blur(4px);
	font-size: .58rem;
	font-weight: 700;
	letter-spacing: .18em;
	text-transform: uppercase;
	color: #FBF7F1;
}

/* Numbers strip on the dark band */
.hl-stat-row {
	display: grid;
	grid-template-columns: repeat(4, minmax(0, 1fr));
	gap: 1px;
	max-width: var(--hl-wrap);
	margin-inline: auto;
	background: var(--hl-line);
	border: 1px solid var(--hl-line);
}
.hl-stat-row > div { padding: clamp(20px, 2.6vw, 34px); background: var(--hl-ink); }
.hl-stat-row b {
	display: block;
	font-family: var(--hl-f-display);
	font-size: clamp(2rem, 4vw, 3.4rem);
	font-weight: 500;
	line-height: 1;
	color: var(--hl-sun);
}
.hl-stat-row b sup { font-size: .4em; vertical-align: super; color: var(--hl-cream); opacity: .7; }
.hl-stat-row p { margin: 12px 0 0; font-size: .8rem; line-height: 1.6; }

/* ---------------------------------------------------------------------------
   Journal listing (/goc-chia-se/)
   ------------------------------------------------------------------------ */
.hl-bmeta {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 16px;
	margin: 0;
	font-size: .68rem;
	font-weight: 600;
	letter-spacing: .14em;
	text-transform: uppercase;
	color: var(--hl-cream-faint);
}
/* A hairline separator drawn per item, so removing one never leaves a dangling
   bullet the way a "·" character would. */
.hl-bmeta span + span { position: relative; padding-left: 16px; }
.hl-bmeta span + span::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	top: 50%;
	width: 6px;
	height: 1px;
	background: var(--hl-line);
}

.hl-bfeature {
	max-width: var(--hl-wrap);
	margin: 0 auto clamp(28px, 4vw, 52px);
	padding-inline: var(--hl-pad);
}
.hl-bfeature[hidden] { display: none; }
.hl-bfeature a {
	display: grid;
	grid-template-columns: 1.15fr 1fr;
	gap: clamp(20px, 3vw, 48px);
	align-items: center;
}
.hl-bfeature__ph {
	position: relative;
	aspect-ratio: 16 / 10;
	overflow: hidden;
	border-radius: var(--hl-radius);
	background: var(--hl-ink-3);
}
.hl-bfeature__ph img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.1s var(--hl-ease);
}
.hl-bfeature a:hover .hl-bfeature__ph img { transform: scale(1.04); }
.hl-bfeature__k {
	margin: 0 0 12px;
	font-size: .66rem;
	font-weight: 700;
	letter-spacing: .22em;
	text-transform: uppercase;
	color: var(--hl-sun);
}
.hl-bfeature h2 { margin-bottom: 12px; }
.hl-bfeature__ex { margin: 0 0 16px; color: var(--hl-cream-dim); }
.hl-bfeature .hl-go { margin-top: 18px; font-weight: 700; }
.hl-bfeature a:hover .hl-go { gap: 16px; }

.hl-b-grid {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	gap: clamp(16px, 2vw, 28px);
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: 0 var(--hl-pad) clamp(20px, 3vw, 36px);
}
.hl-bcard {
	display: flex;
	overflow: hidden;
	border: 1px solid var(--hl-line);
	border-radius: var(--hl-radius);
	background: var(--hl-ink);
	transition: .5s var(--hl-ease);
}
.hl-bcard:hover {
	border-color: var(--hl-sun);
	transform: translateY(-4px);
	box-shadow: var(--hl-shadow-card);
}
.hl-bcard[hidden] { display: none; }
.hl-bcard > a { display: flex; flex-direction: column; width: 100%; }
.hl-bcard__ph {
	position: relative;
	aspect-ratio: 16 / 10;
	overflow: hidden;
	background: var(--hl-ink-3);
}
.hl-bcard__ph img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	transition: transform 1.1s var(--hl-ease);
}
.hl-bcard:hover .hl-bcard__ph img { transform: scale(1.05); }
.hl-bcard__body { display: flex; flex: 1; flex-direction: column; padding: 20px; }
.hl-bcard h2,
.hl-bcard h3 { margin: 12px 0 10px; font-size: 1.24rem; line-height: 1.24; }
.hl-bcard__ex { margin: 0; font-size: .86rem; line-height: 1.7; color: var(--hl-cream-faint); }
.hl-bcard .hl-go { margin-top: auto; padding-top: 18px; font-weight: 700; }
.hl-bcard:hover .hl-go { gap: 15px; }

/* Pagination — square, not pills, matching the button language. */
.hl-paper .hl-pager {
	gap: 8px;
	max-width: var(--hl-wrap);
	margin: 0 auto;
	padding: 0 var(--hl-pad) var(--hl-section);
}
.hl-paper .hl-pager .page-numbers {
	min-width: 42px;
	height: 42px;
	padding: 0 14px;
	border-radius: 2px;
	font-size: .8rem;
	font-weight: 600;
	color: var(--hl-cream-dim);
}
.hl-paper .hl-pager .page-numbers:hover { border-color: var(--hl-cream); color: var(--hl-cream); }
.hl-paper .hl-pager .page-numbers.current {
	background: var(--hl-cream);
	border-color: var(--hl-cream);
	color: var(--hl-ink);
}

/* ---------------------------------------------------------------------------
   Article (/goc-chia-se/<slug>/)
   ------------------------------------------------------------------------ */
.hl-a-head {
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding: clamp(26px, 4vw, 50px) var(--hl-pad) clamp(24px, 3vw, 40px);
}
.hl-a-head .hl-h1 { max-width: 26ch; margin-bottom: 16px; }
.hl-a-head .hl-bmeta { margin-bottom: 20px; }
.hl-a-head .hl-lead { max-width: 60ch; color: var(--hl-cream-dim); }

/* Reading progress, above the sticky header. */
.hl-read-progress {
	position: fixed;
	inset-inline: 0;
	top: 0;
	z-index: 60;
	height: 3px;
	background: transparent;
	pointer-events: none;
}
.hl-read-progress span {
	display: block;
	width: 0;
	height: 100%;
	background: linear-gradient(90deg, var(--hl-sun), #E0A86F);
}

/*
 * Two-column article. minmax(0,1fr) on the text column, never a bare 1fr — a
 * bare 1fr resolves to minmax(auto,1fr), and one long unbroken word would then
 * widen the whole page.
 */
.hl-article-layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 320px;
	gap: clamp(30px, 4vw, 64px);
	align-items: start;
	max-width: var(--hl-wrap);
	margin-inline: auto;
	padding-inline: var(--hl-pad);
}
.hl-article-main { min-width: 0; }

/*
 * The rail is the SINGLE scroll container. Nesting a second scrollbar inside a
 * 320px column makes it guesswork which one the wheel drives.
 */
.hl-article-rail {
	position: sticky;
	top: 100px;
	align-self: start;
	display: grid;
	gap: 20px;
	max-height: calc(100vh - 124px);
	overflow-y: auto;
	padding-right: 4px;
	scrollbar-width: thin;
	scrollbar-color: var(--hl-ink-3) transparent;
	overscroll-behavior: contain;
}
.hl-article-rail::-webkit-scrollbar { width: 6px; }
.hl-article-rail::-webkit-scrollbar-track { background: transparent; }
.hl-article-rail::-webkit-scrollbar-thumb { background: var(--hl-ink-3); border-radius: 3px; }
.hl-article-rail::-webkit-scrollbar-thumb:hover { background: var(--hl-cream-faint); }

.hl-rail-card {
	padding: 20px;
	border: 1px solid var(--hl-line);
	border-radius: var(--hl-radius);
	background: var(--hl-ink-2);
}
.hl-rail-card .hl-eyebrow { display: block; margin-bottom: 14px; }
.hl-rail-card .hl-eyebrow::before { display: none; }
.hl-rail-card p { margin: 0 0 14px; font-size: .86rem; line-height: 1.7; color: var(--hl-cream-faint); }

.hl-rail-toc { margin: 0; padding: 0; list-style: none; font-size: .86rem; line-height: 1.45; }
.hl-rail-toc li { margin-bottom: 2px; }
.hl-rail-toc a {
	display: block;
	padding: 7px 0 7px 14px;
	border-inline-start: 2px solid var(--hl-line);
	color: var(--hl-cream-faint);
	transition: color .3s var(--hl-ease), border-color .3s var(--hl-ease);
}
.hl-rail-toc a:hover,
.hl-rail-toc a:focus-visible { color: var(--hl-cream); border-inline-start-color: var(--hl-cream-faint); }
.hl-rail-toc a.is-active {
	color: var(--hl-sun-hot);
	border-inline-start-color: var(--hl-sun);
	font-weight: 600;
}

.hl-rail-cta { background: var(--hl-ink-3); }
.hl-rail-cta p { color: var(--hl-cream-dim); }
.hl-rail-cta .hl-btn { display: flex; justify-content: center; }
.hl-rail-phone { display: block; margin-top: 12px; text-align: center; font-size: .82rem; color: var(--hl-cream-faint); }
.hl-rail-phone strong { white-space: nowrap; color: var(--hl-sun-hot); }
.hl-rail-phone:hover strong { color: var(--hl-cream); }

.hl-rail-author { display: flex; gap: 12px; align-items: center; }
.hl-rail-author__av {
	display: grid;
	place-items: center;
	flex: 0 0 42px;
	width: 42px;
	height: 42px;
	border-radius: 50%;
	background: radial-gradient(circle at 32% 30%, #F0B063, var(--hl-sun));
	color: #FBF7F1;
	font-family: var(--hl-f-display);
	font-size: 1rem;
	font-weight: 600;
}
.hl-rail-author__name { display: block; font-family: var(--hl-f-display); font-size: .98rem; font-weight: 600; color: var(--hl-cream); }
.hl-rail-author__role { display: block; margin-top: 3px; font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--hl-cream-faint); }

/* Prose. Measure capped near 66 characters; images and boxes stay full width. */
/* ONE measure, on the container.
   ---------------------------------------------------------------------------
   The reading measure used to be declared per child — `> p, > ul, > ol, > h3,
   > blockquote { max-width: 66ch }` — with the container left at `max-width:
   none`. Anything not on that list escaped it, and `h2` was not on it. Measured
   in the paper harness at a 1440px viewport, inside an 834px article column:

     h2, blockquote, figure   right edge 941   (full column)
     p, ul, ol                right edge 759   (66ch = 652px)

   so every paragraph sat 182px short of the right edge its own headings
   established. That step is what reads as the paragraphs being sunken in.
   `blockquote` was in the list and still escaped, because 66ch resolves against
   ITS larger font-size and came out at 1025px — wider than the column.

   Putting the measure on `.hl-prose` fixes both: one cap, in one place, that a
   child cannot opt out of and that does not depend on each child's font-size.
   70ch rather than 66ch because the whole block now shares it, so it can afford
   to be a little wider without any single line getting long.

   Do NOT move the cap back onto the children. */
.hl-paper .hl-prose {
	/* 76ch fills most of the article column without letting a line run long. The
	   column itself tops out around 876px (1340px container − padding − 64px gap −
	   320px rail), which is ~88 characters — too long to read comfortably, so the
	   measure is a real cap rather than decoration. */
	max-width: 76ch;
	/* theme.css centres `.hl-prose` with `margin-inline: auto`, which is right for a
	   single-column page and wrong here: it would leave dead space on the LEFT and
	   pull the body copy out of line with the article title, eyebrow and meta, all
	   of which start at the column's left edge. */
	margin-inline: 0;
	font-size: 1.04rem;
	line-height: 1.85;
}
.hl-paper .hl-prose p { margin: 0 0 20px; }
/*
 * No scroll-margin-top on headings: html already carries scroll-padding-top:90px
 * and the two STACK, landing an anchored heading ~190px down — past the
 * scroll-spy's active line, so the rail highlighted the previous heading after
 * every jump.
 */
.hl-paper .hl-prose h3 { margin: clamp(30px, 4vw, 48px) 0 14px; }
.hl-paper .hl-prose ul,
.hl-paper .hl-prose ol { margin: 0 0 22px; padding-left: 0; list-style: none; }
.hl-paper .hl-prose li {
	position: relative;
	padding: 9px 0 9px 30px;
	border-bottom: 1px solid var(--hl-line);
	line-height: 1.75;
}
.hl-paper .hl-prose ul li::before {
	content: "";
	position: absolute;
	inset-inline-start: 0;
	top: 20px;
	width: 10px;
	height: 1px;
	background: var(--hl-sun);
}
.hl-paper .hl-prose ol { counter-reset: hl-step; }
.hl-paper .hl-prose ol li { counter-increment: hl-step; }
.hl-paper .hl-prose ol li::before {
	content: counter(hl-step, decimal-leading-zero);
	position: absolute;
	inset-inline-start: 0;
	top: 9px;
	font-family: var(--hl-f-display);
	font-size: .86rem;
	font-weight: 600;
	color: var(--hl-sun);
}
.hl-paper .hl-prose li b { color: var(--hl-cream); font-weight: 600; }
.hl-paper .hl-prose blockquote {
	margin: clamp(28px, 4vw, 44px) 0;
	padding: 4px 0 4px 24px;
	border-inline-start: 2px solid var(--hl-sun);
	font-family: var(--hl-f-display);
	font-size: clamp(1.2rem, 2vw, 1.55rem);
	font-style: italic;
	line-height: 1.45;
	color: var(--hl-cream);
}
.hl-paper .hl-prose :is(figure, .wp-block-image) { margin: clamp(28px, 4vw, 44px) 0; }
.hl-paper .hl-prose img { border-radius: var(--hl-radius); background: var(--hl-ink-3); }
.hl-paper .hl-prose figcaption { padding-top: 10px; font-size: .8rem; line-height: 1.6; color: var(--hl-cream-faint); }

/* Callout box */
.hl-a-box {
	margin: clamp(28px, 4vw, 44px) 0;
	padding: clamp(20px, 2.6vw, 30px);
	border: 1px solid var(--hl-line);
	border-radius: var(--hl-radius);
	background: var(--hl-ink-2);
}
.hl-a-box h3 { margin-bottom: 14px; font-size: 1.14rem; }
.hl-a-box ul { margin: 0; }
.hl-a-box li:last-child { border-bottom: 0; padding-bottom: 0; }

.hl-article-tags {
	display: flex;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 30px;
	padding: 0;
	list-style: none;
}
.hl-article-tags a {
	display: inline-block;
	padding: 7px 13px;
	border: 1px solid var(--hl-line);
	border-radius: 999px;
	background: var(--hl-ink-2);
	font-size: .68rem;
	font-weight: 600;
	letter-spacing: .1em;
	text-transform: uppercase;
	color: var(--hl-cream-faint);
	transition: .4s var(--hl-ease);
}
.hl-article-tags a:hover { border-color: var(--hl-sun); color: var(--hl-sun); }

.hl-a-share {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: space-between;
	gap: 12px 22px;
	padding: 20px 0;
	border-block: 1px solid var(--hl-line);
}
.hl-a-share__k { font-size: .66rem; font-weight: 700; letter-spacing: .2em; text-transform: uppercase; color: var(--hl-cream-faint); }
.hl-a-share__links { display: flex; flex-wrap: wrap; gap: 8px; }
.hl-a-share__links a {
	padding: 9px 18px;
	border: 1px solid var(--hl-line);
	border-radius: 999px;
	font-size: .74rem;
	font-weight: 600;
	transition: .4s var(--hl-ease);
}
.hl-a-share__links a:hover { border-color: var(--hl-sun); color: var(--hl-sun); }

/* ---------------------------------------------------------------------------
   Footer — ink, four columns
   ------------------------------------------------------------------------ */
.hl-paper .hl-site-footer {
	padding: clamp(44px, 6vw, 72px) var(--hl-pad) 24px;
	background: #1C1815;
	border-top: 0;
	color: rgba(251, 247, 241, .6);
}
.hl-paper .hl-site-footer__grid { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: clamp(24px, 4vw, 48px); }
.hl-paper .hl-site-footer h2 {
	margin-bottom: 16px;
	font-family: var(--hl-f-body);
	font-size: .7rem;
	font-weight: 700;
	letter-spacing: .22em;
	color: #FBF7F1;
}
.hl-paper .hl-site-footer ul { display: grid; gap: 9px; }
.hl-paper .hl-site-footer li + li { margin-top: 0; }
.hl-paper .hl-site-footer a { font-size: .9rem; color: rgba(251, 247, 241, .6); }
.hl-paper .hl-site-footer a:hover { color: #E0A86F; }
.hl-paper .hl-site-footer .hl-logo b { color: #FBF7F1; }
.hl-paper .hl-site-footer .hl-logo i { color: rgba(251, 247, 241, .5); }
.hl-paper .hl-site-footer .hl-lead { color: rgba(251, 247, 241, .6); font-size: .87rem; }
.hl-ftr-cta {
	margin: 0 0 18px;
	font-family: var(--hl-f-display);
	font-size: 1.45rem;
	line-height: 1.3;
	color: #FBF7F1;
}
.hl-paper .hl-site-footer .hl-btn--ghost {
	color: #FBF7F1;
	border-color: rgba(251, 247, 241, .3);
}
.hl-paper .hl-site-footer .hl-btn--ghost:hover {
	background: rgba(251, 247, 241, .08);
	border-color: #FBF7F1;
	color: #FBF7F1;
}
.hl-paper .hl-site-footer__bar {
	margin-top: clamp(34px, 5vw, 56px);
	padding-top: 20px;
	border-top: 1px solid rgba(251, 247, 241, .14);
	font-size: .76rem;
}
.hl-paper .hl-site-footer__bar .hl-tiny { color: rgba(251, 247, 241, .6); text-transform: none; letter-spacing: 0; }

/* Floating call button — replaces the deck's social bar on paper pages. */
.hl-fab {
	position: fixed;
	inset-inline-end: 20px;
	bottom: 20px;
	z-index: 60;
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 14px 22px;
	border-radius: 999px;
	background: var(--hl-sun);
	color: #FBF7F1;
	font-size: .8rem;
	font-weight: 700;
	letter-spacing: .08em;
	box-shadow: 0 14px 34px -12px rgba(168, 92, 50, .7);
	transition: .4s var(--hl-ease);
}
.hl-fab:hover { background: var(--hl-sun-hot); color: #FBF7F1; transform: translateY(-3px); }

/* ---------------------------------------------------------------------------
   Reveal — paper pages animate per element as they scroll into view
   ------------------------------------------------------------------------ */
.hl-anim .hl-paper [data-hl-reveal],
.hl-anim body.hl-paper [data-hl-reveal] {
	transform: translateY(22px);
	transition: opacity .85s var(--hl-ease), transform .85s var(--hl-ease);
}

/* ---------------------------------------------------------------------------
   Responsive
   ------------------------------------------------------------------------ */
@media (max-width: 1080px) {
	.hl-paper .hl-facts { grid-template-columns: repeat(3, minmax(0, 1fr)); }
	.hl-story,
	.hl-next a,
	.hl-paper .hl-cta-band__in,
	.hl-bfeature a { grid-template-columns: minmax(0, 1fr); }
	.hl-paper .hl-cta-band__actions { justify-content: flex-start; }
	.hl-mats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.hl-t-grid,
	.hl-b-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.hl-stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
	.hl-idx-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
	.hl-projcard,
	.hl-projcard--wide,
	.hl-projcard--half { grid-column: span 2; }

	/*
	 * The rail un-sticks and moves ABOVE the prose as a two-up card row, so the
	 * contents list and the CTA are the first things seen. A static column has
	 * nothing to stick to, so the height cap and the inner scroll go with it.
	 */
	.hl-article-layout { grid-template-columns: minmax(0, 1fr); gap: 34px; }
	.hl-article-rail {
		position: static;
		top: auto;
		order: -1;
		grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
		max-height: none;
		overflow-y: visible;
		padding-right: 0;
	}
	.hl-rail-card--toc { grid-column: 1 / -1; }
	.hl-paper .hl-site-footer__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 640px) {
	.hl-paper .hl-facts { grid-template-columns: 1fr 1fr; }
	.hl-paper .hl-gallery { grid-template-columns: 1fr; }
	.hl-paper .hl-gallery figure,
	.hl-paper .hl-gallery figure.is-wide,
	.hl-paper .hl-gallery figure.is-third,
	.hl-paper .hl-gallery figure.is-two-thirds,
	.hl-ba-fig { grid-column: span 1; }
	/* The 44px handle is most of a phone-width frame, so shrink it rather than
	   let it cover the comparison it is meant to reveal. */
	.hl-ba__line::after { width: 36px; height: 36px; font-size: .9rem; }
	.hl-mats { grid-template-columns: 1fr; }
	.hl-idx-grid { grid-template-columns: 1fr; }
	.hl-projcard,
	.hl-projcard--wide,
	.hl-projcard--half { grid-column: span 1; }
	.hl-t-grid,
	.hl-b-grid { grid-template-columns: 1fr; }
	.hl-stat-row { grid-template-columns: 1fr; }
	.hl-paper .hl-site-footer__grid { grid-template-columns: 1fr; }
	.hl-paper .hl-cover__inner { aspect-ratio: 4 / 3; }
	.hl-a-share { justify-content: flex-start; }
	.hl-article-rail { grid-template-columns: minmax(0, 1fr); }
	.hl-rail-card { padding: 18px; }
	/* Long Vietnamese headings have few break opportunities in a narrow card. */
	.hl-rail-toc a { overflow-wrap: anywhere; }
}
