/* ==========================================================================
   XPEL Indonesia — frontend design system
   Derived from public/redesign/project/XPEL.dc.html
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
    --x-bg: #ffffff;
    --x-ink: #111111;
    --x-ink-2: #555555;
    --x-ink-3: #666666;
    --x-line: rgba(17, 17, 17, 0.12);
    --x-line-2: rgba(17, 17, 17, 0.14);

    --x-accent: #ffb81c;
    --x-accent-deep: #c99000;

    --x-dark: #0f0f0f;
    --x-dark-2: #161616;
    --x-nav-bg: rgba(10, 10, 10, 0.92);

    /* Radius for media that does not run edge to edge. Full-bleed art (hero,
       page hero, product rooms on desktop) stays square. */
    --x-radius: 14px;
    --x-radius-sm: 10px;

    --x-shell: 1160px;
    --x-gutter: 48px;
    --x-section: 140px;
    --x-pill: 999px;

    --x-font: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
}

/* --------------------------------------------------------------------------
   2. Reset & base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--x-bg);
    color: var(--x-ink);
    font-family: var(--x-font);
    font-size: 15px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    overflow-x: hidden;
}

body.x-no-scroll {
    overflow: hidden;
}

a {
    color: var(--x-ink);
    text-decoration: none;
    transition: color 0.25s ease, background 0.25s ease, opacity 0.25s ease;
}

a:hover {
    color: var(--x-accent-deep);
}

img {
    max-width: 100%;
    display: block;
}

::selection {
    background: #111;
    color: var(--x-accent);
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.1;
    text-wrap: pretty;
}

p {
    margin: 0 0 18px;
}

p:last-child {
    margin-bottom: 0;
}

button {
    font: inherit;
    color: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.x-shell {
    max-width: var(--x-shell);
    margin: 0 auto;
    padding-left: var(--x-gutter);
    padding-right: var(--x-gutter);
}

.x-shell--wide {
    max-width: 1440px;
}

.x-section {
    padding-top: var(--x-section);
    padding-bottom: var(--x-section);
}

.x-section--tight {
    padding-top: 100px;
    padding-bottom: 100px;
}

.x-section--flush-top {
    padding-top: 0;
}

.x-section--flush-bottom {
    padding-bottom: 0;
}

/* The hero already carries 90px of its own bottom padding, so the first
   section after it does not need a full section gap on top of that.
   :not() keeps --flush-top sections at zero. */
.x-pagehero + .x-section:not(.x-section--flush-top) {
    padding-top: 80px;
}

.x-section--dark {
    background: var(--x-dark);
    color: #fff;
}

.x-section--dark a {
    color: #fff;
}

.x-section--dark a:hover {
    color: var(--x-accent);
}

/* Consecutive splits (e.g. the Coverage list) space themselves. */
.x-split + .x-split {
    margin-top: 110px;
}

/* Row gap is deliberately much larger than the column gap: a card's caption
   sits 16-22px under its own image, so a tight row gap made the caption of one
   row read as part of the row below it. The extra vertical air is what groups
   each image with its own label. */
.x-grid {
    display: grid;
    column-gap: 32px;
    row-gap: 56px;
}

.x-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.x-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.x-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* --------------------------------------------------------------------------
   4. Typography helpers
   -------------------------------------------------------------------------- */
.x-eyebrow {
    font-size: 11px;
    letter-spacing: 0.26em;
    color: var(--x-accent-deep);
    font-weight: 600;
    text-transform: uppercase;
    margin-bottom: 20px;
}

.x-eyebrow--light {
    color: rgba(255, 255, 255, 0.85);
}

.x-h1 {
    font-size: 64px;
    font-weight: 700;
    line-height: 1.04;
}

.x-h2 {
    margin: 0 0 22px;
    font-size: 44px;
    font-weight: 700;
    line-height: 1.1;
}

.x-h3 {
    margin: 0 0 24px;
    font-size: 30px;
    font-weight: 700;
    line-height: 1.16;
}

.x-h4 {
    margin: 0 0 18px;
    font-size: 20px;
    font-weight: 700;
    line-height: 1.25;
}

.x-lead {
    margin: 0 0 26px;
    font-size: 16px;
    line-height: 1.7;
    color: var(--x-ink-2);
}

.x-body {
    margin: 0 0 26px;
    font-size: 15px;
    line-height: 1.75;
    color: var(--x-ink-2);
}

/* These carry their own rhythm so pages never need inline margins. The
   last-child reset stops a trailing paragraph or list pushing extra space
   into the bottom of its container. */
.x-h2:last-child,
.x-h3:last-child,
.x-h4:last-child,
.x-lead:last-child,
.x-body:last-child,
.x-list:last-child {
    margin-bottom: 0;
}

/* Row of buttons closing a block of copy. */
.x-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    margin-top: 30px;
}

.x-muted {
    color: var(--x-ink-3);
}

.x-measure { max-width: 460px; }
.x-measure-sm { max-width: 420px; }

.x-center { text-align: center; }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.x-btn {
    display: inline-block;
    border-radius: var(--x-pill);
    padding: 13px 28px;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 0.01em;
    line-height: 1;
    text-align: center;
    border: 1px solid transparent;
    cursor: pointer;
    transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.x-btn--accent {
    background: var(--x-accent);
    color: var(--x-ink);
}

.x-btn--accent:hover {
    background: #fff;
    color: var(--x-ink);
    box-shadow: inset 0 0 0 1px var(--x-line-2);
}

.x-btn--dark {
    background: var(--x-ink);
    color: #fff;
}

.x-btn--dark:hover {
    background: var(--x-accent-deep);
    color: var(--x-ink);
}

.x-btn--light {
    background: #fff;
    color: var(--x-ink);
    font-weight: 600;
    padding: 12px 26px;
    font-size: 13px;
}

.x-btn--light:hover {
    background: var(--x-accent);
    color: var(--x-ink);
}

.x-btn--outline {
    background: transparent;
    color: var(--x-ink);
    border-color: var(--x-line-2);
    font-weight: 600;
}

.x-btn--outline:hover {
    background: var(--x-ink);
    color: #fff;
}

.x-btn--outline-light {
    background: transparent;
    color: #fff;
    border-color: rgba(255, 255, 255, 0.4);
    font-weight: 600;
}

.x-btn--outline-light:hover {
    background: #fff;
    color: var(--x-ink);
}

.x-btn--sm {
    padding: 11px 24px;
    font-size: 13px;
}

.x-btn--block {
    display: block;
    width: 100%;
}

/* text link with arrow */
/* "Lihat detail", "6 seri", "Baca artikel".
   These label a card that is *itself* the link, so they are an affordance cue
   rather than a link of their own — no underline. Colour carries it, and the
   trailing dash is a second cue that does not depend on seeing colour. Links
   sitting in running text are styled differently, further down. */
.x-link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--x-accent-deep);
}

/* The bright accent is unreadable on white but right on the dark panels. */
.x-section--dark .x-link,
.x-rooms .x-link {
    color: var(--x-accent);
}

/* Hovering brings the underline back. The card wrapping the label is the thing
   being pointed at, so the ancestor selectors matter more than .x-link:hover —
   the cue should appear anywhere on the card, not only over the words. */
.x-link:hover,
a:hover .x-link,
a:focus-visible .x-link {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
}

.x-link::after {
    content: '';
    width: 16px;
    height: 1px;
    background: currentColor;
    transition: width 0.25s ease;
}

.x-link:hover::after,
a:hover .x-link::after,
a:focus-visible .x-link::after {
    width: 26px;
}

/* --------------------------------------------------------------------------
   6. Top navigation
   -------------------------------------------------------------------------- */
.x-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 60;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 18px var(--x-gutter);
    background: transparent;
    transition: background 0.3s ease, box-shadow 0.3s ease, backdrop-filter 0.3s ease,
                transform 0.32s cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* Scrolling down mid-page on a phone parks the bar off-screen; scrolling up
   brings it straight back. Applied by the script, which only sets it below the
   burger breakpoint. */
.x-nav.is-hidden {
    transform: translateY(-100%);
}

.x-nav__logo {
    display: flex;
    align-items: center;
    flex: none;
}

.x-nav__logo img {
    height: 26px;
    width: auto;
}

.x-nav__menu {
    display: flex;
    gap: 32px;
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.02em;
}

.x-nav__menu a {
    color: #fff;
    position: relative;
    padding-bottom: 2px;
}

.x-nav__menu a:hover {
    color: rgba(255, 255, 255, 0.7);
}

.x-nav__menu a.is-active {
    color: var(--x-accent);
}

/* ---- Nav dropdown -------------------------------------------------------
   Hover and :focus-within only, so it works without JavaScript and stays
   reachable by keyboard. The panel is hidden with visibility rather than
   display so it can fade. */
.x-nav__group {
    position: relative;
    display: flex;
    align-items: center;
}

.x-nav__grouplink {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.x-nav__grouplink svg {
    transition: transform 0.25s ease;
}

.x-nav__group:hover .x-nav__grouplink svg,
.x-nav__group:focus-within .x-nav__grouplink svg {
    transform: rotate(180deg);
}

.x-nav__drop {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translate(-50%, 6px);
    min-width: 200px;
    /* Bridges the gap between the trigger and the panel so the pointer can
       travel down without the menu closing. */
    padding-top: 14px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.x-nav__group:hover .x-nav__drop,
.x-nav__group:focus-within .x-nav__drop {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

.x-nav__drop a {
    display: block;
    padding: 11px 18px;
    font-size: 13px;
    font-weight: 500;
    color: #fff;
    background: var(--x-nav-bg);
    backdrop-filter: saturate(180%) blur(14px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-bottom: 0;
    white-space: nowrap;
}

.x-nav__drop a:first-child { border-radius: 12px 12px 0 0; }

.x-nav__drop a:last-child {
    border-bottom: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 0 0 12px 12px;
}

.x-nav__drop a:hover {
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
}

.x-nav__drop a.is-active { color: var(--x-accent); }

.x-nav__cta {
    flex: none;
}

.x-nav.is-scrolled,
body:not(.x-has-hero) .x-nav {
    background: var(--x-nav-bg);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    box-shadow: 0 1px 0 rgba(255, 255, 255, 0.08);
}

/* burger */
.x-burger {
    display: none;
    width: 38px;
    height: 38px;
    border-radius: var(--x-pill);
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 5px;
    flex: none;
}

.x-burger span {
    display: block;
    width: 18px;
    height: 2px;
    background: #fff;
    transition: transform 0.25s ease, opacity 0.25s ease;
}

body.x-menu-open .x-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.x-menu-open .x-burger span:nth-child(2) { opacity: 0; }
body.x-menu-open .x-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* mobile drawer */
.x-drawer {
    position: fixed;
    inset: 0;
    z-index: 55;
    background: #0a0a0a;
    color: #fff;
    padding: 96px var(--x-gutter) 48px;
    display: flex;
    flex-direction: column;
    gap: 28px;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-12px);
    transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
    overflow-y: auto;
}

body.x-menu-open .x-drawer {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.x-drawer a {
    color: #fff;
}

.x-drawer__menu {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Sub-items in the drawer read as a grouped list under their parent label. */
.x-drawer__group {
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
    padding-bottom: 8px;
}

.x-drawer__grouplabel {
    font-size: 12px;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.45);
    padding: 18px 0 6px;
}

.x-drawer__menu .x-drawer__sublink {
    font-size: 24px;
    border-bottom: 0;
    padding: 6px 0 6px 16px;
}

.x-drawer__menu a {
    font-size: 32px;
    font-weight: 700;
    letter-spacing: -0.02em;
    padding: 8px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.x-drawer__menu a:hover,
.x-drawer__menu a.is-active {
    color: var(--x-accent);
}

.x-drawer__meta {
    font-size: 13px;
    color: rgba(255, 255, 255, 0.65);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

/* --------------------------------------------------------------------------
   7. Hero (home)
   -------------------------------------------------------------------------- */
.x-hero {
    position: relative;
    height: 100vh;
    min-height: 560px;
    overflow: hidden;
}

/* Banner carousel.
   The track is a real horizontal scroller with scroll snapping, so swiping on
   touch is the browser's own gesture — no drag handlers, no momentum to fake.
   JS only drives autoplay and keeps the dots in step. */
.x-hero__slides {
    position: absolute;
    inset: 0;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.x-hero__slides::-webkit-scrollbar {
    display: none;
}

/* Draggable on desktop, where there is no swipe gesture to rely on. */
.x-hero__slides {
    cursor: grab;
}

.x-hero__slides.is-dragging {
    cursor: grabbing;
    /* Snapping would fight the drag, pulling every frame back to the nearest
       slide; the script restores it and snaps once the pointer is released. */
    scroll-snap-type: none;
    scroll-behavior: auto;
}

.x-hero__slide img {
    user-select: none;
    -webkit-user-drag: none;
}

.x-hero__slide {
    position: relative;
    flex: 0 0 100%;
    height: 100%;
    scroll-snap-align: center;
    scroll-snap-stop: always;
}

.x-hero__slide img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Left-aligned with the hero copy rather than bottom-right: the fixed
   WhatsApp button owns that corner and would sit on top of them. */
.x-hero__dots {
    position: absolute;
    left: 56px;
    bottom: 26px;
    z-index: 3;
    display: flex;
    gap: 10px;
}

.x-hero__dot {
    width: 34px;
    height: 4px;
    padding: 0;
    border-radius: var(--x-pill);
    background: rgba(255, 255, 255, 0.35);
    transition: background 0.3s ease, width 0.3s ease;
}

.x-hero__dot.is-active {
    width: 52px;
    background: var(--x-accent);
}

.x-hero__dot:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 4px;
}

.x-hero__dim {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
        linear-gradient(to top, rgba(0, 0, 0, 0.82) 0%, rgba(0, 0, 0, 0.42) 42%, rgba(0, 0, 0, 0.12) 70%),
        linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 22%),
        rgba(0, 0, 0, 0.16);
}

/* Positioned against its own slide, so the copy scrolls with the image it
   belongs to. pointer-events stays off the block: the whole slide has to
   remain draggable, and only the CTA takes clicks. */
.x-hero__body {
    position: absolute;
    z-index: 2;
    left: 56px;
    right: 56px;
    bottom: 78px;
    color: #fff;
    pointer-events: none;
    max-width: 640px;
}

/* The page can only carry one <h1>, so every slide after the first renders its
   headline as a <p role="heading"> and shares the h1's styling here. */
.x-hero__body h1,
.x-hero__heading {
    margin: 0 0 14px;
    font-size: 64px;
    font-weight: 700;
    line-height: 1.04;
    letter-spacing: -0.02em;
    text-wrap: pretty;
}

/* :not() because the stand-in headline is a <p> too and must not pick up the
   body copy's size and colour. */
.x-hero__body p:not(.x-hero__heading) {
    margin: 0 0 26px;
    font-size: 16px;
    line-height: 1.6;
    color: rgba(255, 255, 255, 0.82);
    max-width: 460px;
}

.x-hero__body .x-btn {
    pointer-events: auto;
}

/* --------------------------------------------------------------------------
   8. Page hero (inner pages)
   -------------------------------------------------------------------------- */
.x-pagehero {
    position: relative;
    background: var(--x-dark);
    color: #fff;
    overflow: hidden;
    padding: 190px 0 90px;
}

.x-pagehero__media {
    position: absolute;
    inset: 0;
}

.x-pagehero__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.45;
}

.x-pagehero__media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.88) 0%, rgba(0, 0, 0, 0.52) 60%, rgba(0, 0, 0, 0.66) 100%);
}

.x-pagehero__inner {
    position: relative;
    z-index: 2;
    max-width: var(--x-shell);
    margin: 0 auto;
    /* Matches .x-shell so hero copy lines up with the body below it. */
    padding: 0 var(--x-gutter);
}

.x-pagehero h1 {
    margin: 0 0 16px;
    font-size: 56px;
    font-weight: 700;
}

.x-pagehero p {
    max-width: 520px;
    color: rgba(255, 255, 255, 0.78);
    font-size: 15px;
    line-height: 1.7;
}

.x-crumb {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin: 0 0 22px;
    padding: 0;
    font-size: 12px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
}

.x-crumb a {
    color: rgba(255, 255, 255, 0.6);
}

.x-crumb a:hover {
    color: var(--x-accent);
}

.x-crumb li + li::before {
    content: '/';
    margin-right: 10px;
    opacity: 0.5;
}

.x-crumb .is-active {
    color: var(--x-accent);
}

/* --------------------------------------------------------------------------
   9. Split intro (image + copy + stats)
   -------------------------------------------------------------------------- */
.x-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 88px;
    align-items: center;
}

.x-split--reverse .x-split__media {
    order: -1;
}

.x-split__media {
    position: relative;
    height: 560px;
    min-width: 0;
    overflow: hidden;
    border-radius: var(--x-radius);
}

.x-split__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.x-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 36px;
    border-top: 1px solid var(--x-line-2);
    padding-top: 24px;
}

.x-stats__n {
    font-size: 30px;
    font-weight: 700;
    line-height: 1.1;
}

.x-stats__l {
    font-size: 12px;
    color: var(--x-ink-3);
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   10. Product showcase (scroll-driven rooms)
   -------------------------------------------------------------------------- */
.x-rooms {
    position: relative;
    background: var(--x-dark);
}

.x-rooms__stage {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
}

.x-rooms__hud {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 10;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 92px 64px 0;
    pointer-events: none;
}

.x-rooms__hud .x-eyebrow {
    margin-bottom: 0;
    color: rgba(255, 255, 255, 0.85);
}

.x-rooms__count {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: rgba(255, 255, 255, 0.6);
}

.x-rooms__count b {
    color: var(--x-accent);
    font-weight: 600;
}

.x-rooms__track {
    position: absolute;
    left: 64px;
    bottom: 48px;
    z-index: 10;
    width: 220px;
    height: 2px;
    background: rgba(255, 255, 255, 0.28);
}

.x-rooms__bar {
    width: 100%;
    height: 100%;
    background: var(--x-accent);
    transform: scaleX(0);
    transform-origin: left;
}

.x-room {
    position: absolute;
    inset: 0;
    opacity: 0;
    pointer-events: none;
}

.x-room__text {
    position: absolute;
    left: 64px;
    bottom: 110px;
    max-width: 560px;
    z-index: 2;
    color: #fff;
}

.x-room__kicker {
    font-size: 11px;
    letter-spacing: 0.26em;
    color: rgba(255, 255, 255, 0.75);
    font-weight: 600;
    text-transform: uppercase;
    margin-bottom: 14px;
}

.x-room__text h3 {
    margin: 0 0 18px;
    font-size: 74px;
    font-weight: 800;
    line-height: 0.95;
    text-transform: uppercase;
}

.x-room__text p {
    margin: 0 0 28px;
    font-size: 15px;
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.85);
    max-width: 420px;
}

.x-room__specs {
    display: flex;
    flex-wrap: wrap;
    gap: 28px;
    font-size: 13px;
    color: #fff;
    border-top: 1px solid rgba(255, 255, 255, 0.35);
    padding-top: 18px;
    margin-bottom: 30px;
}

.x-room__img {
    position: absolute;
    inset: 0;
    overflow: hidden;
}

.x-room__parallax {
    position: absolute;
    inset: -70px 0;
}

.x-room__parallax img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.x-room__scrim {
    position: absolute;
    inset: 0;
    pointer-events: none;
    background:
        linear-gradient(to top, rgba(0, 0, 0, 0.86) 0%, rgba(0, 0, 0, 0.46) 46%, rgba(0, 0, 0, 0.06) 72%),
        rgba(0, 0, 0, 0.14);
}

/* --------------------------------------------------------------------------
   11. Coverage / card tiles
   -------------------------------------------------------------------------- */
.x-sechead {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 40px;
    margin-bottom: 44px;
}

.x-sechead__aside {
    font-size: 13px;
    color: var(--x-ink-3);
    max-width: 280px;
    line-height: 1.6;
    text-align: right;
}

.x-tile__media {
    position: relative;
    height: 380px;
    min-width: 0;
    overflow: hidden;
    display: block;
    border-radius: var(--x-radius);
}

/* Shorter tiles used in the "related" and coverage strips. */
.x-tile__media--md { height: 300px; }
.x-tile__media--sm { height: 260px; }

.x-tile__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.x-tile:hover .x-tile__media img {
    transform: scale(1.06);
}

.x-tile__foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    padding: 16px 2px 0;
    font-size: 14px;
    font-weight: 600;
}

.x-tile__foot span:last-child {
    color: var(--x-ink-3);
    font-weight: 400;
}

/* editorial card (services, blog) */
.x-card {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.x-card__media {
    position: relative;
    height: 260px;
    overflow: hidden;
    border-radius: var(--x-radius);
}

.x-card__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.x-card:hover .x-card__media img {
    transform: scale(1.06);
}

.x-card__body {
    padding: 22px 2px 0;
    flex: 1;
    display: flex;
    flex-direction: column;
}

.x-card__meta {
    font-size: 11px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--x-ink-3);
    margin-bottom: 12px;
}

.x-card__body h3 {
    font-size: 22px;
    margin: 0 0 10px;
}

.x-card__body p {
    font-size: 14px;
    line-height: 1.7;
    color: var(--x-ink-2);
}

/* A product with no description still renders its <p>, and the base paragraph
   margin then spaced the card as though there were copy in it. */
.x-card__body p:empty {
    display: none;
}

/* margin-top:auto lines every card's link up along the bottom of a grid row,
   which is what makes a row of cards read as one row. */
.x-card__foot {
    margin-top: auto;
    padding-top: 14px;
}

/* numbered feature list */
.x-feature {
    border-top: 1px solid var(--x-line);
    padding: 28px 0;
    display: grid;
    grid-template-columns: 64px 1fr;
    gap: 24px;
    align-items: start;
}

.x-feature__n {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.1em;
    color: var(--x-accent-deep);
    padding-top: 4px;
}

.x-feature h4 {
    font-size: 20px;
    margin: 0 0 8px;
}

.x-feature p {
    font-size: 14px;
    line-height: 1.7;
    color: var(--x-ink-2);
    max-width: 640px;
}

/* check list */
.x-list {
    list-style: none;
    margin: 0 0 30px;
    padding: 0;
    display: grid;
    gap: 12px;
    font-size: 14px;
    line-height: 1.6;
    color: var(--x-ink-2);
}

.x-list li {
    position: relative;
    padding-left: 26px;
}

.x-list li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 8px;
    width: 12px;
    height: 6px;
    border-left: 1.5px solid var(--x-accent-deep);
    border-bottom: 1.5px solid var(--x-accent-deep);
    transform: rotate(-45deg);
}

/* spec table */
.x-spec {
    margin: 0;
    border-top: 1px solid var(--x-line);
}

.x-spec > div {
    display: flex;
    justify-content: space-between;
    gap: 16px;
    padding: 12px 0;
    border-bottom: 1px solid var(--x-line);
    font-size: 14px;
}

.x-spec dt {
    color: var(--x-ink-3);
}

.x-spec dd {
    margin: 0;
    font-weight: 600;
    text-align: right;
}

/* variant comparison matrix — one column per variant, one row per parameter */
.x-matrix {
    overflow-x: auto;
    border-top: 1px solid var(--x-line);
}

.x-matrix table {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    font-size: 14px;
}

.x-matrix th,
.x-matrix td {
    padding: 14px 18px 14px 0;
    text-align: left;
    border-bottom: 1px solid var(--x-line);
    vertical-align: top;
}

.x-matrix thead th {
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--x-ink-3);
}

.x-matrix tbody th {
    font-weight: 500;
    color: var(--x-ink-3);
    white-space: nowrap;
}

.x-matrix tbody td {
    font-weight: 600;
    color: var(--x-ink);
}

/* colour / finish swatches on a series page */
.x-swatches {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.x-swatches span {
    padding: 9px 16px;
    border: 1px solid var(--x-line-2);
    border-radius: var(--x-pill);
    font-size: 13px;
    font-weight: 600;
}

/* dark-section overrides for tiles and headings */
.x-section--dark .x-tile__foot,
.x-section--dark .x-card__body h3 {
    color: #fff;
}

.x-section--dark .x-tile__foot span:last-child,
.x-section--dark .x-card__meta,
.x-section--dark .x-card__body p,
.x-section--dark .x-sechead__aside {
    color: rgba(255, 255, 255, 0.6);
}

.x-section--dark .x-list,
.x-section--dark .x-body,
.x-section--dark .x-lead {
    color: rgba(255, 255, 255, 0.78);
}

.x-section--dark .x-stats,
.x-section--dark .x-feature,
.x-section--dark .x-info {
    border-color: rgba(255, 255, 255, 0.18);
}

/* --------------------------------------------------------------------------
   12. CTA band
   -------------------------------------------------------------------------- */
/* Accent yellow, matching the .x-strip band used on Coverage. Every CTA on
   the site reads the same way: yellow field, dark pill button. */
.x-cta {
    background: var(--x-accent);
    color: var(--x-ink);
    padding: 110px var(--x-gutter);
    text-align: center;
}

.x-cta h2 {
    margin: 0 auto 18px;
    font-size: 46px;
    font-weight: 700;
    line-height: 1.12;
    max-width: 640px;
}

.x-cta p {
    /* Deeper than --x-ink-3: mid grey does not carry enough contrast on yellow. */
    margin: 0 auto 32px;
    max-width: 620px;
    font-size: 14px;
    color: rgba(17, 17, 17, 0.72);
}

.x-cta--dark {
    background: var(--x-dark);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.12);
}

.x-cta--dark p {
    color: rgba(255, 255, 255, 0.7);
}

/* accent strip */
.x-strip {
    background: var(--x-accent);
    color: var(--x-ink);
    padding: 54px 0;
}

.x-strip__inner {
    max-width: var(--x-shell);
    margin: 0 auto;
    padding: 0 var(--x-gutter);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
    flex-wrap: wrap;
}

.x-strip h3 {
    font-size: 32px;
    margin: 0;
    max-width: 720px;
}

/* --------------------------------------------------------------------------
   13. Marquee (brand logos)
   -------------------------------------------------------------------------- */
.x-marquee {
    overflow: hidden;
    border-top: 1px solid var(--x-line);
    border-bottom: 1px solid var(--x-line);
    padding: 34px 0;
}

.x-marquee__track {
    display: flex;
    align-items: center;
    width: max-content;
    animation: x-marquee 42s linear infinite;
}

/* two identical groups keep the -50% loop seamless */
.x-marquee__group {
    display: flex;
    align-items: center;
    gap: 72px;
    padding-right: 72px;
}

.x-marquee img {
    height: 34px;
    width: auto;
    opacity: 0.4;
    filter: grayscale(1);
    transition: opacity 0.25s ease, filter 0.25s ease;
}

.x-marquee img:hover {
    opacity: 1;
    filter: none;
}

@keyframes x-marquee {
    from { transform: translateX(0); }
    to { transform: translateX(-50%); }
}

/* --------------------------------------------------------------------------
   14. Accordion (FAQ)
   -------------------------------------------------------------------------- */

/* Illustration under the heading in the left column of the FAQ split. Keeps
   the photo's own 1500x818 ratio so nothing is cropped; the width/height
   attributes on the img reserve the space and avoid layout shift. */
.x-faq__media {
    margin-top: 44px;
    overflow: hidden;
    border-radius: var(--x-radius);
}

.x-faq__media img {
    display: block;
    width: 100%;
    height: auto;
}

.x-acc__item {
    border-top: 1px solid var(--x-line);
}

.x-acc__item:last-child {
    border-bottom: 1px solid var(--x-line);
}

.x-acc__head {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    padding: 24px 0;
    text-align: left;
    font-size: 17px;
    font-weight: 600;
    letter-spacing: -0.01em;
}

.x-acc__head:hover {
    color: var(--x-accent-deep);
}

.x-acc__sign {
    flex: none;
    width: 18px;
    height: 18px;
    position: relative;
}

.x-acc__sign::before,
.x-acc__sign::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    background: currentColor;
    transform: translate(-50%, -50%);
    transition: transform 0.3s ease, opacity 0.3s ease;
}

.x-acc__sign::before { width: 14px; height: 1.5px; }
.x-acc__sign::after { width: 1.5px; height: 14px; }

.x-acc__item.is-open .x-acc__sign::after {
    transform: translate(-50%, -50%) rotate(90deg);
    opacity: 0;
}

.x-acc__panel {
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.35s ease;
}

.x-acc__panel > div {
    padding: 0 0 26px;
    font-size: 14px;
    line-height: 1.75;
    color: var(--x-ink-2);
    max-width: 720px;
}

/* --------------------------------------------------------------------------
   15. Forms
   -------------------------------------------------------------------------- */
.x-form {
    display: grid;
    gap: 18px;
}

.x-field label {
    display: block;
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--x-ink-3);
    margin-bottom: 8px;
}

.x-input,
.x-select,
.x-textarea {
    width: 100%;
    background-color: #fff;
    border: 1px solid var(--x-line-2);
    border-radius: 2px;
    padding: 14px 16px;
    font-family: inherit;
    font-size: 14px;
    color: var(--x-ink);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.x-textarea {
    min-height: 150px;
    resize: vertical;
}

.x-select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23111' stroke-width='1.5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 16px center;
    padding-right: 42px;
}

.x-input:focus,
.x-select:focus,
.x-textarea:focus {
    outline: none;
    border-color: var(--x-ink);
    box-shadow: 0 0 0 3px rgba(255, 184, 28, 0.25);
}

.x-input::placeholder,
.x-textarea::placeholder {
    color: #9a9a9a;
}

.x-form__row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}

.x-form__row--3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.x-panel {
    border: 1px solid var(--x-line);
    padding: 44px;
}

.x-panel--dark {
    background: var(--x-dark);
    color: #fff;
    border-color: rgba(255, 255, 255, 0.12);
}

/* background-color, not the `background` shorthand: the shorthand would reset
   background-repeat/position, tiling the select's chevron across the field. */
.x-panel--dark .x-input,
.x-panel--dark .x-select,
.x-panel--dark .x-textarea {
    background-color: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.18);
    color: #fff;
}

.x-panel--dark .x-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%23fff' stroke-width='1.5'/%3E%3C/svg%3E");
}

/* The native dropdown popup keeps its light background, so options must not
   inherit the white text colour set on the select itself. */
.x-panel--dark .x-select option {
    background-color: #fff;
    color: var(--x-ink);
}

.x-panel--dark .x-input:focus,
.x-panel--dark .x-select:focus,
.x-panel--dark .x-textarea:focus {
    border-color: var(--x-accent);
}

.x-panel--dark label {
    color: rgba(255, 255, 255, 0.6);
}

.x-note {
    display: none;
    padding: 16px 18px;
    font-size: 14px;
    border-radius: 2px;
}

.x-note.is-visible {
    display: block;
}

.x-note--ok {
    background: rgba(255, 184, 28, 0.16);
    border: 1px solid var(--x-accent);
    color: var(--x-ink);
}

.x-panel--dark .x-note--ok {
    color: #fff;
}

.x-note--err {
    background: rgba(200, 40, 40, 0.1);
    border: 1px solid rgba(200, 40, 40, 0.5);
}

/* --------------------------------------------------------------------------
   16. Contact / info blocks
   -------------------------------------------------------------------------- */
.x-info {
    border-top: 1px solid var(--x-line);
    padding-top: 22px;
}

.x-info h4 {
    font-size: 18px;
    margin: 0 0 12px;
}

.x-info dl {
    margin: 0;
    display: grid;
    gap: 8px;
    font-size: 14px;
    color: var(--x-ink-2);
}

.x-info dt {
    font-size: 11px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--x-ink-3);
}

.x-info dd {
    margin: 0 0 6px;
}

/* --------------------------------------------------------------------------
   17. Gallery
   -------------------------------------------------------------------------- */
.x-filters {
    list-style: none;
    margin: 0 0 40px;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.x-filters button {
    border: 1px solid var(--x-line-2);
    border-radius: var(--x-pill);
    padding: 9px 20px;
    font-size: 13px;
    font-weight: 600;
    transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.x-filters button:hover {
    border-color: var(--x-ink);
}

.x-filters button.is-active {
    background: var(--x-ink);
    color: #fff;
    border-color: var(--x-ink);
}

.x-gallery {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 24px;
}

.x-gallery__item {
    position: relative;
    display: block;
    overflow: hidden;
    height: 300px;
    border-radius: var(--x-radius);
}

.x-gallery__item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.x-gallery__item::after {
    content: 'View';
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.x-gallery__item:hover::after {
    opacity: 1;
}

.x-gallery__item:hover img {
    transform: scale(1.06);
}

.x-gallery__item.is-hidden {
    display: none;
}

/* lightbox */
.x-lightbox {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(8, 8, 8, 0.94);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 48px;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.3s ease, visibility 0.3s;
}

.x-lightbox.is-open {
    opacity: 1;
    visibility: visible;
}

.x-lightbox img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: var(--x-radius);
}

.x-lightbox__close {
    position: absolute;
    top: 24px;
    right: 32px;
    color: #fff;
    font-size: 28px;
    line-height: 1;
}

/* --------------------------------------------------------------------------
   18. Article (blog detail)
   -------------------------------------------------------------------------- */
.x-article {
    max-width: 720px;
    margin: 0 auto;
    font-size: 16px;
    line-height: 1.8;
    color: #333;
}

/* Blog detail sizes to its content instead of the 720px reading measure the
   product and coverage pages keep. */
.x-article--wide {
    max-width: max-content;
}

/* Article bodies come from the editor, so any link inside one is whatever the
   author pasted. Without a rule these inherited the body's ink colour and were
   indistinguishable from the copy around them — invisible links. Prose is the
   one place both cues are warranted: the text beside them is not clickable,
   and colour alone would leave nothing for a reader who cannot separate amber
   from black. */
.x-article a {
    color: var(--x-accent-deep);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

.x-article a:hover,
.x-article a:focus-visible {
    color: var(--x-ink);
    text-decoration-thickness: 2px;
}

.x-article h2 {
    font-size: 30px;
    margin: 44px 0 16px;
}

.x-article h3 {
    font-size: 22px;
    margin: 34px 0 12px;
}

.x-article ul,
.x-article ol {
    padding-left: 20px;
    margin: 0 0 20px;
}

.x-article li {
    margin-bottom: 8px;
}

.x-article blockquote {
    margin: 34px 0;
    padding: 4px 0 4px 26px;
    border-left: 2px solid var(--x-accent);
    font-size: 20px;
    line-height: 1.5;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: var(--x-ink);
}

.x-article figure {
    margin: 34px 0;
}

.x-article figcaption {
    font-size: 12px;
    color: var(--x-ink-3);
    margin-top: 10px;
}

/* --------------------------------------------------------------------------
   19. Footer
   -------------------------------------------------------------------------- */
.x-footer {
    padding: 90px 0 24px;
}

.x-footer__grid {
    max-width: var(--x-shell);
    margin: 0 auto;
    padding: 0 var(--x-gutter);
    display: grid;
    grid-template-columns: 1.3fr 1fr 1fr 1fr;
    gap: 48px;
    padding-bottom: 90px;
}

.x-footer__brand img {
    height: 44px;
    width: auto;
    margin-bottom: 20px;
}

.x-footer__brand p {
    margin: 0;
    font-size: 13px;
    line-height: 1.7;
    color: var(--x-ink-3);
    max-width: 260px;
}

.x-footer__col {
    display: flex;
    flex-direction: column;
    gap: 12px;
    font-size: 13px;
}

.x-footer__title {
    font-size: 11px;
    letter-spacing: 0.22em;
    color: var(--x-ink-3);
    margin-bottom: 4px;
    text-transform: uppercase;
}

.x-footer__col span {
    color: var(--x-ink-3);
}

.x-subfooter {
    max-width: var(--x-shell);
    margin: 0 auto;
    border-top: 1px solid var(--x-line);
    padding: 24px var(--x-gutter) 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    flex-wrap: wrap;
    font-size: 12px;
    color: var(--x-ink-3);
}

.x-subfooter ul {
    list-style: none;
    display: flex;
    gap: 20px;
    margin: 0;
    padding: 0;
}

.x-subfooter a {
    color: var(--x-ink-3);
}

/* --------------------------------------------------------------------------
   20. Back to top
   -------------------------------------------------------------------------- */
.x-top {
    position: fixed;
    right: 28px;
    /* Sits above the WhatsApp button, which owns the bottom-right corner. */
    bottom: 92px;
    z-index: 45;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: var(--x-ink);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transform: translateY(8px);
    transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s, background 0.25s ease;
}

.x-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none;
}

.x-top:hover {
    background: var(--x-accent);
    color: var(--x-ink);
}

/* --------------------------------------------------------------------------
   21. Reveal on scroll
   -------------------------------------------------------------------------- */
.x-reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity 0.7s cubic-bezier(0.2, 0.7, 0.3, 1), transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1);
}

.x-reveal.is-in {
    opacity: 1;
    transform: none;
}

/* --------------------------------------------------------------------------
   22. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1180px) {
    :root {
        --x-gutter: 36px;
        --x-section: 110px;
    }

    .x-split { gap: 56px; }
    .x-hero__body { left: 36px; right: 36px; bottom: 66px; }
    .x-hero__dots { left: 36px; }
    .x-rooms__hud { padding: 84px 36px 0; }
    .x-room__text { left: 36px; }
    .x-rooms__track { left: 36px; }
}

@media (max-width: 1024px) {
    .x-h1, .x-hero__body h1, .x-hero__heading { font-size: 48px; }
    .x-h2, .x-cta h2 { font-size: 36px; }
    .x-pagehero h1 { font-size: 42px; }
    .x-room__text h3 { font-size: 54px; }
    .x-footer__grid { grid-template-columns: 1fr 1fr; gap: 40px; }
}

@media (max-width: 900px) {
    .x-nav__menu,
    .x-nav__cta {
        display: none;
    }

    .x-burger {
        display: flex;
    }

    .x-split {
        grid-template-columns: 1fr;
        gap: 40px;
    }

    .x-split--reverse .x-split__media {
        order: 0;
    }

    .x-split__media {
        height: 360px;
    }

    /* The split has collapsed to one column, so the FAQ photo now sits between
       the heading and the questions. Cap its height so it stays a supporting
       image instead of pushing the accordion off the first screen; the crop is
       anchored to the top because the technician is in the upper half. */
    .x-faq__media {
        margin-top: 28px;
        height: clamp(180px, 40vw, 300px);
    }

    .x-faq__media img {
        height: 100%;
        object-fit: cover;
        object-position: center top;
    }

    .x-grid--3,
    .x-grid--4,
    .x-gallery {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .x-sechead {
        flex-direction: column;
        align-items: flex-start;
        gap: 20px;
    }

    .x-sechead__aside {
        text-align: left;
        max-width: 100%;
    }

    /* Product showcase keeps the desktop cross-fade — the panels stay pinned
       and dissolve into each other as you scroll, rather than becoming a
       side-scrolling deck. Only the framing changes: the copy runs to the
       gutter, and the JS shortens the scroll each panel occupies so seven
       products do not cost nine screens of thumb work. */
    .x-rooms__hud {
        padding: 78px var(--x-gutter) 0;
    }

    /* Full width at this size, and lifted clear of the fixed WhatsApp button,
       which owns the bottom-right corner and would otherwise sit on top of the
       bar's right end. */
    .x-rooms__track {
        left: var(--x-gutter);
        right: var(--x-gutter);
        width: auto;
        bottom: 72px;
    }

    .x-room__text {
        left: var(--x-gutter);
        right: var(--x-gutter);
        bottom: 88px;
        max-width: none;
    }

    .x-room__text h3 {
        font-size: 44px;
    }

}

@media (max-width: 700px) {
    :root {
        --x-gutter: 22px;
        --x-section: 80px;
    }

    body { font-size: 14px; }

    .x-hero { height: 92vh; }
    .x-hero__body h1, .x-hero__heading { font-size: 38px; }
    .x-hero__body p:not(.x-hero__heading) { font-size: 15px; }

    /* Both hang off --x-gutter so the dots stay flush with the headline above
       them. The copy used to keep the 36px inset from the 1180px breakpoint
       while the dots moved in to the 22px gutter, leaving them 14px adrift. */
    .x-hero__body { left: var(--x-gutter); right: var(--x-gutter); bottom: 70px; }
    .x-hero__dots { left: var(--x-gutter); bottom: 26px; }

    .x-pagehero { padding: 150px 0 64px; }
    .x-pagehero + .x-section:not(.x-section--flush-top) { padding-top: 52px; }
    .x-pagehero h1 { font-size: 34px; }

    .x-h2, .x-cta h2 { font-size: 30px; }
    .x-h3 { font-size: 24px; }

    .x-grid--2,
    .x-grid--3,
    .x-grid--4,
    .x-form__row,
    .x-form__row--3 {
        grid-template-columns: 1fr;
    }

    /* Card and tile grids become swipe decks.
       One card per screen at this width turned every listing into a very long
       column; a snapping horizontal track shows the same cards a flick apart.
       The negative margin lets the track bleed to the screen edge while the
       padding keeps the first and last card lined up with the page gutter, and
       the 84% width leaves the next card peeking so the gesture is discoverable.
       It is a real scroller, so it still works with JS off. */
    .x-grid--swipe {
        display: flex;
        gap: 16px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        overscroll-behavior-x: contain;
        margin-left: calc(var(--x-gutter) * -1);
        margin-right: calc(var(--x-gutter) * -1);
        padding: 0 var(--x-gutter) 4px;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }

    .x-grid--swipe::-webkit-scrollbar {
        display: none;
    }

    .x-grid--swipe > * {
        flex: 0 0 84%;
        scroll-snap-align: center;
    }

    /* .x-card sets height:100%, which resolves to its own content in an
       auto-height flex row and leaves the deck ragged. Handing the height back
       to the flex container lets stretch even the cards out again. */
    .x-grid--swipe > .x-card {
        height: auto;
    }

    /* Descriptions vary from one line to six, and in a deck that difference
       becomes the height of every card. Three lines is enough of a taste. */
    .x-grid--swipe .x-card__body p {
        display: -webkit-box;
        -webkit-line-clamp: 3;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }

    /* But in a deck you only ever see one card, so there is no row for the
       links to line up along — the auto margin just dropped "Lihat detail" to
       the bottom of the tallest card, up to 100px below its own text. */
    .x-grid--swipe .x-card__foot {
        margin-top: 0;
    }

    /* Full-height media inside a swipe deck eats the screen; trim it so the
       caption under each card stays visible without scrolling. */
    .x-grid--swipe .x-tile__media,
    .x-grid--swipe .x-tile__media--md,
    .x-grid--swipe .x-tile__media--sm {
        height: 230px;
    }

    .x-grid--swipe .x-card__media {
        height: 210px;
    }

    /* The gallery keeps its grid — a swipe deck of dozens of photos would be
       worse than a two-up wall — but drops to two columns so the page is not a
       single tall column of 300px images. */
    .x-gallery {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 12px;
    }

    .x-gallery__item {
        height: 180px;
    }

    .x-grid { row-gap: 40px; }

    .x-stats { gap: 24px; }
    .x-stats__n { font-size: 24px; }

    .x-panel { padding: 26px; }
    .x-cta { padding: 70px var(--x-gutter); }
    .x-strip h3 { font-size: 24px; }

    .x-room { min-height: 460px; }
    .x-room__text h3 { font-size: 34px; }
    .x-room__specs { gap: 16px; font-size: 12px; }

    .x-footer { padding: 60px 0 24px; }
    .x-footer__grid { grid-template-columns: 1fr; gap: 32px; padding-bottom: 48px; }
    .x-drawer__menu a { font-size: 26px; }
    .x-feature { grid-template-columns: 1fr; gap: 8px; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    /* The bar still gets out of the way, it just does not slide there. */
    .x-nav { transition: none; }

    .x-reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }

    .x-marquee__track {
        animation: none;
    }
}

/* --------------------------------------------------------------------------
   22. Blog — filters, featured post, pagination, comments
   -------------------------------------------------------------------------- */
.x-blogfilter {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.x-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    border: 1px solid var(--x-line-2);
    border-radius: var(--x-pill);
    padding: 9px 20px;
    font-size: 13px;
    font-weight: 600;
    color: var(--x-ink);
    transition: background 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.x-chip span {
    font-size: 11px;
    color: var(--x-ink-3);
}

.x-chip:hover {
    border-color: var(--x-ink);
    color: var(--x-ink);
}

.x-chip.is-active {
    background: var(--x-ink);
    border-color: var(--x-ink);
    color: #fff;
}

.x-chip.is-active span {
    color: rgba(255, 255, 255, 0.6);
}

.x-blogsearch {
    display: flex;
    gap: 10px;
    align-items: center;
}

.x-blogsearch input {
    border: 1px solid var(--x-line-2);
    border-radius: var(--x-pill);
    padding: 10px 20px;
    font-size: 14px;
    font-family: inherit;
    min-width: 240px;
    background: transparent;
    color: var(--x-ink);
}

.x-blogsearch input:focus {
    outline: none;
    border-color: var(--x-ink);
}

/* Featured article card at the top of the listing. */
.x-hero-post {
    display: grid;
    grid-template-columns: 1.15fr 1fr;
    gap: 0;
    border: 1px solid var(--x-line);
    border-radius: var(--x-radius);
    overflow: hidden;
    margin-bottom: 48px;
    background: #fff;
}

.x-hero-post__media {
    aspect-ratio: 16 / 10;
    overflow: hidden;
}

.x-hero-post__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s ease;
}

.x-hero-post:hover .x-hero-post__media img {
    transform: scale(1.04);
}

.x-hero-post__body {
    padding: 44px 44px 40px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 14px;
}

.x-hero-post__body h2 {
    font-size: 30px;
    line-height: 1.2;
    letter-spacing: -0.02em;
}

.x-hero-post__body p {
    color: var(--x-ink-2);
    font-size: 15px;
    line-height: 1.7;
}

.x-empty {
    border: 1px dashed var(--x-line-2);
    border-radius: 4px;
    padding: 64px 32px;
    text-align: center;
}

.x-empty h3 {
    font-size: 20px;
    margin-bottom: 8px;
}

.x-empty p {
    color: var(--x-ink-3);
    font-size: 15px;
}

.x-pagination {
    margin-top: 56px;
    display: flex;
    justify-content: center;
}

.x-pager {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.x-pager__link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    padding: 0 14px;
    border: 1px solid var(--x-line-2);
    border-radius: var(--x-pill);
    font-size: 13px;
    font-weight: 600;
    color: var(--x-ink);
}

.x-pager__link:hover {
    border-color: var(--x-ink);
}

.x-pager__link.is-active {
    background: var(--x-ink);
    border-color: var(--x-ink);
    color: #fff;
}

.x-pager__link.is-disabled {
    opacity: 0.4;
    cursor: default;
}

.x-pager__gap {
    padding: 0 4px;
    color: var(--x-ink-3);
}

/* Simple stacked form — used by the password prompt on protected articles. */
.x-stackform {
    display: flex;
    flex-direction: column;
    gap: 14px;
    max-width: 760px;
    margin-top: 40px;
}

.x-stackform input,
.x-stackform textarea {
    width: 100%;
    border: 1px solid var(--x-line-2);
    border-radius: 2px;
    padding: 13px 16px;
    font-size: 14px;
    font-family: inherit;
    background: transparent;
    color: var(--x-ink);
}

.x-stackform input:focus,
.x-stackform textarea:focus {
    outline: none;
    border-color: var(--x-ink);
}

.x-stackform button {
    align-self: flex-start;
}

@media (max-width: 860px) {
    .x-hero-post { grid-template-columns: 1fr; }
    .x-hero-post__body { padding: 28px 24px 32px; }
    .x-hero-post__body h2 { font-size: 24px; }
    .x-blogsearch input { min-width: 0; flex: 1; }
}

/* --------------------------------------------------------------------------
   Legal pages — Syarat & Ketentuan, Kebijakan Pengembalian
   Long documents, so the section list stays pinned beside the body on desktop
   and collapses above it on narrow screens.
   -------------------------------------------------------------------------- */
.x-legal {
    display: grid;
    grid-template-columns: 250px minmax(0, 1fr);
    gap: 64px;
    align-items: start;
}

.x-legal__toc {
    position: sticky;
    top: 110px;
    max-height: calc(100vh - 150px);
    overflow-y: auto;
    padding-right: 6px;
}

.x-legal__toc-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--x-ink-3);
    margin-bottom: 14px;
}

.x-legal__toc nav {
    border-left: 1px solid var(--x-line);
}

.x-legal__toc a {
    display: block;
    padding: 7px 0 7px 16px;
    margin-left: -1px;
    border-left: 2px solid transparent;
    font-size: 13px;
    line-height: 1.45;
    color: var(--x-ink-3);
    text-decoration: none;
}

.x-legal__toc a:hover,
.x-legal__toc a:focus-visible {
    color: var(--x-ink);
    border-left-color: var(--x-accent);
}

/* .x-article centres itself on a 720px measure; inside the grid it should sit
   flush against the section list instead. */
.x-legal__body {
    margin: 0;
    max-width: 760px;
}

.x-legal__body h2,
.x-legal__body h3 {
    scroll-margin-top: 110px;
}

.x-legal__body h2 {
    font-size: 26px;
    margin: 52px 0 14px;
}

.x-legal__body h2:first-child {
    margin-top: 0;
}

.x-legal__body h3 {
    font-size: 18px;
    margin: 30px 0 10px;
}

.x-legal__body p {
    margin: 0 0 18px;
}

/* Effective / last-updated stamp and the closing contact block. */
.x-legal__stamp {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 28px;
    padding: 18px 22px;
    margin-bottom: 40px;
    border: 1px solid var(--x-line);
    border-radius: 3px;
    font-size: 13px;
    color: var(--x-ink-3);
}

.x-legal__stamp strong {
    color: var(--x-ink);
    font-weight: 600;
}

.x-legal__card {
    margin-top: 44px;
    padding: 26px 28px;
    background: #f7f7f7;
    border-radius: 3px;
    font-size: 14px;
    line-height: 1.7;
}

.x-legal__card p {
    margin: 0 0 4px;
}

.x-legal__card a {
    color: var(--x-accent-deep);
    font-weight: 600;
}

@media (max-width: 1024px) {
    .x-legal {
        grid-template-columns: 1fr;
        gap: 36px;
    }

    .x-legal__toc {
        position: static;
        max-height: none;
        overflow: visible;
    }

    .x-legal__toc nav {
        columns: 2;
        column-gap: 28px;
    }
}

@media (max-width: 700px) {
    .x-legal__toc nav {
        columns: 1;
    }

    .x-legal__body h2 {
        font-size: 22px;
        margin: 40px 0 12px;
    }
}

/* --------------------------------------------------------------------------
   Public form feedback — validation summary and the spam honeypot
   -------------------------------------------------------------------------- */

/* .x-note--err inherits its colour, which on the dark form panels would put
   near-white text on a pale red ground. Pin both cases explicitly. */
.x-note--err {
    color: #7d1d1d;
}

.x-panel--dark .x-note--err {
    background: rgba(255, 120, 120, 0.14);
    border-color: rgba(255, 140, 140, 0.55);
    color: #ffd9d9;
}

.x-note--err ul {
    margin: 8px 0 0;
    padding-left: 18px;
}

.x-note--err li {
    margin-top: 4px;
}

.x-field__error {
    display: block;
    margin-top: 6px;
    font-size: 12px;
    color: #d05a5a;
}

.x-input.is-invalid,
.x-select.is-invalid,
.x-textarea.is-invalid {
    border-color: rgba(220, 90, 90, 0.8);
}

/* Honeypot: off-screen rather than display:none, because some bots skip
   hidden inputs. People never see or tab into it. */
.x-hp {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Coverage listing links
   -------------------------------------------------------------------------- */

/* Each part of a coverage row points somewhere different: the heading and the
   photo open that coverage's product list, while each product in the checklist
   opens its own page. That rules out wrapping the row in a single <a>, so the
   pieces are linked individually — and each now says so at rest rather than
   only on hover, which a touch screen never delivers.

   There was a blanket `.x-split--linked a { text-decoration: none }` here. It
   outranked the per-link rules below on specificity and silently swallowed
   their underlines, so it is gone; the global `a` reset still covers the
   photo link, which has no text to underline anyway. */

/* Heading link — inherits the heading's size and colour. */
/* A linked heading, left as a plain heading. It does not have to advertise
   itself: the row's product list underneath and its "Jelajahi …" button both
   lead to the same page, so the heading is a shortcut rather than the only
   way in. */
.x-covlink {
    color: inherit;
    text-decoration: none;
    transition: color 0.25s ease;
}

.x-covlink:hover,
.x-covlink:focus-visible {
    color: var(--x-accent-deep);
}

/* Product checklist. The tick marker belongs to the <li>, so the <a> fills the
   row beside it rather than replacing it. */
/* Same treatment as the card labels: colour marks them as clickable at rest,
   the underline arrives on hover. */
.x-list--linked a {
    display: inline-block;
    color: var(--x-accent-deep);
    text-decoration: none;
    transition: color 0.25s ease;

    /* The text alone gives a 22px tall target; WCAG 2.2 asks for 24px. The
       padding buys the extra height without changing how the row looks. */
    padding: 3px 0;
}

/* Keep the tick lined up with the text after that padding. */
.x-list--linked li::before {
    top: 11px;
}

.x-list--linked a:hover,
.x-list--linked a:focus-visible {
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
}

/* Photo link. .x-split__media already sets position/height/overflow, so this
   only needs to make the anchor behave like the div it replaced. */
.x-covmedia {
    display: block;
}

.x-covmedia img {
    transition: transform 0.6s ease;
}

.x-covmedia:hover img {
    transform: scale(1.04);
}

/* The row's links sit on a light background, so the default focus ring is
   fine, but give it room to breathe. */
.x-split--linked a:focus-visible {
    outline: 2px solid var(--x-accent-deep);
    outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
    .x-covlink,
    .x-list--linked a,
    .x-covmedia img {
        transition: none;
    }

    .x-covmedia:hover img {
        transform: none;
    }
}

/* --------------------------------------------------------------------------
   Missing-image placeholder
   -------------------------------------------------------------------------- */

/* Media wrappers crop their images with object-fit: cover, which would stretch
   the placeholder's icon out of shape. Contain keeps it centred and readable.
   Same specificity as those rules but declared later, so it wins without
   needing !important. */
img.is-placeholder {
    object-fit: contain;
    background: #ededed;
}

/* --------------------------------------------------------------------------
   WhatsApp chat button
   -------------------------------------------------------------------------- */

/* Permanently visible, bottom-right. Sits below .x-top, which shifts up to
   make room; z-index stays under the mobile drawer (100) and the lightbox. */
.x-wa {
    position: fixed;
    right: 28px;
    bottom: 28px;
    z-index: 45;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: #25d366;
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.22);
    transition: transform 0.25s ease, box-shadow 0.25s ease, background 0.25s ease;
}

.x-wa:hover,
.x-wa:focus,
.x-wa:active {
    /* The global a:hover turns links gold, and the icon is fill="currentColor",
       so without this the WhatsApp glyph goes gold on hover. Keep it white and
       let the background carry the hover state. */
    color: #fff;
    background: #1ebe5a;
}

.x-wa:hover {
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.28);
}

.x-wa:focus-visible {
    outline: 3px solid var(--x-accent);
    outline-offset: 3px;
}

/* The drawer covers the viewport; a floating button poking through it looks
   broken, so both float buttons step aside while it is open. */
body.x-no-scroll .x-wa,
body.x-no-scroll .x-top {
    opacity: 0;
    pointer-events: none;
}

@media (max-width: 700px) {
    .x-wa {
        right: 18px;
        bottom: 18px;
        width: 48px;
        height: 48px;
    }

    .x-top {
        right: 18px;
        bottom: 78px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .x-wa {
        transition: none;
    }

    .x-wa:hover {
        transform: none;
    }
}
