/* ===================================
   PLATFORM LANDING PAGE
   Loaded AFTER main.css on /wecommerce, its ports and city pages,
   and on the agency homepage (body.pl-agency, overrides at the end).
   Reuses main.css tokens + hero components; inverts them
   for a light surface and owns the layout grid.
   Prefix: .pl-
   =================================== */

/* ===================================
   SECTION 1 — HERO (light, single column)
   Rebuilt Aug 16 2026 on the 1600.agency reference: one centred
   column, black headline, two pill buttons, then a full-bleed
   industries marquee. Uses its own .pl- classes rather than
   main.css's .hero-* / .btn-* family, whose six media-query steps
   are tuned to the dark home hero.
   =================================== */

/* Product accent. platform.css loads on this page only, so a :root
   here cannot reach the other 15 pages. It is a deliberate deviation
   from the tokens-live-in-main.css rule, made because this colour is
   a candidate brand colour for the eCommerce product and not for
   WePremium the agency. If it is adopted, it moves to main.css. */
:root {
    --pl-accent: #FB6930;
}

.pl-hero {
    position: relative;
    background-color: var(--bg-primary);
    /* Top pad clears the 101px fixed header, then the normal section pad.
       Horizontal padding sits on .pl-hero-container instead, so the
       marquee can run edge to edge. */
    padding: calc(101px + 4.375rem) 0 7rem;
    /* No overflow:hidden here. The video frame's shadow reaches 250px
       below the card and a clip cuts it into a straight line across the
       next section. .pl-marquee owns its own overflow, so nothing in
       this section needs the section to clip. */
}

.pl-hero-container {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
    padding: 0 3rem;
}


/* --- Headline --- */

.pl-hero-title {
    max-width: 940px;
    margin: 0 0 1.5rem;
    font-size: 4.5rem;
    font-weight: var(--font-extrabold);
    line-height: 1.02;
    letter-spacing: -0.03em;
    color: #1A1A1A;
}


/* --- Headline letter reveal ---
   platform.js splits the headline into word spans and letter spans,
   then adds .is-split. Every rule below is scoped to .is-split, so if
   the script never runs the headline simply renders as normal text.
   CSS alone never hides it. */

.pl-hero-title .pl-word {
    white-space: nowrap;
}

.pl-hero-title.is-split .pl-letter {
    display: inline-block;
    opacity: 0;
    filter: blur(5px);
    transform: translateY(6px);
    animation: plLetterIn 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
    animation-delay: calc(var(--i) * 18ms);
}

@keyframes plLetterIn {
    to {
        opacity: 1;
        filter: blur(0);
        transform: translateY(0);
    }
}


/* --- Tagline --- */

/* Same 940px box as the headline. The two lines stay short enough to
   break on their own, which is why each is its own <p> and there is no
   manual <br> to fall apart on a phone. */
.pl-hero-tagline {
    max-width: 940px;
    margin: 0 0 2.5rem;
    font-size: 1.25rem;
    font-weight: var(--font-medium);
    line-height: 1.5;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}

.pl-hero-tagline p {
    margin: 0;
}


/* --- Buttons ---
   Deliberately NOT .btn-primary / .btn-secondary. Those carry a blue
   fill, a diagonal shine sweep, and width:100% at 768px, so reusing
   them would mean overriding six rules to reach a black pill. The
   values below match the header CTA, so the two black buttons read
   as one brand element. */

.pl-hero-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
}

/* Geometry read off the reference: 48px tall button, 38px chip, 20px
   gap, 6px of black to the left of the chip. */
.pl-hero-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 15px;
    height: 48px;
    padding: 0 28px;
    font-size: 0.875rem;
    font-weight: var(--font-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    border-radius: 50px;
    /* The labels travel 34px, which is further than the button is tall.
       Without this they would show below it mid-hover. */
    overflow: hidden;
    transition: color 0.3s ease, background-color 0.3s ease, border-color 0.3s ease;
}

/* --- Per-letter label roll, downward --- */

/* Any element that hosts a rolling label carries .pl-roll-host: both
   hero buttons and the header CTA. It replaces the .pl-hero-btn
   selectors this system used while it was hero-only, so the header CTA
   drives the same rules without a second copy of them. */
.pl-roll-host {
    overflow: hidden;
}

.pl-roll {
    position: relative;
    display: inline-block;
    height: 20px;
    line-height: 20px;
    white-space: nowrap;
}

/* Invisible third copy, the only one left in the flow, so it is what
   gives the button its width. Same job as the reference's opacity:0
   ghost label. visibility rather than opacity, so it is never read. */
.pl-roll-ghost {
    display: block;
    visibility: hidden;
}

.pl-roll-out,
.pl-roll-in {
    position: absolute;
    top: 0;
    inset-inline-start: 0;
    display: block;
    white-space: nowrap;
}

/* The label you see at rest. It leaves as ONE block: no letters, no
   stagger, no delay. It also fades faster than it travels, so it is
   gone before the arriving letters reach the middle. */
.pl-roll-out {
    transition: transform 0.4s cubic-bezier(0.44, 0, 0.56, 1),
        opacity 0.22s linear;
}

.pl-roll-host:hover .pl-roll-out,
.pl-roll-host:focus-visible .pl-roll-out {
    opacity: 0;
    transform: translateY(34px);
}

/* The arriving label, letter by letter. Same three properties as the
   headline reveal, opacity plus blur plus travel, which is what makes
   the two read as the same effect. Only the direction differs: the
   headline rises from below, this descends from above. */
/* This block is the RESTING state, which is also what plays on the way
   OUT. Deliberately plain: one move, one fade, no stagger, so leaving
   behaves like the secondary button. The blur is not faded back, it is
   reset instantly by a 0s transition delayed past the fade, because a
   blur growing on a leaving letter reads as a rendering fault. */
.pl-roll-char {
    display: inline-block;
    white-space: pre;
    opacity: 0;
    filter: blur(4px);
    transform: translateY(-16px);
    transition: transform 0.4s cubic-bezier(0.44, 0, 0.56, 1) 0s,
        opacity 0.2s linear 0s,
        filter 0s linear 0.25s;
}

/* The way IN. The stagger and the blur live here and nowhere else, so
   they cannot play in reverse. The three delays must stay identical or
   the letter's fade, sharpen and travel drift apart. */
.pl-roll-host:hover .pl-roll-char,
.pl-roll-host:focus-visible .pl-roll-char {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 22ms),
        opacity 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 22ms),
        filter 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 22ms);
}

.pl-hero-btn--primary {
    padding-block: 0;
    padding-inline: 6px 20px;
    color: #FFF;
    background-color: #1A1A1A;
    border: 1px solid #1A1A1A;
}

/* The chip itself never moves and never changes colour. Everything
   that animates happens to the two glyphs inside it. */
.pl-hero-btn-icon {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    color: var(--color-white);
    background-color: var(--pl-accent);
    border-radius: 50%;
}

/* Two glyphs stacked on the same spot. One rises out while the other
   rises in, so the pair reads as one shape changing rather than two
   pictures swapping. Both keyframes run on the same 4s clock, which is
   what keeps them in step with no JavaScript. Absolute positioning
   with a negative half-size margin centres them without a transform,
   because the animation owns the transform. */
.pl-hero-btn-icon svg {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 20px;
    height: 20px;
    margin: -10px 0 0 -10px;
}

.pl-hero-btn-icon .pl-icon-a {
    animation: plIconA 4s cubic-bezier(0.44, 0, 0.56, 1) infinite;
}

.pl-hero-btn-icon .pl-icon-b {
    animation: plIconB 4s cubic-bezier(0.44, 0, 0.56, 1) infinite;
}

@keyframes plIconA {

    0%,
    38% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

    47%,
    91% {
        opacity: 0;
        transform: translateY(-10px) scale(0.7);
    }

    100% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

@keyframes plIconB {

    0%,
    38% {
        opacity: 0;
        transform: translateY(10px) scale(0.7);
    }

    47%,
    91% {
        opacity: 1;
        transform: translateY(0) scale(1);
    }

    100% {
        opacity: 0;
        transform: translateY(10px) scale(0.7);
    }
}

.pl-hero-btn--primary:hover {
    color: var(--color-white);
    background-color: #000000;
    border-color: #000000;
}

.pl-hero-btn--ghost {
    color: var(--text-primary);
    background-color: var(--color-white);
    border: 1px solid rgba(34, 34, 34, 0.12);
}

.pl-hero-btn--ghost:hover {
    color: var(--text-primary);
    background-color: var(--bg-secondary);
    border-color: rgba(34, 34, 34, 0.28);
}


/* ===================================
   HERO INDUSTRIES MARQUEE
   Same technique as main.css .portfolio-track: the list is written
   twice in the markup and the track travels exactly -50%, so the
   loop is seamless. RTL flips the direction, as it does there.
   =================================== */

.pl-hero-marquee-wrap {
    position: relative;
    z-index: 1;
    margin-top: 4rem;
    /* The section itself has no horizontal padding, so the gutter lives
       here. Padding outside, 1300px cap inside, which is the same shape
       every other section gets from .pl-x .container. */
    padding-inline: 3rem;
}

.pl-hero-marquee-label {
    margin: 0 0 1.5rem;
    text-align: center;
    font-size: 0.9rem;
    font-weight: var(--font-medium);
    color: var(--text-tertiary);
}

.pl-marquee {
    position: relative;
    width: 100%;
    max-width: var(--container-max-width-2);
    margin-inline: auto;
    overflow: hidden;
    /* Vertical page scrolling stays with the browser, horizontal belongs
       to the drag handler. Without this the browser claims the gesture
       and the cards never move under the finger. */
    touch-action: pan-y;
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    /* Fades both edges so items enter and leave instead of being cut */
    -webkit-mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
    mask-image: linear-gradient(to right, transparent, #000 8%, #000 92%, transparent);
}

.pl-marquee.is-held {
    cursor: grabbing;
}

/* No animation here any more. platform.js drives the transform, because
   a keyframe cannot be paused mid-travel and then dragged. */
.pl-marquee-track {
    display: flex;
    align-items: flex-start;
    width: max-content;
    will-change: transform;
}

/* One copy of the list. platform.js measures this element's width to
   know the loop distance, and clones it as many times as the screen
   needs, so the markup below carries the list exactly once. */
.pl-marquee-copy {
    display: flex;
    align-items: flex-start;
    flex-shrink: 0;
}

/* No fixed width. Each card is as wide as its own name, so a long one
   like "Hardware & tools" keeps its spacing instead of overflowing. */
.pl-marquee-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
    padding-inline-end: 2.25rem;
}

.pl-marquee-media {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 80px;
}

/* contain, never cover: these are product photos on white and cropping
   one would cut the product, the same rule the storefront gallery uses.
   Height drives the size; width follows, so a wide photo and a tall one
   sit on the same baseline. */
.pl-marquee-media img {
    width: auto;
    height: 100%;
    max-width: 160px;
    object-fit: contain;
}

/* Dropped from 1.25rem. The image now carries the card, so the name is
   a caption under it, not the item itself. clamp holds the three steps
   in one place. */
.pl-marquee-name {
    font-size: clamp(0.875rem, 0.78rem + 0.3vw, 0.92rem);
    font-weight: var(--font-semibold);
    letter-spacing: -0.01em;
    white-space: nowrap;
    color: #6E6E6E;
}

/* ===================================
   HERO VIDEO FRAME
   Geometry taken from the reference: a white card with 5px of padding,
   17px radius outside and 16px on the media inside, and a five-layer
   shadow. The last layer is fully transparent and is theirs, kept so
   the stack matches value for value.
   =================================== */

.pl-hero-video {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 5rem auto 0;
    padding-inline: 0;
}

.pl-hero-video-frame {
    padding: 5px;
    background-color: var(--color-white);
    border-radius: 17px;
    box-shadow: 0 10px 22px rgba(0, 0, 0, 0.1),
        0 40px 40px rgba(0, 0, 0, 0.09),
        0 90px 54px rgba(0, 0, 0, 0.05),
        0 160px 64px rgba(0, 0, 0, 0.01),
        0 250px 70px rgba(0, 0, 0, 0);
}

/* Ratio matches the coded demo stage: a 1000px full-bleed page region
   at the captures' 5:3 ratio, plus the phone column beside it. */
.pl-hero-video-media {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1290 / 591;
    border-radius: 16px;
    overflow: hidden;
    background-color: var(--bg-secondary);
}

.pl-hero-video-media video,
.pl-hero-video-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* Placeholder. Delete this rule and its markup together when the MP4
   exists; nothing else in this block changes. */
.pl-hero-video-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    padding: 1.5rem;
    text-align: center;
}

.pl-hero-video-play {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 64px;
    height: 64px;
    color: var(--color-white);
    background-color: var(--pl-accent);
    border-radius: 50%;
}

.pl-hero-video-play svg {
    width: 24px;
    height: 24px;
}

.pl-hero-video-placeholder strong {
    font-size: 0.95rem;
    font-weight: var(--font-semibold);
    color: var(--text-secondary);
}

.pl-hero-video-placeholder span {
    font-size: 0.8rem;
    color: var(--text-tertiary);
}


/* ===================================
   KEPT FROM THE OLD HERO BLOCK — DO NOT DELETE
   .pl-card-icon was removed on Aug 17 with the old features cards,
   which held all 40 of its uses. .pl-highlight stays: pricing and
   compare still use it.
   =================================== */

/* .pl-highlight: the blue-word rule. The new headline is all black,
   but 4 later section titles use it. */
.pl-highlight {
    color: var(--color-primary-blue);
    font-weight: var(--font-extrabold);
}

/* ===================================
   HERO RESPONSIVE
   =================================== */

@media (max-width: 1400px) {

    .pl-hero-title {
        font-size: 3.75rem;
    }
}

@media (max-width: 1024px) {

    /* Header is 80px here (16px top pad + a 64px pill), not 101px.
       The old value said 101px and over-padded the hero by 21px. */
    .pl-hero {
        padding: calc(80px + 3.5rem) 0 3rem;
    }

    .pl-hero-title {
        font-size: 3rem;
    }

    .pl-hero-tagline {
        font-size: 1.125rem;
    }

    .pl-hero-marquee-wrap {
        margin-top: 3.25rem;
    }

    .pl-hero-video {
        margin-top: 4rem;
    }
}

@media (max-width: 768px) {

    .pl-hero {
        padding: calc(80px + 2.5rem) 0 2.5rem;
    }

    .pl-hero-container {
        padding: 0 1.5rem;
    }

    .pl-hero-title {
        font-size: 2.4rem;
        margin-bottom: 1.25rem;
    }

    /* Cheap Android phones stutter on forty simultaneous blur filters.
       The rise and the fade read the same at this size. */
    .pl-hero-title.is-split .pl-letter {
        filter: none;
        animation-name: plLetterInFlat;
    }

    @keyframes plLetterInFlat {
        to {
            opacity: 1;
            transform: translateY(0);
        }
    }

    .pl-hero-tagline {
        font-size: 1rem;
        margin-bottom: 2rem;
    }

    /* Stacked and centred, each button only as wide as its own label,
       the way the reference does it. Never stretched to the screen. */
    .pl-hero-actions {
        flex-direction: column;
        align-items: center;
    }

    .pl-hero-marquee-wrap {
        margin-top: 2.75rem;
        padding-inline: 1.5rem;
    }

    .pl-hero-video {
        margin-top: 3rem;
        padding-inline: 1.5rem;
    }

    .pl-hero-video-play {
        width: 48px;
        height: 48px;
    }

    .pl-marquee-item {
        padding-inline-end: 1.5rem;
    }

    .pl-marquee-media {
        height: 60px;
    }

    /* Features section, not hero. Carried over from the old block. */
    .pl-card-icon {
        width: 30px;
        height: 30px;
    }

    .pl-card-icon svg {
        width: 16px;
        height: 16px;
    }
}

@media (max-width: 480px) {

    .pl-hero-title {
        font-size: 2rem;
    }

    .pl-hero-tagline {
        font-size: 0.95rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-hero-title.is-split .pl-letter {
        opacity: 1;
        filter: none;
        transform: none;
        animation: none;
    }

    .pl-roll-out,
    .pl-roll-char {
        transition: none;
    }

    .pl-hero-btn-icon .pl-icon-a {
        animation: none;
        opacity: 1;
        transform: none;
    }

    .pl-hero-btn-icon .pl-icon-b {
        animation: none;
        opacity: 0;
    }
}

/* ===================================
   SECTION 2: HOW IT WORKS
   Rebuilt Aug 17 2026 on the 1600.agency process cards. White
   section, grey cards, orange step label, centred title and text,
   then a visual slot. Every number is read off the reference; the
   only change is 4 cards at 468px becoming 3 inside our 1300px
   container.
   =================================== */

.pl-steps {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
}

.pl-steps .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}


/* --- Section header ---
   New family, built to the reference: 50px title, 18px description,
   16px between them, 56px down to the cards. Deliberately NOT
   .services-header, which carries a badge this section no longer has.
   The later sections move onto this family when we reach them. */

.pl-title-block {
    margin: 0 auto 3.5rem;
    text-align: center;
}

.pl-title {
    margin: 0 0 1rem;
    font-size: 3.125rem;
    font-weight: var(--font-extrabold);
    line-height: 1.28;
    letter-spacing: -0.03em;
    color: #1A1A1A;
}

.pl-subtitle {
    max-width: 717px;
    margin: 0 auto;
    font-size: 1.125rem;
    font-weight: var(--font-medium);
    line-height: 1.5;
    letter-spacing: -0.02em;
    color: var(--text-secondary);
}


/* --- KEPT FROM THE OLD HEADER — DO NOT DELETE ---
   .pl-section-header was declared here when this section still used
   the badge header. It is used by FOUR later sections: features,
   industries, pricing, compare. It stays until those sections move
   onto .pl-title-block. */
.pl-section-header {
    margin-bottom: 3.5rem;
}


/* --- Step cards --- */

.pl-steps-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 26px;
}

/* overflow:hidden is the reference's, and it is load-bearing: it is
   what lets the floating chips inside the visual sit half off the
   card edge in the animation pass. */
.pl-step {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 32px;
    min-height: 475px;
    padding: 24px 0;
    background-color: var(--bg-secondary);
    border-radius: 24px;
    overflow: hidden;
}

.pl-step-body {
    width: 90%;
    text-align: center;
}

/* The reference draws a 2px rgba(255,255,255,0.1) border with a 2.5px
   backdrop blur around this label. On a light card that renders
   invisible and only the orange text reads, which is what the live
   site shows. Kept value for value in case the card ever takes a dark
   or image background. */
.pl-step-label {
    display: inline-flex;
    align-items: center;
    height: 40px;
    margin: 0;
    padding: 10px 14px;
    font-size: 1.25rem;
    font-weight: var(--font-bold);
    line-height: 1.26;
    color: var(--pl-accent);
    border: 2px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    backdrop-filter: blur(2.5px);
    -webkit-backdrop-filter: blur(2.5px);
}

.pl-step-title {
    margin: 10px 0 0;
    font-size: 1.4rem;
    font-weight: var(--font-semibold);
    line-height: 1.17;
    color: #171717;
}

.pl-step-desc {
    margin: 8px 0 0;
    font-size: 1rem;
    font-weight: var(--font-regular);
    line-height: 1.6;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}

/* 355 x 222 inside a 468px card in the reference. Ours is a fluid
   3-column row, so the same proportion is written as a ratio. */
/* Widened from 82%, and the ratio is gone. Three cards in a 1300px row
   leave each mock under 400px, and everything inside is drawn at a real
   pixel size, so the slot has to give back every pixel it can and let
   its content decide the height. */
.pl-step-visual {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 92%;
}

.pl-step-visual img {
    display: block;
    width: 100%;
    height: auto;
}

/* --- Step 1 visual: the WhatsApp conversation ---
   Drawn in CSS, not a screenshot. Reasons: every string here has to
   exist in three languages, a picture of a chat cannot be translated
   or animated bubble by bubble, and a generated one would invent
   letterforms. Colours are WhatsApp's real light theme; the typeface
   is deliberately ours, so it reads as an illustration of a
   conversation rather than a stolen screenshot.
   The whole block is aria-hidden: the card's text already says it. */

.pl-chat {
    position: relative;
    width: 100%;
    border-radius: 14px;
    overflow: hidden;
    /* WhatsApp's light wallpaper is not a flat colour: it is a warm
       beige with a doodle tile drawn over it in a slightly darker warm
       grey. The stroke colour is baked into the file rather than set
       with opacity, so nothing painted on top has to be re-tinted. */
    background-color: #EFEAE2;
    background-image: url("/images/platform/whatsapp-doodle.svg");
    background-size: 260px 260px;
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.06),
        0 12px 24px rgba(11, 20, 26, 0.08),
        0 28px 44px rgba(11, 20, 26, 0.06);
}


/* Top bar */

.pl-chat-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding-inline: 10px;
    background-color: #008069;
}

.pl-chat-back {
    flex: none;
    width: 13px;
    height: 13px;
    color: #FFFFFF;
    opacity: 0.9;
}

.pl-chat-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 29px;
    height: 29px;
    border-radius: 50%;
    background-color: #FFFFFF;
    overflow: hidden;
}

/* Inset inside the circle rather than filling it. The mark is a square
   with four outer points, and a circular crop would cut all four off. */
.pl-chat-avatar img {
    width: 23px;
    height: 23px;
    object-fit: contain;
}

.pl-chat-who {
    display: flex;
    flex-direction: column;
    justify-content: center;
    flex: 1 1 auto;
    min-width: 0;
}

.pl-chat-who strong {
    font-size: 12.5px;
    font-weight: var(--font-semibold);
    line-height: 1.2;
    color: #FFFFFF;
}

.pl-chat-who em {
    font-size: 9.5px;
    font-style: normal;
    line-height: 1.3;
    color: rgba(255, 255, 255, 0.75);
}

.pl-chat-tools {
    display: flex;
    align-items: center;
    gap: 11px;
    flex: none;
}

.pl-chat-tools svg {
    width: 15px;
    height: 15px;
    color: #FFFFFF;
    opacity: 0.85;
}


/* Conversation */

/* Fixed height, and the messages are packed to the BOTTOM. Those two
   rules are the entire auto-scroll: as each message opens the stack
   grows downward, the box cannot, so the oldest messages are pushed off
   the top and clipped. No scroll position is ever calculated. */
.pl-chat-body {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 200px;
    padding: 11px 10px 14px;
    overflow: hidden;
}

/* One beat of the conversation. Closed at 0fr, opened to 1fr by
   platform.js. Animating the grid track is what makes the messages
   above slide up smoothly instead of jumping a whole line. */
.pl-chat-step {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.45s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-chat-step.is-in {
    grid-template-rows: 1fr;
}

/* The 5px gap lives here, inside the clipped row, and not as a gap on
   the body: a gap on the body would paint space between messages that
   have not arrived yet. */
.pl-chat-row {
    display: flex;
    min-height: 0;
    padding-top: 5px;
    overflow: hidden;
    opacity: 0;
    transform: translateY(5px);
    transition: opacity 0.3s ease 0.08s, transform 0.3s ease 0.08s;
}

.pl-chat-step.is-in .pl-chat-row {
    opacity: 1;
    transform: none;
}

.pl-chat-row--out {
    justify-content: flex-end;
}

.pl-chat-row--day {
    justify-content: center;
    padding-bottom: 3px;
}

.pl-chat-day {
    padding: 3px 8px;
    border-radius: 6px;
    background-color: #FFFFFF;
    box-shadow: 0 1px 0.5px rgba(11, 20, 26, 0.13);
    font-size: 9.5px;
    font-weight: var(--font-semibold);
    letter-spacing: 0.04em;
    line-height: 1;
    color: rgba(17, 27, 33, 0.5);
}

/* padding-bottom reserves the line the timestamp sits on, which is how
   the real client does it: the clock never pushes the text around. */
.pl-chat-bubble {
    position: relative;
    max-width: 80%;
    padding: 7px 9px 16px;
    border-radius: 8px;
    background-color: #FFFFFF;
    box-shadow: 0 1px 0.5px rgba(11, 20, 26, 0.13);
    font-size: 12px;
    font-weight: var(--font-regular);
    line-height: 1.4;
    letter-spacing: 0;
    color: #111B21;
}

.pl-chat-row--out .pl-chat-bubble {
    background-color: #D9FDD3;
}

/* The tail. A border triangle rather than a rotated square, because a
   diamond poking out of the corner never reads as a speech bubble. */
.pl-chat-bubble::after {
    content: "";
    position: absolute;
    top: 0;
    width: 0;
    height: 0;
    border-bottom: 8px solid transparent;
}

.pl-chat-row--in .pl-chat-bubble {
    border-start-start-radius: 0;
}

.pl-chat-row--in .pl-chat-bubble::after {
    inset-inline-start: -7px;
    border-right: 7px solid #FFFFFF;
}

.pl-chat-row--out .pl-chat-bubble {
    border-start-end-radius: 0;
}

.pl-chat-row--out .pl-chat-bubble::after {
    inset-inline-end: -7px;
    border-left: 7px solid #D9FDD3;
}

/* The tails are drawn with physical border sides, so the Arabic page
   needs the two of them swapped. Everything else mirrors on its own. */
[dir="rtl"] .pl-chat-row--in .pl-chat-bubble::after {
    border-right: 0;
    border-left: 7px solid #FFFFFF;
}

[dir="rtl"] .pl-chat-row--out .pl-chat-bubble::after {
    border-left: 0;
    border-right: 7px solid #D9FDD3;
}

.pl-chat-meta {
    position: absolute;
    inset-inline-end: 8px;
    bottom: 4px;
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 9.5px;
    line-height: 1;
    color: rgba(17, 27, 33, 0.45);
}

.pl-chat-meta svg {
    width: 13px;
    height: 13px;
    color: #53BDEB;
}


/* Typing indicator. Three dots on one 0.9s cycle offset by 0.15s each,
   which is what makes it read as a wave instead of a blink. */
.pl-chat-typing {
    display: flex;
    align-items: center;
    gap: 3px;
    padding: 9px 10px;
    border-radius: 8px;
    border-start-start-radius: 0;
    background-color: #FFFFFF;
    box-shadow: 0 1px 0.5px rgba(11, 20, 26, 0.13);
}

.pl-chat-typing span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: rgba(17, 27, 33, 0.35);
    animation: plTypingDot 0.9s ease-in-out infinite;
}

.pl-chat-typing span:nth-child(2) {
    animation-delay: 0.15s;
}

.pl-chat-typing span:nth-child(3) {
    animation-delay: 0.3s;
}

@keyframes plTypingDot {

    0%,
    60%,
    100% {
        opacity: 0.35;
        transform: translateY(0);
    }

    30% {
        opacity: 1;
        transform: translateY(-3px);
    }
}


/* The floating attachment card. Same device as the reference's chips:
   a small object rotated a few degrees, lifted off the surface by its
   shadow, overlapping the corner of the thing behind it. */
.pl-chat-file {
    position: absolute;
    inset-inline-end: -8px;
    bottom: 2px;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 13px 8px 9px;
    border-radius: 11px;
    background-color: #FFFFFF;
    border: 1px solid rgba(0, 0, 0, 0.05);
    /* Without this the browser rotates each glyph on the pixel grid
       instead of rotating one rasterised layer, and the letters
       staircase. It is a rendering hint, not a performance one. */
    will-change: transform;
    backface-visibility: hidden;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.06),
        0 14px 26px rgba(0, 0, 0, 0.1);
    /* The resting state IS the not-yet-arrived state: smaller, flatter,
       invisible. platform.js adds .is-in on the turn the file is sent.
       The overshoot in the curve is what gives it weight when it lands. */
    opacity: 0;
    transform: rotate(1deg) scale(0.82);
    transform-origin: 100% 100%;
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.pl-chat-file.is-in {
    opacity: 1;
    transform: rotate(-4deg) scale(1);
}

.pl-chat-file-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background-color: rgba(251, 105, 48, 0.12);
    color: var(--pl-accent);
}

.pl-chat-file-icon svg {
    width: 16px;
    height: 16px;
}

.pl-chat-file-text {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.pl-chat-file-text strong {
    font-size: 11px;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

.pl-chat-file-text span {
    font-size: 9.5px;
    color: var(--text-tertiary);
}


/* --- Step 2 visual: the browser window that builds itself ---
   The storefront inside is drawn, not screenshotted. Text below 8px is
   unreadable anyway, so the copy is grey bars; what carries the
   likeness is the colour signature of the real store, which at this
   scale is four things and only four: navy heading, yellow stars, the
   red discount badge, the green Add To Cart. */

.pl-browser {
    width: 100%;
    border-radius: 10px;
    overflow: hidden;
    background-color: var(--color-white);
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.05),
        0 12px 24px rgba(11, 20, 26, 0.07),
        0 28px 44px rgba(11, 20, 26, 0.05);
}


/* Window bar */

.pl-browser-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    height: 34px;
    padding-inline: 11px;
    background-color: #F1F2F4;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}

.pl-browser-dots {
    display: flex;
    gap: 4px;
    flex: none;
}

.pl-browser-dots span {
    width: 7px;
    height: 7px;
    border-radius: 50%;
}

.pl-browser-dots span:nth-child(1) {
    background-color: #FF5F57;
}

.pl-browser-dots span:nth-child(2) {
    background-color: #FEBC2E;
}

.pl-browser-dots span:nth-child(3) {
    background-color: #28C840;
}

.pl-browser-url {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    height: 20px;
    padding-inline: 9px;
    border-radius: 20px;
    background-color: var(--color-white);
    font-size: 11px;
    line-height: 1;
    color: #4A4A4A;
    overflow: hidden;
}

/* The padlock waits until the address is finished, so the two read as
   cause and effect rather than as decoration that was always there. */
.pl-browser-lock {
    flex: none;
    width: 12px;
    height: 12px;
    opacity: 0;
    color: #1FA34A;
}

.pl-browser-url.is-in .pl-browser-lock {
    animation: plFadeIn 0.35s ease 1.3s forwards;
}

/* Typed by revealing the real text with clip-path, one step per
   character. The element keeps its natural width, so changing the
   domain never needs a pixel measurement again: only the step count
   in plType has to match the number of characters. */
.pl-browser-type {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex: none;
}

.pl-browser-domain {
    white-space: nowrap;
    clip-path: inset(0 100% 0 0);
}

.pl-browser-url.is-in .pl-browser-domain {
    animation: plType 1.2s steps(17) forwards;
}

/* Absolutely positioned and travelling on the same step count, so it
   sits exactly at the edge of what has been typed instead of being
   clipped away with the text. */
.pl-browser-caret {
    position: absolute;
    top: 50%;
    inset-inline-start: 0;
    width: 1.5px;
    height: 12px;
    margin-top: -6px;
    background-color: #4A4A4A;
}

.pl-browser-url.is-in .pl-browser-caret {
    animation: plCaret 1.2s steps(17) forwards,
        plFadeOut 0.25s ease 1.35s forwards;
}

@keyframes plType {
    to {
        clip-path: inset(0 0 0 0);
    }
}

@keyframes plCaret {
    to {
        inset-inline-start: 100%;
    }
}

@keyframes plFadeIn {
    to {
        opacity: 1;
    }
}

@keyframes plFadeOut {
    to {
        opacity: 0;
    }
}


/* The page inside. Every part is in the layout from the start and only
   fades and rises, so the window never jumps as it fills. */

.pl-browser-page {
    background-color: #F1F2F4;
    padding-bottom: 10px;
}

.pl-browser-page [data-seq] {
    opacity: 0;
    transform: translateY(9px);
    transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-browser-page [data-seq].is-in {
    opacity: 1;
    transform: none;
}

/* #01539F is the storefront's navy, read off the real store. It is not
   a main.css token: the site's blues are #207DE9 and #1666C3, and this
   is the shop's colour, not the agency's. */
.pl-shop-promo {
    height: 11px;
    background-color: #01539F;
}

.pl-shop-head {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 32px;
    padding-inline: 10px;
    background-color: var(--color-white);
}

.pl-shop-logo {
    flex: none;
    width: 17px;
    height: 17px;
    border-radius: 3px;
    background-color: #F2B705;
}

.pl-shop-name {
    flex: none;
    font-size: 10px;
    font-weight: var(--font-bold);
    line-height: 1;
    letter-spacing: -0.01em;
    color: #01539F;
}

.pl-shop-search {
    flex: 1 1 auto;
    height: 14px;
    border-radius: 3px;
    background-color: #F1F2F4;
    border: 1px solid #E4E4E5;
}

.pl-shop-cart {
    flex: none;
    width: 13px;
    height: 13px;
    border-radius: 2px;
    background-color: #01539F;
}

.pl-shop-nav {
    display: flex;
    align-items: center;
    gap: 11px;
    height: 18px;
    padding-inline: 10px;
    background-color: var(--color-white);
    border-top: 1px solid #EFEFF1;
}

.pl-shop-nav span {
    height: 4px;
    border-radius: 2px;
    background-color: #C9CDD3;
}

.pl-shop-nav span:nth-child(1) {
    width: 14px;
}

.pl-shop-nav span:nth-child(2) {
    width: 20px;
}

.pl-shop-nav span:nth-child(3) {
    width: 16px;
}

.pl-shop-nav span:nth-child(4) {
    width: 24px;
}

.pl-shop-nav span:nth-child(5) {
    width: 18px;
}

.pl-shop-body {
    padding: 9px 10px 0;
}

.pl-shop-hero {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    height: 62px;
    padding-inline: 12px;
    border-radius: 5px;
    background: linear-gradient(115deg, #2C3E50 0%, #46617D 55%, #7C8FA3 100%);
}

.pl-shop-hero i {
    display: block;
    height: 4px;
    border-radius: 2px;
    background-color: rgba(255, 255, 255, 0.85);
}

.pl-shop-hero i:nth-child(1) {
    width: 62px;
}

.pl-shop-hero i:nth-child(2) {
    width: 44px;
    background-color: rgba(255, 255, 255, 0.55);
}

.pl-shop-hero b {
    width: 26px;
    height: 8px;
    margin-top: 2px;
    border-radius: 2px;
    background-color: #F2B705;
}

/* Two cards, not three. The real card puts the image beside the text,
   which needs horizontal room; three of them inside a 380px window
   would each be 118px and the layout would have to be faked. */
.pl-shop-row {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
    margin-top: 9px;
}

.pl-shop-card {
    padding: 6px;
    background-color: var(--color-white);
    border: 1px solid #E9EAEC;
    border-radius: 5px;
}

/* Image beside the text. The stepper and the button live on their own
   row underneath, which is the real card's anatomy. */
.pl-shop-card-top {
    display: flex;
    gap: 6px;
}

.pl-shop-img {
    flex: none;
    width: 38px;
    height: 46px;
    border-radius: 3px;
    background-color: #EDEEF0;
}

.pl-shop-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex: 1 1 auto;
    min-width: 0;
}

.pl-shop-line {
    height: 4px;
    border-radius: 2px;
    background-color: #C9CDD3;
}

.pl-shop-line--short {
    width: 55%;
}

.pl-shop-stars {
    display: flex;
    gap: 2px;
}

.pl-shop-stars i {
    width: 4px;
    height: 4px;
    border-radius: 1px;
    background-color: #F2B705;
}

.pl-shop-price {
    display: flex;
    align-items: center;
    gap: 4px;
}

/* The notch on the trailing edge is the real discount badge's shape,
   and at this size it is most of what makes the card recognisable. */
.pl-shop-badge {
    flex: none;
    width: 17px;
    height: 8px;
    background-color: #D8232A;
    clip-path: polygon(0 0, 78% 0, 100% 50%, 78% 100%, 0 100%);
}

.pl-shop-cost {
    width: 24px;
    height: 5px;
    border-radius: 2px;
    background-color: #1A1A1A;
}

/* The struck-through old price, as a washed red bar. */
.pl-shop-old {
    width: 18px;
    height: 3px;
    border-radius: 2px;
    background-color: #E58C90;
}

.pl-shop-card-bottom {
    display: flex;
    gap: 5px;
    margin-top: 7px;
}

.pl-shop-qty {
    flex: none;
    width: 40px;
    height: 15px;
    border: 1px solid #DEE0E3;
    border-radius: 3px;
}

.pl-shop-btn {
    flex: 1 1 auto;
    height: 15px;
    border-radius: 3px;
    background-color: #4CAF50;
}


/* The tag. The reference's device: a solid accent label rotated a few
   degrees with a glow of its own colour under it. Card 1's chip is
   white and sits bottom right, so this one is orange and sits bottom
   left, and the row does not repeat itself. */
.pl-tag {
    position: absolute;
    inset-inline-start: -12px;
    bottom: 4px;
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 8px 12px;
    border-radius: 9px;
    background-color: var(--pl-accent);
    font-size: 11.5px;
    font-weight: var(--font-bold);
    will-change: transform;
    backface-visibility: hidden;
    line-height: 1;
    color: var(--color-white);
    box-shadow: 0 6px 14px rgba(251, 105, 48, 0.35),
        0 14px 30px rgba(0, 0, 0, 0.12);
    opacity: 0;
    transform: rotate(1deg) scale(0.82);
    transform-origin: 0 100%;
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.pl-tag.is-in {
    opacity: 1;
    transform: rotate(-5deg) scale(1);
}

.pl-tag svg {
    width: 12px;
    height: 12px;
}


/* --- Step 3 visual: the phone ---
   The list is the real dashboard's order card: number and date on one
   line with the status pill opposite, then customer and phone, then the
   amount, then the payment and delivery chips. Same reason as card 2 for
   drawing rather than shooting, with one more: this screen carries real
   customer names and phone numbers, and those must never travel onto a
   public page. Every value below is invented and modest.
   =================================== */

/* The phone is taller than the space it is given and is cropped by this
   box. A device cut by the frame edge reads as a photograph of a phone;
   a whole phone squeezed to fit reads as a drawing of one. */
.pl-phone-stage {
    position: relative;
    width: 100%;
    height: 300px;
    overflow: hidden;
}

.pl-phone-frame {
    position: absolute;
    bottom: -70px;
    left: 50%;
    width: 238px;
    height: 370px;
    padding: 7px;
    border-radius: 28px;
    background-color: #1A1A1A;
    transform: translateX(-50%);
    box-shadow: 0 4px 10px rgba(11, 20, 26, 0.1),
        0 18px 34px rgba(11, 20, 26, 0.14),
        0 40px 60px rgba(11, 20, 26, 0.1);
}

.pl-phone-notch {
    position: absolute;
    top: 12px;
    left: 50%;
    width: 54px;
    height: 6px;
    border-radius: 4px;
    background-color: #000000;
    transform: translateX(-50%);
    z-index: 2;
}

.pl-phone-screen {
    width: 100%;
    height: 100%;
    border-radius: 21px;
    overflow: hidden;
    background-color: #F1F2F4;
}

/* Everything on the screen rises into place. The one exception is the
   arriving order, which has to open the list rather than fade onto it. */
.pl-phone-screen [data-seq]:not(.pl-grow) {
    opacity: 0;
    transform: translateY(9px);
    transition: opacity 0.4s ease, transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-phone-screen [data-seq]:not(.pl-grow).is-in {
    opacity: 1;
    transform: none;
}

/* A row that opens the list instead of appearing on top of it. Same
   grid technique as the chat: the track goes 0fr to 1fr, so the orders
   underneath are pushed down smoothly rather than jumping. */
.pl-grow {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-grow.is-in {
    grid-template-rows: 1fr;
}

.pl-grow>div {
    min-height: 0;
    overflow: hidden;
}


/* Status bar */

.pl-phone-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 22px;
    padding: 0 13px;
    background-color: var(--color-white);
    font-size: 9.5px;
    font-weight: var(--font-semibold);
    line-height: 1;
    color: #1A1A1A;
}

.pl-phone-signal {
    display: flex;
    align-items: flex-end;
    gap: 2px;
}

.pl-phone-signal i {
    width: 2.5px;
    border-radius: 1px;
    background-color: #1A1A1A;
}

.pl-phone-signal i:nth-child(1) {
    height: 4px;
}

.pl-phone-signal i:nth-child(2) {
    height: 6px;
}

.pl-phone-signal i:nth-child(3) {
    height: 8px;
}


/* App bar */

.pl-app-bar {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 34px;
    padding: 0 11px;
    background-color: var(--color-white);
    border-bottom: 1px solid #EDEEF0;
}

.pl-app-burger {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
    flex: none;
    width: 13px;
}

.pl-app-burger i {
    height: 1.5px;
    border-radius: 1px;
    background-color: #1A1A1A;
}

.pl-app-title {
    flex: 1 1 auto;
    font-size: 12px;
    font-weight: var(--font-semibold);
    line-height: 1;
    color: #1A1A1A;
}

.pl-app-bell {
    flex: none;
    width: 13px;
    height: 13px;
    color: #8E8E8E;
}

.pl-app-avatar {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 19px;
    height: 19px;
    border-radius: 50%;
    background-color: #E7F0FD;
    font-size: 8px;
    font-weight: var(--font-bold);
    line-height: 1;
    letter-spacing: 0.02em;
    color: #1666C3;
}

.pl-app-chevron {
    flex: none;
    width: 10px;
    height: 10px;
    margin-inline-start: -4px;
    color: #8E8E8E;
}


/* Page heading and controls. These sit on the grey page background, not
   on the white app bar, which is what separates the two zones. */

.pl-app-page {
    padding: 10px 11px 9px;
}

.pl-app-head strong {
    display: block;
    font-size: 14px;
    font-weight: var(--font-bold);
    line-height: 1;
    letter-spacing: -0.01em;
    color: #1A1A1A;
}

.pl-app-head span {
    display: block;
    margin-top: 5px;
    font-size: 9.5px;
    line-height: 1;
    color: #8E8E8E;
}

.pl-app-controls {
    display: flex;
    gap: 7px;
    margin-top: 10px;
}

.pl-app-select {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex: none;
    width: 68px;
    height: 27px;
    padding: 0 7px;
    border-radius: 5px;
    background-color: var(--color-white);
    border: 1px solid #DEE0E3;
    font-size: 9px;
    font-weight: var(--font-medium);
    line-height: 1;
    color: #3A3A3A;
}

.pl-app-select svg {
    flex: none;
    width: 9px;
    height: 9px;
    color: #8E8E8E;
}

/* #2563EB is the dashboard's action blue, read off the real page. */
.pl-app-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 1 1 auto;
    height: 27px;
    padding: 0 8px;
    border-radius: 5px;
    background-color: #2563EB;
    font-size: 9px;
    font-weight: var(--font-semibold);
    line-height: 1;
    color: var(--color-white);
    white-space: nowrap;
}


/* Tabs */

/* No background: the grey page shows through. overflow:hidden is not a
   safety net, it is the design. The real page runs out of width and cuts
   the last tab mid-word, and that cut is part of what makes it read as a
   real phone screen. */
.pl-app-tabs {
    display: flex;
    align-items: center;
    gap: 11px;
    height: 26px;
    padding: 0 11px;
    border-bottom: 1px solid #E4E5E8;
    font-size: 9.5px;
    font-weight: var(--font-medium);
    line-height: 1;
    color: #8E8E8E;
    white-space: nowrap;
    overflow: hidden;
}

.pl-app-tabs b {
    margin-inline-start: 3px;
    font-weight: var(--font-medium);
    color: #A4A4A4;
}

.pl-app-tabs span {
    position: relative;
    height: 100%;
    display: flex;
    align-items: center;
}

.pl-app-tabs .is-active {
    font-weight: var(--font-semibold);
    color: #1A1A1A;
}

.pl-app-tabs .is-active::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 2px;
    background-color: #1A1A1A;
}


/* The order card */

.pl-orders {
    padding: 9px 11px 0;
}

.pl-order {
    margin-bottom: 8px;
    background-color: var(--color-white);
    border: 1px solid #E9EAEC;
    border-radius: 8px;
    overflow: hidden;
}

/* Two zones with a rule between them: the identity row on top, the order
   itself below. That rule is most of what makes the real card
   recognisable at a glance. */
.pl-order-top {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 9px 11px;
    border-bottom: 1px solid #EDEEF0;
}

.pl-order-body {
    padding: 9px 11px 11px;
}

.pl-order-id {
    flex: none;
    font-size: 10px;
    font-weight: var(--font-bold);
    line-height: 1;
    color: #1A1A1A;
}

.pl-order-date {
    flex: 1 1 auto;
    font-size: 9.5px;
    line-height: 1;
    color: #9A9A9A;
}

.pl-order-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: none;
    padding: 4px 7px;
    border-radius: 20px;
    background-color: #E4F7E7;
    font-size: 8.5px;
    font-weight: var(--font-semibold);
    line-height: 1;
    color: #1B7F2A;
}

.pl-order-pill::before {
    content: "";
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background-color: #2AB131;
}

/* The arriving order. Blue, not green: it is new, nothing has happened
   to it yet, and green here would say delivered. */
.pl-order-pill--new {
    background-color: #E7F0FD;
    color: #1666C3;
}

.pl-order-pill--new::before {
    background-color: #207DE9;
}

/* Two flashes, then it settles. The ring is an INSET shadow and the
   colour change is on the border, both of which live inside the box: an
   outer ring would be clipped away by the overflow:hidden that the row's
   opening animation depends on. */
.pl-grow.is-in .pl-order--new {
    animation: plNewFlash 1.9s ease-in-out 0.55s 1 both;
}

@keyframes plNewFlash {

    0%,
    32%,
    72%,
    100% {
        border-color: #E9EAEC;
        background-color: var(--color-white);
        box-shadow: inset 0 0 0 0 rgba(32, 125, 233, 0);
    }

    12%,
    52% {
        border-color: #207DE9;
        background-color: #EFF6FF;
        box-shadow: inset 0 0 0 1.5px rgba(32, 125, 233, 0.45);
    }
}

.pl-order-body {
    padding: 9px 11px 11px;
}

.pl-order-who {
    display: flex;
    align-items: baseline;
    gap: 4px;
}

.pl-order-who strong {
    font-size: 10px;
    font-weight: var(--font-medium);
    line-height: 1;
    color: #3A3A3A;
}

.pl-order-who span {
    font-size: 9.5px;
    line-height: 1;
    color: #A4A4A4;
}

.pl-order-amount {
    margin-top: 6px;
    font-size: 12.5px;
    font-weight: var(--font-bold);
    line-height: 1;
    color: #1A1A1A;
}

.pl-order-chips {
    display: flex;
    gap: 10px;
    margin-top: 9px;
}

/* A tinted icon square followed by plain text, never a pill. Pills here
   would compete with the status badge, which is the only thing on the
   card that should look like a badge. */
.pl-order-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 9px;
    font-weight: var(--font-medium);
    line-height: 1;
    color: #4A4A4A;
    white-space: nowrap;
}

.pl-order-chip i {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 20px;
    height: 20px;
    border-radius: 5px;
}

/* Colour by position, and it is safe here because the position is not
   arbitrary: the first chip is always the payment method and the second
   is always how the order reaches the customer. Money reads green, the
   journey reads amber. Two tints, not two more icons to draw.
   The real dashboard uses colour emoji in these squares; emoji render
   differently on every OS, so these are SVGs tinted to match. */
.pl-order-chip:nth-child(1) i {
    background-color: #E4F7E7;
    color: #1B7F2A;
}

.pl-order-chip:nth-child(2) i {
    background-color: #FFF0E6;
    color: #C2570F;
}

.pl-order-chip svg {
    width: 12px;
    height: 12px;
}


/* --- The push notification ---
   Overlaps the phone rather than sitting beside it, which is what makes
   the two read as one object. It lives OUTSIDE .pl-phone-stage on
   purpose: the stage crops the phone, and anything inside it would be
   cropped too. */
/* Straddling the phone's RIGHT edge: half over the screen, half hanging
   off into the card, which is what ties the two objects together. The
   inset is measured from the phone's centre, not from the card, so it
   holds its place when the card grows. The height is the empty band
   beside the Orders heading, so it covers no data. */
.pl-push {
    position: absolute;
    top: 60px;
    inset-inline-start: calc(30% + 60px);
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 9px 12px 9px 9px;
    border-radius: 12px;
    background-color: var(--color-white);
    border: 1px solid rgba(0, 0, 0, 0.05);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.07),
        0 16px 30px rgba(0, 0, 0, 0.12);
    opacity: 0;
    transform: translateY(-12px) scale(0.88);
    transform-origin: 50% 0;
    transition: opacity 0.3s ease, transform 0.5s cubic-bezier(0.34, 1.4, 0.5, 1);
    will-change: transform;
    backface-visibility: hidden;
}

.pl-push.is-in {
    opacity: 1;
    transform: translateY(0) scale(1);
}

.pl-push-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    background-color: rgba(251, 105, 48, 0.12);
    color: var(--pl-accent);
}

.pl-push-icon svg {
    width: 16px;
    height: 16px;
}

.pl-push-text {
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.2;
}

.pl-push-text strong {
    font-size: 11.5px;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

.pl-push-text span {
    font-size: 10.5px;
    color: var(--text-tertiary);
}


/* The reference closes the section with a 1200px hairline. */
.pl-steps-line {
    width: 1200px;
    max-width: 100%;
    height: 1px;
    margin: 3.5rem auto 0;
    background-color: var(--border-light);
}


/* --- Client testimonial --- */

.pl-testimonial {
    max-width: 760px;
    margin: 4.5rem auto 0;
    padding: 0;
    text-align: center;
}

.pl-testimonial-avatar {
    display: block;
    width: 64px;
    height: 64px;
    margin: 0 auto 1.5rem;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid var(--border-light);
}

/* Placeholder: delete once the real avatar exists */
.pl-testimonial-avatar--placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--bg-tertiary);
    border: 1px dashed var(--border-medium);
    font-size: 0.7rem;
    color: var(--text-tertiary);
}

.pl-testimonial-quote {
    font-size: 1.5rem;
    font-weight: var(--font-medium);
    color: var(--text-primary);
    line-height: 1.4;
    margin: 0 0 1.5rem;
}

.pl-testimonial-author strong {
    display: block;
    font-size: 0.95rem;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.pl-testimonial-author span {
    font-size: 0.9rem;
    color: var(--text-secondary);
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-steps {
        padding: 3rem;
    }

    .pl-section-header {
        margin-bottom: 3rem;
    }

    .pl-title {
        font-size: 2.5rem;
    }

    .pl-title-block {
        margin-bottom: 3rem;
    }

    /* One column from here, as the reference does, with the card held
       at its reference width instead of stretching to the container. */
    .pl-steps-grid {
        grid-template-columns: 1fr;
        max-width: 475px;
        margin-inline: auto;
    }

    .pl-testimonial {
        margin-top: 3.5rem;
    }

    .pl-testimonial-quote {
        font-size: 1.3rem;
    }
}

@media (max-width: 768px) {

    .pl-steps {
        padding: 2.5rem 1.5rem;
    }

    .pl-section-header {
        margin-bottom: 2.5rem;
    }

    .pl-title {
        font-size: 2rem;
    }

    .pl-title-block {
        margin-bottom: 2.5rem;
    }

    .pl-subtitle {
        font-size: 1rem;
    }

    /* Card height follows its content on a phone, as in the reference. */
    .pl-step {
        min-height: 0;
    }

    .pl-step-visual {
        width: 90%;
    }

    .pl-testimonial {
        margin-top: 3rem;
    }

    .pl-testimonial-quote {
        font-size: 1.15rem;
    }
}

@media (max-width: 480px) {

    .pl-testimonial-avatar {
        width: 56px;
        height: 56px;
        margin-bottom: 1.25rem;
    }

    .pl-testimonial-quote {
        font-size: 1.05rem;
    }
}

/* ===================================
   SECTION 3: FEATURES
   Rebuilt Aug 17 2026. Six cards in two columns, each one a real
   screenshot over a title and three checked lines. The card values
   are SECTION 2's (grey card on a white section, 24px radius, 26px
   gap) so the two sections read as one system. The text is aligned
   to the start rather than centred, because a screenshot card is
   read top-left downward, not like a caption under a photo.
   The check chip is the reference's: an 18px circle in --pl-accent,
   10px to a 14px / 600 label.
   =================================== */

/* The reference's device, read off ref-1600-agency.html: no band with
   edges, a vertical gradient across the whole section. The title sits
   in the white part, the cards in the grey part, and nothing draws a
   line between them.
   Theirs runs white to grey and the NEXT section runs grey back to
   white, which needs two sections to close. Ours sits between two white
   ones, so it makes the return trip itself. The stops are in pixels,
   not percentages, so the fade stays the same length whether the grid
   is two columns or one. */
.pl-features {
    position: relative;
    background-color: var(--bg-primary);
    background-image: linear-gradient(180deg,
            var(--bg-primary) 0px,
            var(--bg-secondary) 220px,
            var(--bg-secondary) calc(100% - 140px),
            var(--bg-primary) 100%);
    padding: var(--container-section-padding);
}

.pl-features .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}


/* --- Grid ---
   Two columns and nothing else: a screenshot needs width. The gap is
   SECTION 2's 26px, so the card edges line up down the page. */

.pl-features-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 26px;
}

/* Inverted from SECTION 2: white card on grey, not grey card on white.
   The border is the reference's testimonial card, value for value
   (2px, rgba(211,216,217,0.4)). The radius stays 24px rather than their
   16px, because these cards are 637px wide against their 260px.
   Orange is left to the check chips, which is the only place on this
   section the accent appears. */
.pl-feature {
    display: flex;
    flex-direction: column;
    gap: 24px;
    padding: 24px;
    background-color: var(--bg-primary);
    border: 2px solid rgba(211, 216, 217, 0.4);
    border-radius: 24px;
    overflow: hidden;
}


/* --- Media ---
   16:10 at every width, and every screenshot is shot to that ratio at
   1600 x 1000. The white box and the light border are what let a
   screenshot with pale edges still read as a framed object sitting on
   the grey card. */

/* Same border as the card, one pixel instead of two: it is an inner
   frame, so it should read quieter than the thing containing it. */
.pl-feature-media {
    aspect-ratio: 16 / 10;
    overflow: hidden;
    background-color: var(--bg-primary);
    border: 1px solid rgba(211, 216, 217, 0.4);
    border-radius: 16px;
}

.pl-feature-media img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* --- Phone and browser variants ------------------------------------
   SECTION 2's mockups, value for value: step 3's phone shell
   (#1A1A1A, 28px radius, 7px padding, 54x6 notch, same triple shadow)
   and step 2's window bar. The screen is a real screenshot instead of
   a rebuilt UI. The phone is sized and offset in percentages so the
   bottom-edge crop survives every card width. */

.pl-feature-media--phone {
    position: relative;
    background-color: #F1F2F4;
}

.pl-fphone {
    position: absolute;
    bottom: -22%;
    left: 50%;
    transform: translateX(-50%);
    width: 40%;
    height: 115%;
    padding: 7px;
    border-radius: 28px;
    background-color: #1A1A1A;
    overflow: hidden;
    box-shadow: 0 4px 10px rgba(11, 20, 26, 0.1),
        0 18px 34px rgba(11, 20, 26, 0.14),
        0 40px 60px rgba(11, 20, 26, 0.1);
}

/*.pl-fphone-notch {
    position: absolute;
    top: 12px;
    left: 50%;
    width: 54px;
    height: 6px;
    border-radius: 4px;
    background-color: #000000;
    transform: translateX(-50%);
    z-index: 2;
}*/

.pl-fphone img {
    height: auto;
    border-radius: 21px;
}

.pl-fbrowser {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.pl-fbrowser-url {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1 1 auto;
    height: 20px;
    padding-inline: 9px;
    border-radius: 20px;
    background-color: var(--color-white);
    font-size: 11px;
    line-height: 1;
    color: #4A4A4A;
}

.pl-fbrowser-lock {
    flex: none;
    width: 12px;
    height: 12px;
    color: #1FA34A;
}

.pl-fbrowser img {
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
    object-fit: cover;
    object-position: top;
}

/* --- Title and checked lines --- */

.pl-feature-title {
    margin: 0 0 1rem;
    font-size: 1.4rem;
    font-weight: var(--font-semibold);
    line-height: 1.17;
    letter-spacing: -0.02em;
    color: #171717;
}

/* Type is SECTION 2's .pl-step-desc, value for value, so the card text
   and a step description read in the same voice. */
.pl-feature-text {
    margin: 0;
    font-size: 1rem;
    font-weight: var(--font-regular);
    line-height: 1.6;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}

/* --- The text drops in on first scroll ---
   platform.js adds .is-armed at init, so if the script never runs the
   text renders as plain content and CSS alone never hides it. Same
   vocabulary as the button label roll; one element now, so no stagger.
   The reveal is one shot, never replayed. */

/* The screens enter with the hero buttons' letter vocabulary: fade,
   sharpen and rise, one block instead of per letter. Media only —
   the text keeps its own drop from above. */
.pl-feature.is-armed .pl-feature-media {
    opacity: 0;
    filter: blur(6px);
    transform: translateY(14px);
}

.pl-feature.is-revealed .pl-feature-media {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
        opacity 0.6s cubic-bezier(0.22, 0.61, 0.36, 1),
        filter 0.6s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-feature.is-armed .pl-feature-text {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(-12px);
}

.pl-feature.is-revealed .pl-feature-text {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1),
        opacity 0.5s cubic-bezier(0.22, 0.61, 0.36, 1),
        filter 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-features {
        padding: 3rem;
    }

    /* One column, held at one card's desktop width instead of
       stretching to the container, as SECTION 2 does. */
    .pl-features-grid {
        grid-template-columns: 1fr;
        max-width: 640px;
        margin-inline: auto;
    }
}

@media (max-width: 768px) {

    .pl-features {
        padding: 2.5rem 1.5rem;
    }

    .pl-features-grid {
        gap: 1rem;
    }

    .pl-feature {
        gap: 20px;
        padding: 16px;
        border-radius: 20px;
    }

    .pl-feature-media {
        border-radius: 12px;
    }

    .pl-fphone {
        padding: 5px;
        border-radius: 26px;
    }

    .pl-feature-title {
        font-size: 1.25rem;
    }

    .pl-feature-text {
        font-size: 0.9375rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-feature.is-armed .pl-feature-media,
    .pl-feature.is-armed .pl-feature-text {
        opacity: 1;
        filter: none;
        transform: none;
    }
}

/* ===================================
   SECTION 6: INDUSTRIES
   Decorative pill row. No panels, no behaviour.
   =================================== */

.pl-industries {
    position: relative;
    background-color: var(--bg-secondary);
    padding: var(--container-section-padding);
    overflow: hidden;
}

.pl-industries .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

.pl-industry-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
}

.pl-industry-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.6rem 1.1rem;
    font-family: inherit;
    font-size: 0.9rem;
    font-weight: var(--font-medium);
    color: var(--text-45);
    background-color: var(--color-white);
    border: 1px solid var(--border-light);
    border-radius: 50px;
    cursor: default;
    white-space: nowrap;
    transition: all 0.3s ease;
}

.pl-industry-tab:hover {
    color: var(--color-primary-blue);
    border-color: var(--color-primary-blue);
}

.pl-industry-tab svg {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
}

.pl-industries-note {
    max-width: 700px;
    margin: 2rem auto 0;
    text-align: center;
    font-size: 0.9rem;
    color: var(--text-secondary);
    line-height: 1.6;
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-industries {
        padding: 3rem;
    }
}

@media (max-width: 768px) {

    .pl-industries {
        padding: 2.5rem 1.5rem;
    }

    /* Twelve pills would stack into six rows on a phone, so they scroll */
    .pl-industry-tabs {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        scrollbar-width: none;
    }

    .pl-industry-tabs::-webkit-scrollbar {
        display: none;
    }

    .pl-industry-tab {
        flex: 0 0 auto;
        font-size: 0.85rem;
        padding: 0.55rem 1rem;
    }
}

/* ===================================
   SECTION 7: PRICING
   Rebuilt Aug 19 on the reference's two offer cards. The main.css
   .pricing-card shell is no longer used here: the reference card is a
   different structure (head, price stack, pill CTA, bordered feature
   box), so the section owns its own .pl-plan family. Header moved onto
   .pl-title-block. Every value below is read from the reference:
   white card = gradient #ffffffdb->#fafafa, 1px #0000001c, radius 22,
   pad 42/40, gap 30; dark card = gradient #1a1a1af5->#1a1a1a, 1px
   #ef673947, orange glow shadow; cards row 1120px, gap 22px; feature
   box top border, 26px top pad; CTA 48px pill, 13px/700 uppercase.
   The billing switch is gone: two cards ARE the two billing periods.
   =================================== */

.pl-pricing {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
    overflow: hidden;
}

.pl-pricing .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

.pl-pricing .pl-title-block {
    margin-bottom: 2.25rem;
}

.pl-pricing .pl-title {
    font-size: 3.4rem;
    font-weight: var(--font-extrabold);
}


/* --- Proof chips row ---
   The reference's hero pills: light pill, orange rounded-square tile
   holding a white check, DM Sans 600 label. Tile is 18px with a 10px
   radius, check art 14px, pill 42px tall — all reference values. */

.pl-perks {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-bottom: 3rem;
}

.pl-perk {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    height: 42px;
    padding: 10px 18px;
    font-size: 0.875rem;
    font-weight: var(--font-semibold);
    letter-spacing: -0.02em;
    color: #474747;
    background-color: #F7F7F7;
    border: 1px solid rgba(34, 34, 34, 0.05);
    border-radius: 50px;
    white-space: nowrap;
}

/* The reference's middle chip is a different component, not a border
   tweak: white, borderless, and a seven-layer shadow whose first layer
   is the 1px ring. Values copied verbatim from the reference. */
.pl-perk--main {
    color: #1A1A1A;
    background-color: var(--color-white);
    border: none;
    box-shadow: 0 0 0 1px rgba(93, 94, 94, 0.1),
        0 1px 1px -0.5px rgba(70, 71, 74, 0.03),
        0 2px 2px -1px rgba(69, 70, 74, 0.04),
        0 3px 3px -1.5px rgba(66, 68, 71, 0.04),
        0 5px 5px -2.5px rgba(42, 51, 70, 0.03),
        0 10px 10px -5px rgba(62, 64, 66, 0.03),
        0 24px 24px -8px rgba(58, 59, 61, 0.03);
}

/* Morocco flag tile: same 18px slot as the check, Twemoji artwork.
   Static on purpose — the reference's flag never rotates either. */
.pl-perk-flag {
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
}

.pl-perk-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
    background-color: var(--pl-accent);
    border-radius: 10px;
}

.pl-perk-check svg {
    width: 14px;
    height: 14px;
}

/* Same 18px slot as the check, for a row that brings its own coloured
   icon instead of the accent tile. */
.pl-perk-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 18px;
    height: 18px;
}

.pl-perk-icon svg {
    width: 18px;
    height: 18px;
}

/* --- Row rotation, built by platform.js ---
   The reference rotates the whole row (icon + text) inside a clipped
   pill, and each variant of its chip component has a DIFFERENT fixed
   width — meaning the pill resizes to the label on show. Ours does
   both live: platform.js builds a one-row window holding a column of
   [row, alt row, clone-of-first], steps it up by 38px (18px row +
   20px margin), and animates the window's width to the incoming row's
   width on the same clock. Two invisible absolute ghosts exist only
   to be measured. All states live behind .is-rotating, added by JS,
   so CSS alone never hides a row. */

.pl-perk-window {
    position: relative;
    display: block;
    height: 18px;
    overflow: hidden;
    transition: width 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-perk-ghost {
    position: absolute;
    top: 0;
    inset-inline-start: 0;
    visibility: hidden;
    pointer-events: none;
}

.pl-perk-col {
    position: absolute;
    top: 0;
    inset-inline-start: 0;
    transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-perk-item {
    display: flex;
    align-items: center;
    gap: 9px;
    height: 18px;
    margin-bottom: 20px;
    white-space: nowrap;
}


/* --- The two cards ---
   Reference row: 1120px, 22px gap, cards top-aligned so the yearly
   card may run taller without stretching the monthly one. */

.pl-plans {
    display: flex;
    align-items: flex-start;
    gap: 22px;
    width: 1120px;
    max-width: 100%;
    margin: 0 auto;
}

.pl-plan {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 30px;
    flex: 1 0 0;
    padding: 42px 40px;
    background: linear-gradient(rgba(255, 255, 255, 0.86) 0%, #FAFAFA 100%);
    border: 1px solid rgba(0, 0, 0, 0.11);
    border-radius: 22px;
}

.pl-plan--year {
    background: linear-gradient(180deg, rgba(26, 26, 26, 0.96) 0%, #1A1A1A 164%);
    border-color: rgba(239, 103, 57, 0.28);
    box-shadow: 0 70px 120px -70px rgba(239, 103, 57, 0.85);
}


/* --- Card head: name then billing line, fixed height so the price
   rows of the two cards start level, as in the reference. --- */

.pl-plan-head {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    min-height: 72px;
}

.pl-plan-name {
    font-size: 1.25rem;
    font-weight: var(--font-bold);
    line-height: 1.15;
    color: #1A1A1A;
}

.pl-plan--year .pl-plan-name {
    color: var(--pl-accent);
}

.pl-plan-desc {
    font-size: 0.875rem;
    font-weight: var(--font-medium);
    line-height: 1.4;
    color: var(--text-secondary);
}

.pl-plan--year .pl-plan-desc {
    color: rgba(255, 255, 255, 0.48);
}


/* --- Price stack: struck old price + save chip (yearly only), the
   figure at the reference's 46px/700/-0.04em, then what is billed. --- */

.pl-plan-pricing {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: 100%;
}

/* The save badge sits where the sparks used to: the card's dead
   corner, offset by the card's own padding at every width. */
.pl-plan-save {
    position: absolute;
    top: 40px;
    inset-inline-end: 40px;
    padding: 0.3rem 0.8rem;
    font-size: 0.8125rem;
    font-weight: var(--font-bold);
    letter-spacing: 0.02em;
    color: #FFF;
    background-color: var(--pl-accent);
    border-radius: 50px;
}

.pl-plan-price {
    font-size: 2.875rem;
    font-weight: var(--font-bold);
    letter-spacing: -0.04em;
    line-height: 1;
    color: #1A1A1A;
}

.pl-plan--year .pl-plan-price {
    color: #FFF;
}

.pl-plan-currency {
    font-size: 1.5rem;
    font-weight: var(--font-bold);
    letter-spacing: -0.02em;
}

.pl-plan-billed {
    font-size: 0.875rem;
    font-weight: var(--font-medium);
    color: var(--text-tertiary);
}

.pl-plan--year .pl-plan-billed {
    color: rgba(255, 255, 255, 0.48);
}


/* --- CTA: the reference's 48px pill, uppercase 13px/700. Hosts the
   existing label roll, so hover behaves like every other button. --- */

.pl-plan-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 48px;
    padding: 0 28px;
    font-size: 0.8125rem;
    font-weight: var(--font-bold);
    letter-spacing: 0.2px;
    text-transform: uppercase;
    text-decoration: none;
    color: #1A1A1A;
    background-color: var(--color-white);
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 50px;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.pl-plan-cta:hover {
    transform: translateY(-1px);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.08);
}

.pl-plan-cta--accent {
    color: #FFF;
    background-color: var(--pl-accent);
    border-color: transparent;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 10px 20px rgba(0, 0, 0, 0.1);
}

.pl-plan-cta--accent:hover {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25), 0 14px 26px rgba(0, 0, 0, 0.16);
}


/* --- Feature list: the reference's bordered box, 26px above the first
   line. Checks are bare orange strokes, no circle chip. Lines reveal on
   scroll with the same vocabulary as the features section: platform.js
   arms them, so a failed script leaves all ten visible. --- */

.pl-plan-features {
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    width: 100%;
    padding-top: 26px;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
    list-style: none;
    margin: 0;
}

.pl-plan--year .pl-plan-features {
    border-top-color: rgba(255, 255, 255, 0.08);
}

.pl-plan-features li {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    line-height: 1.4;
    color: rgba(0, 0, 0, 0.55);
}

.pl-plan--year .pl-plan-features li {
    color: #FFF;
}

.pl-plan-features li svg {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    color: var(--pl-accent);
}

.pl-plan.is-armed .pl-plan-features li {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(-12px);
}

.pl-plan.is-revealed .pl-plan-features li {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        opacity 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        filter 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms);
}

.pl-plan-features li:nth-child(1) {
    --i: 0;
}

.pl-plan-features li:nth-child(2) {
    --i: 1;
}

.pl-plan-features li:nth-child(3) {
    --i: 2;
}

.pl-plan-features li:nth-child(4) {
    --i: 3;
}

.pl-plan-features li:nth-child(5) {
    --i: 4;
}

.pl-plan-features li:nth-child(6) {
    --i: 5;
}

.pl-plan-features li:nth-child(7) {
    --i: 6;
}

.pl-plan-features li:nth-child(8) {
    --i: 7;
}

.pl-plan-features li:nth-child(9) {
    --i: 8;
}

.pl-plan-features li:nth-child(10) {
    --i: 9;
}

.pl-plan-features li:nth-child(11) {
    --i: 10;
}


/* --- What the platform does, grouped --- */

.pl-highlights {
    margin-top: 4.5rem;
    padding-top: 3.5rem;
    border-top: 1px solid var(--border-light);
}

.pl-highlights-header {
    max-width: 680px;
    margin: 0 auto 2.5rem;
    text-align: center;
}

.pl-highlights-title {
    margin-bottom: 0.75rem;
    font-size: 1.5rem;
    font-weight: var(--font-bold);
    color: var(--text-primary);
}

.pl-highlights-text {
    font-size: 0.95rem;
    line-height: 1.7;
    color: var(--text-secondary);
}

.pl-highlights-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    align-items: start;
    gap: 1.5rem;
}

.pl-highlight-group {
    padding: 1.75rem;
    background-color: var(--bg-primary);
    border: 1px solid var(--border-light);
    border-radius: var(--radius-12);
}

.pl-group-title {
    margin-bottom: 1rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid var(--border-light);
    font-size: 1rem;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

.pl-group-list {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    list-style: none;
    font-size: 0.88rem;
    line-height: 1.5;
    color: var(--text-45);
}

.pl-group-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}

.pl-group-list li::before {
    content: "";
    flex-shrink: 0;
    width: 6px;
    height: 6px;
    margin-top: 0.45em;
    background-color: var(--color-success);
    border-radius: 50%;
}

/* ===================================
   PRICING ADD-ON CARD
   One wide card in the plan cards' skin, replacing the six-card
   services grid. The dark pill rides the top edge, which is why the
   card must NOT clip. The six keys are the industries-tab icon row
   with a dotted underline; each tooltip is a real element shown on
   :hover and :focus-within, so a phone tap opens it, a tap elsewhere
   closes it, and no script exists to fail.
   =================================== */

.pl-addon {
    position: relative;
    display: flex;
    align-items: center;
    gap: 48px;
    width: 1120px;
    max-width: 100%;
    margin: 68px auto 0;
    padding: 42px 40px;
    background: linear-gradient(rgba(255, 255, 255, 0.86) 0%, #FAFAFA 100%);
    border: 1px solid rgba(0, 0, 0, 0.11);
    border-radius: 22px;
}

.pl-addon-badge {
    position: absolute;
    top: -15px;
    left: 50%;
    transform: translateX(-50%);
    padding: 0.35rem 1rem;
    font-size: 0.8125rem;
    font-weight: var(--font-bold);
    letter-spacing: 0.02em;
    white-space: nowrap;
    color: #FFF;
    background-color: #1A1A1A;
    border-radius: 50px;
}

/* --- Left column: label chip, the range, its one-line explainer --- */

.pl-addon-intro {
    flex: 0 0 auto;
}

.pl-addon-chip {
    display: inline-block;
    margin-bottom: 1rem;
    padding: 0.3rem 0.7rem;
    font-size: 0.75rem;
    font-weight: var(--font-bold);
    letter-spacing: 0.04em;
    color: var(--text-secondary);
    background-color: #F7F7F7;
    border: 1px solid rgba(34, 34, 34, 0.05);
    border-radius: 8px;
}

.pl-addon-price {
    margin-bottom: 0.5rem;
    font-size: 2.875rem;
    font-weight: var(--font-bold);
    letter-spacing: -0.04em;
    line-height: 1;
    color: #1A1A1A;
}

.pl-addon-currency {
    font-size: 1.25rem;
    letter-spacing: -0.02em;
}

.pl-addon-note {
    font-size: 0.875rem;
    font-weight: var(--font-regular);
    color: rgba(0, 0, 0, 0.55);
}

/* --- The six keys, two columns, industries-tab icon rows --- */

/* Columns size to their content and the pair is centred in the
   remaining width, which is what puts the two lists shoulder to
   shoulder as in the reference layout instead of stretched apart. */
.pl-addon-keys {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    justify-content: center;
    gap: 0.875rem 2.75rem;
    flex: 1 1 auto;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pl-addon-key {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0;
    font-family: inherit;
    font-size: 0.9375rem;
    font-weight: var(--font-regular);
    color: var(--text-primary);
    background: none;
    border: none;
    cursor: help;
    text-align: start;
}

/* stroke-width is a presentation attribute, so this CSS wins over the
   2 in the markup: the rows read regular, matching the de-bolded text. */
.pl-addon-key svg {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    stroke-width: 1.5;
    color: var(--text-45);
}

/* The "small light dots" underline that says: touch me. */
.pl-addon-key-text {
    border-bottom: 1px dotted var(--border-medium);
    padding-bottom: 1px;
}

/* --- Tooltip: dark bubble above the key. A real element, so nothing
   depends on generated content; hidden by opacity and disarmed by
   pointer-events, never display:none, so it can fade. --- */

.pl-addon-tip {
    position: absolute;
    bottom: calc(100% + 12px);
    inset-inline-start: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.55rem;
    width: max-content;
    max-width: 280px;
    padding: 1.1rem;
    text-align: start;
    background-color: var(--color-white);
    border-radius: 16px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06),
        0 18px 40px rgba(0, 0, 0, 0.14);
    opacity: 0;
    transform: translateY(4px);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease;
}

/* The icon tile at the bubble's top: the key's own icon in its own
   grey, on white, held by a grey ring. */
.pl-addon-tip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    color: var(--text-45);
    background-color: var(--color-white);
    border: 1px solid var(--border-medium);
    border-radius: 10px;
}

.pl-addon-tip-icon svg {
    width: 18px;
    height: 18px;
    stroke-width: 1.5;
}

.pl-addon-tip-title {
    font-size: 0.9375rem;
    font-weight: var(--font-bold);
    line-height: 1.3;
    color: #1A1A1A;
}

.pl-addon-tip-text {
    font-size: 0.8125rem;
    font-weight: var(--font-regular);
    line-height: 1.55;
    color: var(--text-secondary);
}

.pl-addon-key:hover .pl-addon-tip,
.pl-addon-key:focus-visible .pl-addon-tip,
.pl-addon-key:focus .pl-addon-tip {
    opacity: 1;
    transform: translateY(0);
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-pricing {
        padding: 3rem;
    }

    .pl-plan--year {
        box-shadow: 0 55px 90px -75px rgba(239, 103, 57, 0.7);
    }

    /* Two classes, because the base size is set at .pl-pricing .pl-title
       and a media query adds no specificity: without the prefix here,
       the 3.4rem base would win at every width. Values = .pl-title's. */
    .pl-pricing .pl-title {
        font-size: 2.5rem;
    }

    .pl-addon {
        flex-direction: column;
        align-items: flex-start;
        gap: 28px;
    }
}

@media (max-width: 768px) {

    .pl-pricing {
        padding: 2.5rem 1.5rem;
    }

    /* Reference stacks the cards below 810px: column, tighter gap and
       padding, softer glow on the dark card. */
    .pl-plans {
        flex-direction: column;
        gap: 18px;
    }

    .pl-plan {
        width: 100%;
        padding: 32px 28px;
    }

    .pl-plan--year {
        box-shadow: 0 45px 75px -60px rgba(239, 103, 57, 0.65);
    }

    .pl-pricing .pl-title {
        font-size: 2rem;
    }

    .pl-plan-save {
        top: 30px;
        inset-inline-end: 28px;
    }

    .pl-plan-head {
        min-height: 0;
    }

    .pl-plan-price {
        font-size: 2.125rem;
    }

    .pl-addon {
        margin-top: 52px;
        padding: 32px 28px;
    }

    .pl-addon-keys {
        grid-template-columns: 1fr;
    }

    /* One column of keys means a tooltip can escape the viewport on
       neither side; pin it to the key's start and cap it to the card. */
    .pl-addon-tip {
        max-width: min(260px, 78vw);
    }
}

/* ===================================
   SHARED: hand-drawn underline
   =================================== */

.pl-underline {
    position: relative;
    display: inline-block;
    color: var(--color-primary-blue);
    font-weight: var(--font-extrabold);
}

.pl-underline-stroke {
    position: absolute;
    inset-inline: 0;
    bottom: -0.35em;
    width: 100%;
    height: 0.38em;
    overflow: visible;
}


/* ===================================
   SECTION: COMPARE
   =================================== */

.pl-compare {
    background-color: var(--bg-secondary);
    padding: var(--container-section-padding);
}

.pl-compare .container {
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

.pl-compare .pl-section-header {
    margin-bottom: 2.5rem;
}

.pl-compare-table {
    max-width: 1080px;
    margin: 0 auto;
}

.pl-compare-row {
    display: grid;
    grid-template-columns: 1.2fr 1fr 1fr 1.15fr;
    border-bottom: 1px solid var(--border-light);
}

.pl-compare-cell {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 1.25rem 1rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.pl-compare-cell svg {
    flex-shrink: 0;
}

.pl-compare-cell--label {
    padding-inline-start: 0;
    color: var(--text-primary);
    font-weight: var(--font-semibold);
}

.pl-compare-cell--head {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    gap: 0.25rem;
    font-size: 1.05rem;
    font-weight: var(--font-bold);
    color: var(--text-primary);
}

.pl-compare-logo {
    width: 130px;
    height: auto;
}

.pl-compare-cell--us {
    background-color: var(--color-info-light);
    border-inline: 1px solid rgba(32, 125, 233, 0.35);
    padding-inline: 1.25rem;
    color: var(--text-primary);
    font-weight: var(--font-medium);
}

.pl-compare-cell--head.pl-compare-cell--us {
    color: var(--color-primary-blue);
    border-top: 1px solid rgba(32, 125, 233, 0.35);
    border-start-start-radius: 12px;
    border-start-end-radius: 12px;
}

.pl-compare-row:last-child {
    border-bottom: none;
}

.pl-compare-row:last-child .pl-compare-cell--us {
    border-bottom: 1px solid rgba(32, 125, 233, 0.35);
    border-end-start-radius: 12px;
    border-end-end-radius: 12px;
}

.pl-compare-who {
    display: none;
}

/* --- Responsive --- */

@media (max-width: 1024px) {
    .pl-compare-cell {
        padding: 1rem 0.75rem;
        font-size: 0.9rem;
    }

    .pl-compare-cell--head {
        font-size: 0.95rem;
    }
}

@media (max-width: 768px) {
    .pl-compare {
        padding: 2.5rem 1.5rem;
    }

    .pl-compare-row--head {
        display: none;
    }

    .pl-compare-row {
        grid-template-columns: 1fr;
        gap: 0.5rem;
        padding: 1.25rem 0;
    }

    .pl-compare-cell {
        padding: 0;
        align-items: flex-start;
    }

    .pl-compare-cell--label {
        margin-bottom: 0.25rem;
        font-size: 1rem;
    }

    .pl-compare-who {
        display: inline-block;
        flex: 0 0 6.5rem;
        font-weight: var(--font-semibold);
        color: var(--text-primary);
    }

    .pl-compare-cell--us {
        border: 1px solid rgba(32, 125, 233, 0.35);
        border-radius: 8px;
        padding: 0.6rem 0.75rem;
    }
}

/* ===================================
   SECTION 0: FIXED HEADER (pill)
   Landing page only. Reuses main.css .nav-links, .nav-right,
   .language-*, .cta-button, .hamburger-menu and .menu-overlay, so
   main.js initLanguageHandler + initMobileMenu run unchanged.
   Geometry from the 1600 reference: pill gap 22px, padding
   8px 8px 8px 44px, nav gap 20px, buttons 48px, WhatsApp 65px,
   badge dot 14px at the wrapper's top-right corner.
   Header height: 101px desktop, 80px at 1024 and below. The hero
   offsets and the scroll-margin rule below both depend on those.
   =================================== */

.pl-header {
    position: fixed;
    inset-inline: 0;
    top: 0;
    z-index: 100;
    display: flex;
    justify-content: center;
    padding: 20px 3rem 0;
    /* The strip either side of the pill must not swallow hero clicks */
    pointer-events: none;
}

.pl-header-pill,
.pl-header .menu-overlay {
    pointer-events: auto;
}

.pl-header-pill {
    display: flex;
    align-items: center;
    gap: 22px;
    width: 100%;
    max-width: 1200px;
    padding-block: 8px;
    padding-inline: 30px 8px;
    background-color: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-radius: 60px;
    /* First layer is a 1px hairline ring, the rest is a soft stacked lift */
    box-shadow: rgba(93, 94, 94, 0.1) 0 0 0 1px,
        rgba(70, 71, 74, 0.03) 0 1px 1px -0.5px,
        rgba(69, 70, 74, 0.04) 0 2px 2px -1px,
        rgba(66, 68, 71, 0.04) 0 3px 3px -1.5px,
        rgba(42, 51, 70, 0.03) 0 5px 5px -2.5px,
        rgba(62, 64, 66, 0.03) 0 10px 10px -5px,
        rgba(58, 59, 61, 0.03) 0 24px 24px -8px;
}


/* --- Brand --- */
/* Sized here, not by main.css's .header-logo, whose 34px mobile rule
   would fight these values. */

.pl-header-brand {
    display: flex;
    flex-shrink: 0;
}

.pl-header-brand img {
    display: block;
    /* The cart's wheels sit 20% of the logo's height below the wordmark, so
       centering the box lifts the word. Nudge it back down. */
    transform: translateY(14%);
    width: auto;
    height: 30px;
    /* 38px = the footer mark. The wordmark is 5.46:1 where the old logo
       was 4.18:1, so the previous 44px rendered 30% wider. */
}


/* --- Nav --- */

.pl-header-nav {
    flex: 1 1 0;
}

.pl-header .nav-links {
    gap: 20px;
}

.pl-header .nav-links a {
    font-size: 1rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.01em;
    color: #505050;
    transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
}

.pl-header .nav-links a:hover {
    color: #7a7a7a;
}


/* --- Right group --- */

.pl-header .nav-right {
    flex-shrink: 0;
    gap: 10px;
}

.pl-header .hamburger-menu {
    flex-shrink: 0;
}


/* --- Language --- */

.pl-header .language-btn {
    height: 48px;
    padding: 0 1rem;
    gap: 0.5rem;
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.01em;
    color: #1A1A1A;
    background-color: var(--color-white);
    border: 1px solid rgba(0, 0, 0, 0.12);
    border-radius: 50px;
    transition: border-color 0.3s ease;
}

.pl-header .language-btn:hover {
    color: #1A1A1A;
    border-color: rgba(0, 0, 0, 0.28);
}

/* Twemoji flags are square with transparent padding, not 3:2 rectangles */
.pl-flag {
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    object-fit: contain;
}

.pl-caret {
    flex-shrink: 0;
}

.pl-header .language-dropdown {
    top: calc(100% + 0.5rem);
    border-radius: var(--radius-12);
}


/* --- CTA + badge dot --- */
/* The dot sits on a wrapper, not the button: .cta-button is
   overflow:hidden for its shine sweep and would clip it. Position is
   the reference's own: the wrapper's top-right corner, which falls
   just outside a 50px-radius pill. */

/* Flex, not block: a block wrapper around an inline-level anchor gets a
   taller line box than the 48px button, which lifts the badge off the
   button's real top edge. */
.pl-cta-wrap {
    position: relative;
    display: flex;
    flex-shrink: 0;
}

.pl-header .pl-cta {
    height: 48px;
    padding: 0 28px;
    font-size: 0.875rem;
    font-weight: var(--font-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    white-space: nowrap;
    color: #EFEFEF;
    background-color: #1A1A1A;
    border-radius: 50px;
}

.pl-header .pl-cta:hover {
    color: var(--color-white);
    background-color: #1A1A1A;
}

/* main.css line 499 sweeps a white diagonal gradient across .cta-button
   on hover. That is the agency site's blue-button treatment; this
   button rolls its label instead. */
.pl-header .pl-cta::before,
.pl-header .pl-cta:hover::before {
    display: none;
}

.pl-cta-dot {
    position: absolute;
    z-index: 2;
    top: 0;
    inset-inline-end: 0;
    width: 14px;
    height: 14px;
    background-color: rgb(255, 88, 88);
    border: 1px solid var(--color-white);
    border-radius: 100%;
}


/* --- WhatsApp --- */
/* Three nested circles, per the reference: a 65px outer ring holding a
   faint green hairline, a pulsing circle behind, and the real 50px
   button on top. The 65px box is the tallest child of the pill, so it
   is what sets the header's 101px height.
   Both pseudo-elements centre with translate(-50%,-50%), so every
   transform on them must repeat it or they jump to the corner. */

.pl-header-wa {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 65px;
    height: 65px;
    color: var(--color-white);
    border: 1px solid rgba(47, 250, 61, 0.3);
    border-radius: 50%;
}

/* Pulse, between the ring and the button */
.pl-header-wa::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 50px;
    height: 50px;
    background-color: rgb(27, 199, 57);
    border-radius: 50%;
    transform: translate(-50%, -50%) scale(1);
    will-change: transform;
    animation: pl-wa-pulse 2.4s ease-out infinite;
}

/* The button. A real element, not ::after, because it needs its own
   clipped child for the hover fill. */
.pl-wa-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    background-color: rgb(37, 211, 102);
    border: 1px solid rgb(1, 130, 49);
    border-radius: 50%;
    box-shadow: rgba(37, 211, 102, 0.2) 5px 15px 30px 0,
        rgb(37, 211, 102) 0 1px 6px -2px;
    transform: translate(-50%, -50%);
    overflow: hidden;
}

/* Fill parked directly below, rising to flood the circle on hover.
   Travel = half the button height + half the fill height. */
.pl-wa-btn::before {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    width: 108px;
    height: 108px;
    background-color: var(--color-white);
    border-radius: 50%;
    transform: translateX(-50%);
    transition: transform 0.5s cubic-bezier(0.44, 0, 0.56, 1);
}

.pl-header-wa:hover .pl-wa-btn::before {
    transform: translateX(-50%) translateY(-79px);
}

.pl-header-wa svg {
    position: relative;
    z-index: 1;
    width: 24px;
    height: 24px;
    transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
}

.pl-header-wa:hover svg {
    color: rgb(37, 211, 102);
}

@keyframes pl-wa-pulse {
    0% {
        transform: translate(-50%, -50%) scale(1);
        opacity: 0.95;
    }

    100% {
        transform: translate(-50%, -50%) scale(1.3);
        opacity: 0;
    }
}


/* --- Anchor targets must clear the fixed pill --- */

#services,
#how-it-works,
#features,
#industries,
#pricing,
#compare,
#faq {
    scroll-margin-top: 116px;
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-header {
        padding: 16px 3rem 0;
    }

    .pl-header-pill {
        gap: 12px;
        padding: 8px 12px 8px 20px;
    }

    /* main.css already hides .nav-links and .nav-right .cta-button here;
       their wrappers must go too or they keep their flex space. */
    .pl-header-nav,
    .pl-header-pill .pl-cta-wrap {
        display: none;
    }

    /* Hidden in the pill, shown inside the open menu card */
    .pl-header-pill .language-selector {
        display: none;
    }

    /* .pl-header-nav carried flex:1 and is hidden here, so nothing is
       left to push this group to the pill's right edge. */
    .pl-header .nav-right {
        gap: 15px;
        margin-inline-start: auto;
    }

    .pl-header-brand img {
        height: 26px;
    }

    .pl-header-wa {
        width: 48px;
        height: 48px;
    }

    .pl-header-wa::before,
    .pl-wa-btn {
        width: 38px;
        height: 38px;
    }

    .pl-header-wa:hover .pl-wa-btn::before {
        transform: translateX(-50%) translateY(-73px);
    }

    .pl-header-wa svg {
        width: 20px;
        height: 20px;
    }

    #services,
    #how-it-works,
    #features,
    #industries,
    #pricing,
    #compare,
    #faq {
        scroll-margin-top: 96px;
    }
}

@media (max-width: 768px) {

    .pl-header {
        padding: 16px 1.5rem 0;
    }

    /* Symmetric here: the last element is a flat burger icon, not the
       desktop's 65px circle whose curve absorbs a smaller right pad. */
    .pl-header-pill {
        padding: 8px 16px;
    }

    .pl-header-brand img {
        height: 24px;
    }
}

/* ===================================
   HEADER: MOBILE MENU PANEL
   Restyles main.css's .menu-overlay to read as the header pill
   expanded downward, per the 1600 reference. Scoped under .pl-header
   so the other 15 pages keep their bottom-sheet menu.
   main.js initMobileMenu drives it unchanged.
   =================================== */

@media (max-width: 1024px) {

    /* Colour and blur live in the animation block, which toggles them
       with .active. Setting them here would be overridden anyway, and
       the blur would stay live while the menu is closed. */
    .pl-header .menu-overlay {
        justify-content: flex-start;
        align-items: center;
        padding-block-start: 16px;
        padding-inline: 3rem;
    }

    .pl-header .mobile-menu {
        width: 100%;
        max-width: 1200px;
        padding: 0 20px 10px;
        margin-bottom: 0;
        background-color: rgba(255, 255, 255, 0.97);
        border-radius: 30px;
        box-shadow: rgba(93, 94, 94, 0.1) 0 0 0 1px,
            rgba(62, 64, 66, 0.06) 0 10px 10px -5px,
            rgba(58, 59, 61, 0.06) 0 24px 24px -8px;
    }

    .pl-header .mobile-menu ul {
        align-items: flex-start;
        gap: 0;
    }

    .pl-header .mobile-menu li {
        text-align: start;
    }

    /* Scoped to the list: unscoped, this outranks .pl-header .pl-cta
       (0-2-1 vs 0-2-0) and strips the CTA's padding and white label.
       Keeping it off the dropdown also lets the language options keep
       their desktop styling from main.css. */
    .pl-header .mobile-menu ul a {
        padding: 10px 0;
        font-size: 1rem;
        font-weight: var(--font-medium);
        letter-spacing: -0.01em;
        color: #505050;
        transition: color 0.4s cubic-bezier(0.44, 0, 0.56, 1);
    }

    .pl-header .mobile-menu ul a:hover {
        color: #7a7a7a;
    }

    /* fit-content because .mobile-menu is a block container: a full-width
       div would send the right-aligned dropdown to the card's edge.
       z-index 3 clears the CTA below, which .cta-button puts at 1 and
       the badge dot at 2. */
    .mobile-menu .language-selector {
        position: relative;
        z-index: 3;
        width: fit-content;
        margin-block-start: 12px;
    }

    /* Opens upward: the card is overflow:hidden for the collapse
       animation, so a downward dropdown gets clipped at the card's
       bottom edge. There is room above the button. */
    .mobile-menu .language-dropdown {
        top: auto;
        bottom: calc(100% + 0.5rem);
        inset-inline-start: 0;
        right: auto;
    }

    /* main.css line 4186 paints .mobile-menu li:last-child a as a blue
       button, written when the CTA was the last <li>. The CTA is its own
       block now, so that rule lands on FAQ and must be undone. */
    .pl-header .mobile-menu li:last-child a {
        display: block;
        height: auto;
        padding: 10px 0;
        margin-top: 0;
        font-weight: var(--font-medium);
        color: #505050;
        background-color: transparent;
        border-radius: 0;
    }

    /* Width comes from the button, not the card: a block wrapper would
       stretch full width and take the badge to the card's edge. */
    .pl-menu-cta {
        width: fit-content;
        margin-block-start: 20px;
    }

    /* main.css .mobile-menu a sets display:block (0-1-1), which outranks
       .cta-button (0-1-0) and drops the flex centring. */
    .pl-menu-cta .pl-cta {
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Logo row: becomes the card's top bar, sitting exactly where the
       pill's own bar was, so the two read as one object. Height matches
       the pill's 64px. */
    .pl-menu-top {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 64px;
    }

    .pl-menu-top img {
        transform: translateY(14%);
        width: auto;
        height: 26px;
    }

    /* Static now: the button sits in the row's flow, not over the card */
    .pl-header .menu-close {
        position: static;
        display: flex;
        align-items: center;
    }

    .pl-header .menu-close img {
        width: 40px;
        height: 40px;
    }
}

@media (max-width: 768px) {

    .pl-header .menu-overlay {
        padding-inline: 1.5rem;
    }

    .pl-menu-top img {
        height: 24px;
    }
}

/* ===================================
   HEADER: MOBILE MENU ANIMATION
   The card's top 64px sits exactly over the pill and is always opaque,
   so what the eye sees is the header itself growing: only the bottom
   edge moves. Rows fade up in sequence behind it.
   The overlay stays display:flex and toggles visibility instead, since
   display cannot be transitioned and would snap the close animation.
   =================================== */

@media (max-width: 1024px) {

    /* Always laid out, never display:none, so both directions animate.
       visibility is delayed out by the full duration so the card stays
       on screen while it collapses, then hides. pointer-events keeps
       the invisible overlay from swallowing clicks on the page. */
    .pl-header .menu-overlay {
        display: flex;
        visibility: hidden;
        pointer-events: none;
        opacity: 1;
        background-color: transparent;
        transition: background-color 0.4s ease,
            visibility 0s linear 0.45s;
    }

    .pl-header .menu-overlay.active {
        visibility: visible;
        pointer-events: auto;
        background-color: rgba(19, 19, 19, 0.25);
        backdrop-filter: blur(2px);
        -webkit-backdrop-filter: blur(2px);
        transition: background-color 0.4s ease,
            visibility 0s linear 0s;
    }

    /* Only the bottom edge moves */
    .pl-header .mobile-menu {
        max-height: 64px;
        overflow: hidden;
        transition: max-height 0.45s cubic-bezier(0.44, 0, 0.56, 1);
    }

    .pl-header .menu-overlay.active .mobile-menu {
        max-height: 600px;
    }

    /* Rows arrive in order, behind the growing edge */
    .pl-header .mobile-menu ul li,
    .pl-header .mobile-menu .language-selector,
    .pl-header .mobile-menu .pl-menu-cta {
        opacity: 0;
        transform: translateY(10px);
        transition: opacity 0.35s ease,
            transform 0.35s cubic-bezier(0.44, 0, 0.56, 1);
    }

    .pl-header .menu-overlay.active .mobile-menu ul li,
    .pl-header .menu-overlay.active .mobile-menu .language-selector,
    .pl-header .menu-overlay.active .mobile-menu .pl-menu-cta {
        opacity: 1;
        transform: translateY(0);
    }

    .pl-header .menu-overlay.active .mobile-menu ul li:nth-child(1) {
        transition-delay: 0.10s;
    }

    .pl-header .menu-overlay.active .mobile-menu ul li:nth-child(2) {
        transition-delay: 0.15s;
    }

    .pl-header .menu-overlay.active .mobile-menu ul li:nth-child(3) {
        transition-delay: 0.20s;
    }

    .pl-header .menu-overlay.active .mobile-menu ul li:nth-child(4) {
        transition-delay: 0.25s;
    }

    .pl-header .menu-overlay.active .mobile-menu ul li:nth-child(5) {
        transition-delay: 0.30s;
    }

    .pl-header .menu-overlay.active .mobile-menu .language-selector {
        transition-delay: 0.35s;
    }

    .pl-header .menu-overlay.active .mobile-menu .pl-menu-cta {
        transition-delay: 0.40s;
    }

    /* Burger to X: the card's X sits where the burger was, rotating in */
    .pl-header .menu-close img {
        opacity: 0;
        transform: rotate(-90deg);
        transition: opacity 0.25s ease,
            transform 0.4s cubic-bezier(0.44, 0, 0.56, 1);
    }

    .pl-header .menu-overlay.active .menu-close img {
        opacity: 1;
        transform: rotate(0deg);
        transition-delay: 0.08s;
    }
}

/* ===================================
   HEADER: REDUCED MOTION
   Every header animation, switched off in one place.
   =================================== */

@media (prefers-reduced-motion: reduce) {

    .pl-header .menu-overlay,
    .pl-header .mobile-menu,
    .pl-header .mobile-menu ul li,
    .pl-header .mobile-menu .language-selector,
    .pl-header .mobile-menu .pl-menu-cta,
    .pl-header .menu-close img {
        transition: none;
    }

    .pl-header-wa::before {
        animation: none;
        opacity: 0;
    }
}

/* ===================================
   SECTION 8: FAQ
   Built Aug 20 2026. Two columns of grouped questions, the GetHookd
   structure: an icon plus a group title, then the questions of that
   group as cards. The card values are the page's own: SECTION 2's
   grey card on a white section, the features border, and the pricing
   chip's tile for the chevron. Open state is the reference's white
   variant with the seven-layer ring shadow, the same component the
   middle proof chip uses, so an open answer LIFTS off the section
   instead of changing colour.
   No overflow:hidden on the section: that shadow must not be clipped.
   =================================== */

.pl-faq {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
}

.pl-faq .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

/* The subtitle now carries the email and the WhatsApp link. Accent
   coloured, underlined only on hover, so the sentence still reads as a
   sentence. */
.pl-faq .pl-subtitle a {
    color: var(--pl-accent);
    font-weight: var(--font-semibold);
    text-decoration: none;
}

.pl-faq .pl-subtitle a:hover {
    text-decoration: underline;
}


/* --- Two columns, groups stacked inside them ---
   Left column carries two groups, right column one, which is what
   keeps the two sides roughly level: the right group's answers are
   the long ones. */

.pl-faq-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 64px;
    align-items: start;
}

.pl-faq-col {
    display: flex;
    flex-direction: column;
    gap: 48px;
}

/* --- Group heading: icon then title, the add-on keys' icon style
   (stroke 1.5, --text-45) one size up. --- */

.pl-faq-group-title {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0 0 1.25rem;
    font-size: 1.375rem;
    font-weight: var(--font-semibold);
    line-height: 1.2;
    letter-spacing: -0.02em;
    color: #1A1A1A;
}

/* stroke-width is a presentation attribute, so this wins over the 2
   in the markup, exactly as the add-on keys do it. */
.pl-faq-group-title svg {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    stroke-width: 1.7;
    color: var(--text-45);
}


/* --- One question card --- */

.pl-faq-item {
    background-color: var(--bg-secondary);
    border: 1px solid rgba(211, 216, 217, 0.4);
    border-radius: 16px;
    transition: background-color 0.3s ease,
        border-color 0.3s ease,
        box-shadow 0.3s ease;
}

.pl-faq-item+.pl-faq-item {
    margin-top: 10px;
}

/* Open: the reference's white chip component. The border stays at 1px
   and only loses its colour, so the card never changes size when the
   ring shadow arrives. */
.pl-faq-item.is-open {
    background-color: var(--color-white);
    border-color: transparent;
    box-shadow: 0 0 0 1px rgba(93, 94, 94, 0.1),
        0 1px 1px -0.5px rgba(70, 71, 74, 0.03),
        0 2px 2px -1px rgba(69, 70, 74, 0.04),
        0 3px 3px -1.5px rgba(66, 68, 71, 0.04),
        0 5px 5px -2.5px rgba(42, 51, 70, 0.03),
        0 10px 10px -5px rgba(62, 64, 66, 0.03),
        0 24px 24px -8px rgba(58, 59, 61, 0.03);
}

.pl-faq-q {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    padding: 18px 20px;
    font-family: inherit;
    font-size: 1rem;
    font-weight: var(--font-medium);
    line-height: 1.35;
    letter-spacing: -0.02em;
    color: #1A1A1A;
    text-align: start;
    background: none;
    border: none;
    cursor: pointer;
}

/* The chevron tile is the pricing chip's skin: #F7F7F7 with the 5%
   ring. Open flips it to the accent, which is the only orange in this
   section. */
.pl-faq-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 30px;
    height: 30px;
    color: var(--text-45);
    background-color: #FFF;
    border: 1px solid rgba(211, 216, 217, 0.4);
    border-radius: 10px;
    transition: color 0.3s ease,
        background-color 0.3s ease,
        border-color 0.3s ease,
        transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-faq-icon svg {
    width: 16px;
    height: 16px;
}

.pl-faq-item.is-open .pl-faq-icon {
    color: var(--color-white);
    background-color: var(--pl-accent);
    border-color: transparent;
    transform: rotate(180deg);
}


/* --- The answer ---
   Animated on grid-template-rows, not max-height: the row measures the
   real text, so a four-line answer and a one-line answer both open at
   the same speed and nothing is capped.
   The closed state lives behind .is-armed, which platform.js adds. No
   script means every answer is simply open and readable. */

.pl-faq-a {
    display: grid;
    grid-template-rows: 1fr;
    transition: grid-template-rows 0.35s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.pl-faq.is-armed .pl-faq-a {
    grid-template-rows: 0fr;
}

.pl-faq.is-armed .pl-faq-item.is-open .pl-faq-a {
    grid-template-rows: 1fr;
}

/* min-height:0 is what lets a grid row actually collapse to zero. */
.pl-faq-a-inner {
    min-height: 0;
    overflow: hidden;
}

.pl-faq-a p {
    margin: 0;
    padding: 0 20px 20px;
    font-size: 0.9375rem;
    font-weight: var(--font-regular);
    line-height: 1.65;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-faq {
        padding: 3rem;
    }

    /* One column, held at the features section's width so the page
       keeps one measure below the breakpoint. */
    .pl-faq-grid {
        grid-template-columns: 1fr;
        gap: 48px;
        max-width: 640px;
        margin-inline: auto;
    }
}

@media (max-width: 768px) {

    .pl-faq {
        padding: 2.5rem 1.5rem;
    }

    .pl-faq-col {
        gap: 40px;
    }

    .pl-faq-group-title {
        font-size: 1.25rem;
    }

    .pl-faq-q {
        padding: 16px;
        font-size: 0.95rem;
    }

    .pl-faq-icon {
        width: 28px;
        height: 28px;
    }

    .pl-faq-a p {
        padding: 0 16px 16px;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-faq-item,
    .pl-faq-icon,
    .pl-faq-a {
        transition: none;
    }
}

/* ===================================
   SECTION 9: CLOSING CTA BAND
   Built Aug 20 2026. A dark card inside a white section, on the
   yearly plan card's skin (same gradient, same orange border, same
   glow) so the page closes with the element it wants you to buy.
   The light beam is the appkittie device, drawn in CSS: a bright bar
   on the top edge and a cone widening below it.
   overflow:hidden IS allowed here, unlike the pricing add-on card:
   the cone must be clipped by the card, and a card's own box-shadow
   is never clipped by its own overflow.
   =================================== */

.pl-cta-band {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
}

.pl-cta-band .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

.pl-cta-card {
    position: relative;
    overflow: hidden;
    padding: 108px 40px 96px;
    text-align: center;
    background: linear-gradient(180deg, rgba(26, 26, 26, 0.96) 0%, #1A1A1A 164%);
    border: 1px solid rgba(239, 103, 57, 0.28);
    border-radius: 32px;
    box-shadow: 0 70px 120px -80px rgba(239, 103, 57, 0.7);
}


/* --- The light ---
   One layer, no bar and no cone. A soft radial halo hanging from the
   top edge of the card, clipped by the card's own overflow. The
   clip-path cone that used to sit under this was removed on Aug 20:
   even blurred, it read as a long streak down the card. Nothing here
   has an edge, so nothing needs a filter. */

.pl-cta-beam {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    z-index: 0;
    width: min(900px, 108%);
    height: 520px;
    pointer-events: none;
    background: radial-gradient(46% 64% at 50% 0%,
            rgba(251, 105, 48, 0.4) 0%,
            rgba(251, 105, 48, 0.15) 38%,
            rgba(251, 105, 48, 0.04) 66%,
            rgba(251, 105, 48, 0) 82%);
}


/* --- Content ---
   .pl-title and .pl-subtitle are used bare, without .pl-title-block,
   so the shared responsive sizes keep working and only the colours
   and the spacing are set here. */

.pl-cta-inner {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: 760px;
    margin: 0 auto;
}

.pl-cta-band .pl-title {
    margin: 0;
    color: var(--color-white);
}

.pl-cta-band .pl-subtitle {
    color: rgba(255, 255, 255, 0.62);
}

.pl-cta-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin-top: 0.75rem;
}


/* --- Two more variants of the hero button, for a dark surface.
   Base geometry, the label roll and the hover timing all come from
   .pl-hero-btn, so nothing is duplicated and no new JS is needed. --- */

/* The hero's primary button inverted: there it is a black pill with an
   orange chip on a white page, here it is a white pill with the same
   orange chip on a dark card. Chip geometry is the hero's exactly
   (38px circle, 6px of pill beside it), so the two read as one
   component. */
.pl-hero-btn--solid {
    padding-block: 0;
    padding-inline: 28px 6px;
    color: #1A1A1A;
    background-color: var(--color-white);
    border: 1px solid var(--color-white);
}

.pl-hero-btn--solid:hover {
    color: #1A1A1A;
    background-color: #F1F1F1;
    border-color: #F1F1F1;
}

/* Scale rather than a nudge along X, because a nudge would point the
   wrong way on the Arabic page. */
.pl-cta-arrow {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    color: var(--color-white);
    background-color: var(--pl-accent);
    border-radius: 50%;
    transition: transform 0.3s ease;
}

.pl-cta-arrow svg {
    width: 18px;
    height: 18px;
}

.pl-hero-btn--solid:hover .pl-cta-arrow {
    transform: scale(1.09);
}

.pl-hero-btn--light {
    color: var(--color-white);
    background-color: transparent;
    border: 1px solid rgba(255, 255, 255, 0.25);
}

.pl-hero-btn--light:hover {
    color: var(--color-white);
    background-color: rgba(255, 255, 255, 0.08);
    border-color: rgba(255, 255, 255, 0.45);
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-cta-band {
        padding: 3rem;
    }

    .pl-cta-card {
        padding: 84px 32px 72px;
        border-radius: 28px;
        box-shadow: 0 55px 90px -80px rgba(239, 103, 57, 0.6);
    }
}

@media (max-width: 768px) {

    .pl-cta-band {
        padding: 2.5rem 1.5rem;
    }

    .pl-cta-card {
        padding: 64px 20px 56px;
        border-radius: 24px;
    }

    .pl-cta-beam {
        width: 118%;
        height: 380px;
    }

    .pl-cta-inner {
        gap: 1rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-cta-arrow {
        transition: none;
    }
}

/* ===================================
   FOOTER (this page only)
   Built Aug 20 2026 on the 1600.agency footer, values read from the
   reference: 60px block padding, logo row with the links and the
   social icons opposite it, a wrapped city row at 15px/500/-0.01em in
   #A9A9A9, a hairline, then the legal row at #515151.
   The agency footer from main.css is NOT reused: it is a light,
   four-column layout with a different job. This one is black and
   flat, and it carries the city links that feed the SEO pages.
   =================================== */

.pl-footer {
    background-color: #191919;
    padding: 4.375rem 3rem 2.5rem;
}

.pl-footer .container {
    display: flex;
    flex-direction: column;
    gap: 44px;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}


/* --- Row 1: logo, links, social --- */

.pl-footer-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 32px;
}

/* The logo file is dark artwork made for a white pill. brightness(0)
   crushes it to solid black and invert(1) turns that white, which is
   correct for a one-colour mark. Replace this with a real white SVG
   if the logo ever gains a second colour. */
.pl-footer-brand img {
    display: block;
    width: auto;
    height: 30px;
}

.pl-footer-right {
    display: flex;
    align-items: center;
    gap: 32px;
}

.pl-footer-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 26px;
}

.pl-footer-nav a {
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.01em;
    color: rgba(255, 255, 255, 0.86);
    text-decoration: none;
    transition: color 0.25s ease;
}

.pl-footer-nav a:hover {
    color: var(--color-white);
}

.pl-footer-social {
    display: flex;
    align-items: center;
    gap: 16px;
}

.pl-footer-social a {
    display: inline-flex;
    color: #A9A9A9;
    transition: color 0.25s ease;
}

.pl-footer-social a:hover {
    color: var(--color-white);
}

.pl-footer-social svg {
    width: 18px;
    height: 18px;
}


/* --- Row 2: the cities ---
   Plain text today, links the day the city pages exist. The rule is
   written for the anchor as well, so swapping the tag changes nothing
   visually. */

.pl-footer-cities {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px 20px;
}

.pl-footer-city {
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.01em;
    color: #A9A9A9;
    text-decoration: none;
    transition: color 0.25s ease;
}

a.pl-footer-city:hover {
    color: var(--color-white);
}


/* --- Row 3: the hairline ---
   The reference draws a 4px SVG here. A 1px line is the same thing
   without an asset. */

.pl-footer-line {
    height: 1px;
    background-color: rgba(255, 255, 255, 0.08);
}


/* --- Row 4: copyright and legal --- */

.pl-footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
}

.pl-footer-copy {
    margin: 0;
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.02em;
    color: #6e6e6e;
}

.pl-footer-legal {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 24px;
}

.pl-footer-legal a {
    font-size: 0.9375rem;
    font-weight: var(--font-medium);
    letter-spacing: -0.02em;
    color: #6e6e6e;
    text-decoration: none;
    transition: color 0.25s ease;
}

.pl-footer-legal a:hover {
    color: #A9A9A9;
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-footer {
        padding: 3rem 3rem 2.5rem;
    }

    .pl-footer .container {
        gap: 36px;
    }

    .pl-footer-top {
        flex-direction: column;
        align-items: flex-start;
        gap: 24px;
    }

    .pl-footer-brand img {
        height: 26px;
    }

    .pl-footer-right {
        flex-wrap: wrap;
        gap: 24px;
    }
}

@media (max-width: 768px) {

    .pl-footer {
        padding: 2.5rem 1.5rem 2rem;
    }

    .pl-footer-brand img {
        height: 24px;
    }

    .pl-footer-nav {
        gap: 14px 20px;
    }

    .pl-footer-cities {
        gap: 14px 16px;
    }

    .pl-footer-bottom {
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
    }

    .pl-footer-legal {
        gap: 18px;
    }
}

/* ===================================
   SCROLL TO TOP (fixing a main.css bug, on this page only)
   main.css styles this button with var(--white) and var(--hero-bg),
   and NEITHER TOKEN EXISTS in the file. An invalid var() kills the
   whole declaration, so the button has always been a transparent
   circle with a dark inherited arrow. It is invisible against the CTA
   card and the black footer while still being clickable.
   Rebuilt here as the header pill's material: the same 0.85 white, the
   same 10px backdrop blur, the same seven-layer ring shadow. That
   reads on a white section AND on a black one, which is what a fixed
   button crossing the whole page needs, and it makes the two floating
   elements on the page one component family.
   OWED: the same two dead tokens break this button on all 17 pages.
   Fix them in main.css during the home page port, not before.
   =================================== */

.scroll-to-top {
    color: #1A1A1A;
    background-color: rgba(255, 255, 255, 0.85);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 0 0 1px rgba(93, 94, 94, 0.1),
        0 1px 1px -0.5px rgba(70, 71, 74, 0.03),
        0 2px 2px -1px rgba(69, 70, 74, 0.04),
        0 3px 3px -1.5px rgba(66, 68, 71, 0.04),
        0 5px 5px -2.5px rgba(42, 51, 70, 0.03),
        0 10px 10px -5px rgba(62, 64, 66, 0.03),
        0 24px 24px -8px rgba(58, 59, 61, 0.03);
    transition: color 0.3s ease,
        background-color 0.3s ease,
        opacity 0.3s ease,
        visibility 0.3s ease,
        transform 0.3s ease;
}

/* Hover keeps the glass rather than going solid, so the two states are
   the same material at two darknesses. The dark value is the header
   CTA's black at the same 0.85, and the blur carries through. */
.scroll-to-top:hover {
    color: var(--color-white);
    background-color: rgba(26, 26, 26, 0.85);
}

/* ===================================
   HERO DEMO
   A real order travelling across the stage: screenshot states in a
   browser window on the left, the owner's coded phone on the right.
   Designed at a fixed 1194x672 and scaled to the frame width through
   --pl-hd-scale, set by initHeroDemo. The media queries at the end of
   this block are a coarse no-JS fallback only.
   =================================== */

.pl-hd {
    position: absolute;
    inset: 0;
    overflow: hidden;
    background:
        radial-gradient(120% 140% at 85% 10%, rgba(251, 105, 48, 0.07), transparent 55%),
        linear-gradient(160deg, #FFFFFF 0%, #F1F2F4 60%, #E9EBEE 100%);
}

.pl-hd-stage {
    position: absolute;
    top: 0;
    left: 0;
    width: 1290px;
    height: 591px;
    transform: scale(var(--pl-hd-scale, 1));
    transform-origin: top left;
}

.pl-hd-desktop {
    position: absolute;
    inset: 0;
}

.pl-hd-shots {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 985px;
    background-color: var(--color-white);
    box-shadow: 24px 0 48px -18px rgba(11, 20, 26, 0.12);
}

.pl-hd-shot {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
    opacity: 0;
}

.pl-hd-shot.is-on {
    opacity: 1;
}

.pl-hd-cursor {
    position: absolute;
    top: 300px;
    left: 380px;
    width: 26px;
    height: 26px;
    z-index: 3;
    opacity: 0;
    filter: drop-shadow(0 2px 4px rgba(11, 20, 26, 0.35));
    transition: left 0.85s cubic-bezier(0.45, 0.05, 0.2, 1),
        top 0.85s cubic-bezier(0.45, 0.05, 0.2, 1),
        opacity 0.3s ease;
}

.pl-hd-cursor.is-on {
    opacity: 1;
}

.pl-hd-cursor svg {
    width: 100%;
    height: 100%;
}

.pl-hd-cursor::after {
    content: "";
    position: absolute;
    top: -13px;
    left: -5px;
    width: 30px;
    height: 30px;
    border: 2px solid var(--pl-accent);
    border-radius: 50%;
    opacity: 0;
    transform: scale(0.4);
}

.pl-hd-cursor.is-click::after {
    animation: plHdClick 0.45s ease-out;
}

@keyframes plHdClick {
    0% {
        opacity: 0.9;
        transform: scale(0.4);
    }

    100% {
        opacity: 0;
        transform: scale(1.5);
    }
}

.pl-hd-phone {
    position: absolute;
    top: 20px;
    left: 1005px;
    width: 265px;
    height: 551px;
}

/* The hero phone reuses the step-3 phone component wholesale. Only the
   frame geometry changes here: static and full size instead of the
   step stage's cropped absolute placement. */
.pl-hd-phone .pl-phone-frame {
    position: static;
    width: 100%;
    height: 100%;
    transform: none;
}

.pl-hd-phone .pl-phone-screen {
    position: relative;
}

.pl-hd-bell {
    position: relative;
    display: inline-flex;
}

.pl-hd-bell b {
    position: absolute;
    top: -5px;
    right: -6px;
    min-width: 14px;
    height: 14px;
    padding: 0 3px;
    border-radius: 99px;
    background-color: #E5484D;
    color: var(--color-white);
    font-size: 9px;
    font-weight: var(--font-semibold);
    display: flex;
    align-items: center;
    justify-content: center;
}

.pl-hd-notify {
    position: absolute;
    top: 8px;
    left: 8px;
    right: 8px;
    z-index: 4;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-radius: 14px;
    background-color: rgba(255, 255, 255, 0.96);
    box-shadow: 0 8px 22px rgba(11, 20, 26, 0.18);
    transform: translateY(-130%);
    opacity: 0;
    transition: transform 0.55s cubic-bezier(0.22, 0.61, 0.36, 1),
        opacity 0.4s ease;
}

.pl-hd-notify.is-in {
    transform: translateY(0);
    opacity: 1;
}

.pl-hd-notify img {
    width: 26px;
    height: 26px;
    border-radius: 8px;
    flex-shrink: 0;
}

.pl-hd-notify span {
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.pl-hd-notify strong {
    font-size: 10.5px;
    color: #1A1A1A;
}

.pl-hd-notify em {
    font-style: normal;
    font-size: 9.5px;
    color: var(--text-tertiary);
}

@media (prefers-reduced-motion: reduce) {

    .pl-hd-shot,
    .pl-hd-cursor,
    .pl-hd-notify,
    .pl-hd .pl-grow {
        transition: none;
    }
}

/* Coarse no-JS scale steps. initHeroDemo overwrites these with the
   exact frame ratio on load and on resize. */
@media (max-width: 1300px) {
    .pl-hd {
        --pl-hd-scale: 0.85;
    }
}

@media (max-width: 1024px) {
    .pl-hd {
        --pl-hd-scale: 0.65;
    }
}

@media (max-width: 768px) {
    .pl-hd {
        --pl-hd-scale: 0.5;
    }
}

@media (max-width: 480px) {
    .pl-hd {
        --pl-hd-scale: 0.27;
    }
}


/* ===================================
   RTL (Arabic page only)
   Arabic joins its letters and carries marks above the line: the
   Latin display values (tight line-height, negative tracking) clip
   and crowd it. Scoped to dir="rtl" so EN/FR keep their values.
   The icon flip makes the arrows point "forward" in reading order. */

[dir="rtl"] .pl-hero-title {
    line-height: 1.3;
    letter-spacing: 0;
}

[dir="rtl"] .pl-hero-tagline {
    line-height: 1.75;
    letter-spacing: 0;
}

[dir="rtl"] .pl-cta-arrow svg {
    transform: scaleX(-1);
}


/* ===================================
   AGENCY HOMEPAGE (index.html, body.pl-agency)
   Same header, same components. Only the brand colour, the logo
   lift and the CTA colour differ.
   =================================== */

.pl-agency {
    --pl-accent: var(--color-primary-blue);
}

/* The WePremium wordmark has no element hanging below the baseline,
   so the cart-W optical lift does not apply. */
.pl-agency .pl-header-brand img,
.pl-agency .pl-menu-top img {
    transform: none;
}

/* Blue, not the reference black. Hover keeps the colour: the label
   roll is the hover effect. Same specificity as the shared hover rule
   and later in the file, so it wins. */
.pl-agency .pl-header .pl-cta,
.pl-agency .pl-header .pl-cta:hover {
    color: var(--color-white);
    background-color: var(--pl-accent);
}


/* --- Agency hero ---
   The WeCommerce hero is a white full-bleed column. This one is a blue
   rounded card inside the shared 1300px box, two columns, starting
   below the header instead of behind it. It reuses .pl-hero-title (so
   the letter reveal runs unchanged), .pl-hero-tagline, .pl-hero-btn
   --solid/--light and the .pl-perk chips; only the card, the columns
   and the phone are new. */

.pl-agency .pl-hero {
    padding: calc(101px + 2.5rem) 0 4.375rem;
}

.pl-agency .pl-hero-container {
    display: block;
    text-align: start;
}

.pl-hero-card {
    position: relative;
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    align-items: center;
    gap: 5rem;
    padding: 4rem 4.5rem;
    color: var(--color-white);
    background-color: #020215;
    border-radius: 3.125rem;
    overflow: hidden;
}

/* The old hero's two blurred circles, orange bottom left and purple top
   right, now clipped by the card's radius. */
.pl-hero-card::before {
    content: '';
    position: absolute;
    bottom: -10%;
    inset-inline-start: -10%;
    width: 500px;
    height: 500px;
    background: radial-gradient(circle, #D35400 0%, transparent 60%);
    border-radius: 50%;
    filter: blur(100px);
    pointer-events: none;
}

.pl-hero-card::after {
    content: '';
    position: absolute;
    top: -20%;
    inset-inline-end: -15%;
    width: 700px;
    height: 700px;
    background: radial-gradient(circle, var(--color-primary-purple) 0%, transparent 50%);
    border-radius: 50%;
    filter: blur(100px);
    pointer-events: none;
}

.pl-hero-copy,
.pl-hero-visual {
    position: relative;
    z-index: 1;
}

.pl-hero-copy {
    min-width: 0;
}

/* A .pl-perk chip in the white --main skin, rotating three rows.
   36px, not the chip's 42, so it sits under the 48px buttons rather
   than beside them. */
.pl-hero-badge {
    height: 36px;
    margin-bottom: 1.25rem;
    padding: 8px 14px;
    font-size: 0.8125rem;
    letter-spacing: 0;
}

/* Same colour as the header CTA's badge dot, not the page accent. */
.pl-hero-badge .pl-perk-check {
    background-color: rgb(255, 88, 88);
}

.pl-agency .pl-hero-title {
    max-width: none;
    margin-bottom: 1.25rem;
    font-size: 2.75rem;
    line-height: 1.1;
    letter-spacing: -0.025em;
    color: var(--color-white);
}

.pl-agency .pl-hero-tagline {
    max-width: 34rem;
    margin-bottom: 2rem;
    font-size: 1.125rem;
    line-height: 1.55;
    color: rgba(255, 255, 255, 0.86);
}

.pl-agency .pl-hero-actions {
    justify-content: flex-start;
    margin-bottom: 1.75rem;
}

.pl-agency .pl-hero-btn--solid {
    color: var(--color-white);
    background-color: var(--pl-accent);
    border-color: var(--pl-accent);
}

.pl-agency .pl-hero-btn--solid:hover {
    color: var(--color-white);
    background-color: var(--color-primary-blue-dark);
    border-color: var(--color-primary-blue-dark);
}

.pl-agency .pl-cta-arrow {
    color: var(--pl-accent);
    background-color: var(--color-white);
}

/* --- Phone + floating cards --- */

.pl-hero-visual {
    justify-self: center;
    width: 100%;
    max-width: 380px;
}

.pl-hero-phone {
    display: block;
    width: 100%;
    height: auto;
    filter: drop-shadow(0 20px 40px rgba(0, 0, 0, 0.35));
}

/* Small: icon plus two short lines. main.css's @keyframes float is
   already loaded on this page, so the bob reuses it. */
.pl-hero-float {
    position: absolute;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    max-width: 160px;
    padding: 0.9rem 0.85rem;
    text-align: center;
    background-color: rgba(255, 255, 255, 0.94);
    border-radius: 14px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.18);
    animation: float 4s ease-in-out infinite;
}

.pl-hero-float img {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
}

.pl-hero-float strong {
    display: block;
    margin-bottom: 0.2rem;
    font-size: 0.8125rem;
    font-weight: var(--font-semibold);
    line-height: 1.25;
    color: #1A1A1A;
}

.pl-hero-float p {
    margin: 0;
    font-size: 0.6875rem;
    line-height: 1.3;
    color: var(--text-secondary);
}

.pl-hero-float--1 {
    top: 8%;
    inset-inline-start: -14%;
}

.pl-hero-float--2 {
    top: 24%;
    inset-inline-end: -12%;
    animation-delay: 1s;
}

.pl-hero-float--3 {
    bottom: 26%;
    inset-inline-start: -12%;
    animation-delay: 2s;
}

.pl-hero-float--4 {
    bottom: 8%;
    inset-inline-end: -10%;
    animation-delay: 1.5s;
}

/* --- Responsive --- */

@media (max-width: 1200px) {

    .pl-hero-card {
        padding: 3rem 3.5rem;
    }

    .pl-agency .pl-hero-title {
        font-size: 2.5rem;
    }

    .pl-hero-visual {
        max-width: 340px;
    }
}

@media (max-width: 1024px) {

    .pl-agency .pl-hero {
        padding: calc(80px + 2rem) 0 3rem;
    }

    .pl-hero-card {
        grid-template-columns: 1fr;
        gap: 2.5rem;
        padding: 3rem 2.5rem;
        border-radius: 2.5rem;
    }

    .pl-agency .pl-hero-title {
        font-size: 2.4rem;
    }

    .pl-hero-visual {
        max-width: 320px;
    }
}

@media (max-width: 768px) {

    .pl-hero-card {
        padding: 2.5rem 1.5rem;
        border-radius: 2rem;
    }

    .pl-agency .pl-hero-title {
        font-size: 2.1rem;
    }

    .pl-agency .pl-hero-tagline {
        font-size: 1rem;
    }

    /* Cards sit on the phone's edges: the card's 1.5rem padding would
       clip the desktop overhang. */
    .pl-hero-float--1,
    .pl-hero-float--3 {
        inset-inline-start: 0;
    }

    .pl-hero-float--2,
    .pl-hero-float--4 {
        inset-inline-end: 0;
    }
}

@media (max-width: 480px) {

    .pl-agency .pl-hero-title {
        font-size: 1.85rem;
    }

    .pl-hero-visual {
        max-width: 260px;
    }

    .pl-hero-float {
        max-width: 160px;
        padding: 0.85rem 0.7rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-hero-float {
        animation: none;
    }
}

/* ===================================
   SECTION: BEFORE / AFTER (agency homepage, .pl-vs)
   One card, two panes, ONE sequence: data-sequence sits on the card so
   both windows share a timeline ordered by data-seq. Each pane: label,
   seven rows, and a browser window bleeding off the bottom edge (the
   pane clips it). Windows reuse the step-2 browser component including
   its typed address; chips reuse .pl-tag. No number appears here that
   we did not measure.
   (.pl-compare* further up is a different, dead family. Not this.)
   =================================== */

.pl-vs {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
}

.pl-vs .container {
    position: relative;
    z-index: 1;
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

.pl-vs-line {
    display: block;
}

.pl-vs-card {
    display: grid;
    grid-template-columns: 1fr 1fr;
    background-color: var(--bg-primary);
    border: 2px solid rgba(211, 216, 217, 0.4);
    border-radius: 24px;
    overflow: hidden;
}

/* overflow:hidden is what clips the window at the pane's bottom edge,
   stacked or side by side. Chips and cards overhang the window
   sideways only, inside the pane's own padding, so they are never cut. */
.pl-vs-pane {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
    padding: 40px 40px 0;
    overflow: hidden;
}

.pl-vs-pane--old {
    background-image: radial-gradient(90% 70% at 0% 0%,
            rgba(255, 61, 100, 0.09),
            rgba(255, 61, 100, 0) 100%);
}

.pl-vs-pane--new {
    background-image: radial-gradient(90% 70% at 100% 0%,
            rgba(32, 125, 233, 0.11),
            rgba(32, 125, 233, 0) 100%);
    border-inline-start: 1px solid rgba(211, 216, 217, 0.5);
}


/* --- Labels --- */

.pl-vs-label {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    height: 30px;
    margin: 0;
    padding: 0 12px;
    font-size: 0.8125rem;
    font-weight: var(--font-semibold);
    letter-spacing: -0.01em;
    color: var(--color-error);
    background-color: rgba(255, 61, 100, 0.08);
    border: 1px solid rgba(255, 61, 100, 0.18);
    border-radius: 50px;
}

.pl-vs-label--brand {
    padding: 0;
    background: none;
    border: none;
}

/* Same 30px as the header pill's logo */
.pl-vs-label--brand img {
    display: block;
    width: auto;
    height: 30px;
}


/* --- Rows --- */

.pl-vs-list {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.pl-vs-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    font-size: 0.95rem;
    line-height: 1.5;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}

.pl-vs-list strong {
    font-weight: var(--font-semibold);
    color: #1A1A1A;
}

.pl-vs-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin-top: 1px;
    border-radius: 50%;
}

.pl-vs-icon svg {
    width: 12px;
    height: 12px;
}

.pl-vs-pane--old .pl-vs-icon {
    color: var(--color-error);
    background-color: rgba(255, 61, 100, 0.12);
}

.pl-vs-pane--new .pl-vs-icon {
    color: var(--color-white);
    background-color: var(--pl-accent);
}

/* One-shot reveal, the pricing list's values. platform.js arms the
   list, so a failed script leaves all fourteen rows visible. */
.pl-vs-list.is-armed li {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(-12px);
}

.pl-vs-list.is-revealed li {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        opacity 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        filter 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms);
}

.pl-vs-list li:nth-child(1) {
    --i: 0;
}

.pl-vs-list li:nth-child(2) {
    --i: 1;
}

.pl-vs-list li:nth-child(3) {
    --i: 2;
}

.pl-vs-list li:nth-child(4) {
    --i: 3;
}

.pl-vs-list li:nth-child(5) {
    --i: 4;
}

.pl-vs-list li:nth-child(6) {
    --i: 5;
}

.pl-vs-list li:nth-child(7) {
    --i: 6;
}


/* --- The window ---
   80% of the pane, centred, in a fixed-height slot at the bottom. The
   browser is taller than the slot and runs past the pane's edge, where
   the pane's overflow clips it. The 10% either side is where the chips
   and floating cards live. */

.pl-vs-visual {
    position: relative;
    width: 80%;
    height: 250px;
    margin: auto auto 0;
}

.pl-vs-visual .pl-browser {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
}

/* Typed address, the step-2 mechanism. The step count must equal the
   number of characters in the domain: 22 and 15 here. A single timing
   function applies to both of the caret's animations, which is fine. */
.pl-vs-url.is-in .pl-browser-domain,
.pl-vs-url.is-in .pl-browser-caret {
    animation-timing-function: steps(16);
}

/* "Not secure" takes the padlock's slot and its 1.3s delay, so both
   windows reveal their verdict at the same moment. */
.pl-vs-url-warn {
    display: inline-flex;
    align-items: center;
    flex: none;
    gap: 4px;
    padding-inline-end: 6px;
    border-inline-end: 1px solid rgba(0, 0, 0, 0.15);
    color: #8E8E8E;
    opacity: 0;
}

.pl-vs-url--old.is-in .pl-vs-url-warn {
    animation: plFadeIn 0.35s ease 1.3s forwards;
}

.pl-vs-url-icon {
    flex: none;
    width: 12px;
    height: 12px;
}

.pl-vs-page {
    position: relative;
    min-height: 320px;
}

/* Loading bar under the window bar. Left creeps to 38% and stays
   there. Right fills in a third of a second and then fades itself
   out, so it needs no transient flag. */
.pl-vs-bar {
    position: absolute;
    top: 0;
    inset-inline-start: 0;
    z-index: 2;
    display: block;
    width: 0;
    height: 3px;
}

.pl-vs-bar--stall {
    background-color: var(--color-error);
}

.pl-vs-bar--stall.is-in {
    animation: plVsStall 2.2s cubic-bezier(0.2, 0.8, 0.3, 1) forwards;
}

.pl-vs-bar--fill {
    background-color: var(--pl-accent);
}

.pl-vs-bar--fill.is-in {
    animation: plVsFill 0.7s ease-out forwards;
}

@keyframes plVsStall {
    to {
        width: 38%;
    }
}

@keyframes plVsFill {
    55% {
        width: 100%;
        opacity: 1;
    }

    100% {
        width: 100%;
        opacity: 0;
    }
}

/* Spinner over the empty page. Hidden again by the sibling rule the
   moment the template paints. */
.pl-vs-wait {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding-bottom: 90px;
    font-size: 11px;
    color: #8E8E8E;
}

.pl-vs-tpl.is-in~.pl-vs-wait {
    opacity: 0;
}

.pl-vs-wait i {
    width: 22px;
    height: 22px;
    border: 3px solid rgba(0, 0, 0, 0.1);
    border-top-color: #8E8E8E;
    border-radius: 50%;
    animation: plVsSpin 0.9s linear infinite;
}

@keyframes plVsSpin {
    to {
        transform: rotate(360deg);
    }
}


/* --- Left page: the messy one ---
   Nothing lines up on purpose: a header whose links stack, a hero
   whose text runs past its box, three cards of three heights, one
   pushed down and one overlapping its neighbour. All grey. */

.pl-vs-tpl-head,
.pl-vs-site-head {
    display: flex;
    align-items: center;
    gap: 7px;
    height: 32px;
    padding-inline: 10px;
    background-color: var(--color-white);
}

.pl-vs-tpl-head {
    align-items: flex-start;
    gap: 6px;
    height: auto;
    padding: 6px 8px 5px 14px;
    background-color: #E9EAEC;
}

.pl-vs-tpl-head i {
    flex: none;
    width: 22px;
    height: 14px;
    margin-top: 3px;
    background-color: #9AA0A6;
}

.pl-vs-tpl-head span,
.pl-vs-site-head span {
    width: 22px;
    height: 4px;
    border-radius: 2px;
    background-color: #C9CDD3;
}

.pl-vs-tpl-head span {
    background-color: #B4B8BE;
}

.pl-vs-tpl-head span:nth-of-type(1) {
    width: 40px;
    margin-top: 8px;
}

.pl-vs-tpl-head span:nth-of-type(2) {
    width: 18px;
    margin-top: 2px;
}

.pl-vs-tpl-head span:nth-of-type(3) {
    width: 55px;
    margin-top: 12px;
    margin-inline-start: -30px;
}

.pl-vs-site-head span:first-of-type {
    margin-inline-start: auto;
}

.pl-vs-tpl-head b,
.pl-vs-site-head b {
    width: 30px;
    height: 12px;
    border-radius: 3px;
    background-color: #C9CDD3;
}

.pl-vs-tpl-head b {
    width: 44px;
    height: 16px;
    margin-inline-start: auto;
    margin-top: -1px;
    border-radius: 0;
    background-color: #7F8790;
}

.pl-vs-tpl-hero {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 5px;
    height: 58px;
    margin: 4px 22px 0 6px;
    padding: 9px 0 0 6px;
    background-color: #C3C7CC;
}

.pl-vs-tpl-hero i {
    display: block;
    height: 4px;
    border-radius: 2px;
    background-color: #6F7680;
}

.pl-vs-tpl-hero i:nth-child(1) {
    width: 118%;
}

.pl-vs-tpl-hero i:nth-child(2) {
    width: 70%;
    background-color: #8A9199;
}

.pl-vs-tpl-hero b {
    width: 34px;
    height: 10px;
    margin-top: 4px;
    margin-inline-start: 60%;
    background-color: #9AA0A6;
}

.pl-vs-tpl-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin: 8px 10px 0;
}

.pl-vs-tpl-row--messy {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    margin: 10px 8px 0;
}

.pl-vs-tpl-card,
.pl-vs-site-card {
    display: flex;
    flex-direction: column;
    gap: 5px;
    padding: 7px;
    border-radius: 5px;
    background-color: var(--color-white);
}

.pl-vs-tpl-card {
    gap: 4px;
    padding: 6px;
    border-radius: 0;
    background-color: #F3F4F5;
}

.pl-vs-tpl-card:nth-child(1) {
    width: 38%;
}

.pl-vs-tpl-card:nth-child(2) {
    width: 26%;
    margin-top: 12px;
    background-color: #DADCE0;
}

.pl-vs-tpl-card:nth-child(3) {
    width: 40%;
    margin-inline-start: -8px;
}

.pl-vs-tpl-card i {
    display: block;
    height: 30px;
    background-color: #C3C7CC;
}

.pl-vs-tpl-card:nth-child(2) i {
    height: 44px;
}

.pl-vs-tpl-card:nth-child(3) i {
    height: 22px;
}

.pl-vs-tpl-card span,
.pl-vs-site-card span {
    display: block;
    width: 100%;
    height: 4px;
    border-radius: 2px;
    background-color: #C9CDD3;
}

.pl-vs-tpl-card span {
    background-color: #A8ADB4;
}

.pl-vs-tpl-card span:last-child {
    width: 55%;
}

.pl-vs-tpl-card:nth-child(3) span:first-of-type {
    width: 120%;
}

.pl-vs-site-card span:nth-of-type(2) {
    width: 60%;
}


/* --- Right page: the real one ---
   Structured: brand mark and name, a brand-blue hero, image-led cards
   with a blue link line on each. */

.pl-vs-site-head i {
    flex: none;
    width: 17px;
    height: 17px;
    border-radius: 3px;
    background-color: var(--pl-accent);
}

.pl-vs-site-head em {
    flex: none;
    font-size: 10px;
    font-style: normal;
    font-weight: var(--font-bold);
    line-height: 1;
    letter-spacing: -0.01em;
    color: #1A1A1A;
}

.pl-vs-site-head b {
    background-color: var(--pl-accent);
}

/* Green round button, sized for each header. The desktop rule beats
   ".pl-vs-site-head span" on specificity. */
.pl-vs-site-head .pl-vs-site-wa,
.pl-vs-mini-head .pl-vs-site-wa {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    color: var(--color-white);
    background-color: rgb(37, 211, 102);
    border-radius: 50%;
}

.pl-vs-site-head .pl-vs-site-wa {
    width: 14px;
    height: 14px;
    margin-inline-start: 2px;
}

.pl-vs-site-head .pl-vs-site-wa svg {
    width: 8px;
    height: 8px;
}

.pl-vs-mini-head .pl-vs-site-wa {
    width: 9px;
    height: 9px;
    margin-inline-start: auto;
}

.pl-vs-mini-head .pl-vs-site-wa svg {
    width: 5px;
    height: 5px;
}

.pl-vs-site-hero {
    background: linear-gradient(115deg, var(--color-primary-blue-dark) 0%, var(--color-primary-blue) 100%);
}

.pl-vs-site-hero b {
    background-color: var(--color-white);
}

.pl-vs-site-head span {
    background-color: #9DB7D8;
}

/* Three image tints, one per card, all from the site's own palette. */
.pl-vs-site-card i {
    display: block;
    height: 36px;
    border-radius: 3px;
    background-color: rgba(32, 125, 233, 0.16);
}

.pl-vs-site-card:nth-child(2) i {
    background-color: rgba(49, 189, 55, 0.18);
}

.pl-vs-site-card:nth-child(3) i {
    background-color: rgba(242, 183, 5, 0.22);
}

.pl-vs-site-card b {
    width: 40%;
    height: 4px;
    margin-top: 1px;
    border-radius: 2px;
    background-color: var(--pl-accent);
}


/* --- Chips (.pl-tag's recipe, moved to the window's top right) --- */

.pl-vs-tag {
    inset-inline-start: auto;
    inset-inline-end: -12px;
    top: 72px;
    bottom: auto;
    transform: scale(0.82);
    transform-origin: 100% 0;
}

.pl-vs-tag.is-in {
    transform: scale(1);
}

.pl-vs-tag img {
    width: 14px;
    height: 14px;
}

.pl-vs-tag--bad {
    background-color: var(--color-error);
    box-shadow: 0 6px 14px rgba(255, 61, 100, 0.35),
        0 14px 30px rgba(0, 0, 0, 0.12);
}

/* White, so Google's mark sits on white. */
.pl-vs-tag--good {
    color: #1A1A1A;
    background-color: var(--color-white);
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.06),
        0 12px 24px rgba(11, 20, 26, 0.14);
}


/* --- Floating cards ---
   White pills with a tinted icon, hanging over the window's edges in
   the 10% margins. Pop in with the chip's spring, no stagger needed:
   the sequence is the stagger. */

.pl-vs-float {
    position: absolute;
    z-index: 3;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 14px 6px 6px;
    font-size: 13px;
    font-weight: var(--font-semibold);
    line-height: 1;
    letter-spacing: -0.01em;
    white-space: nowrap;
    color: #1A1A1A;
    background-color: var(--color-white);
    border-radius: 12px;
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.06),
        0 12px 24px rgba(11, 20, 26, 0.12);
    opacity: 0;
    transform: translateY(8px) scale(0.92);
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.pl-vs-float.is-in {
    opacity: 1;
    transform: none;
}

.pl-vs-float-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 46px;
    height: 46px;
    border-radius: 12px;
}

.pl-vs-float-icon svg {
    width: 30px;
    height: 30px;
}

.pl-vs-float--bad .pl-vs-float-icon {
    color: var(--color-error);
    background-color: rgba(255, 61, 100, 0.12);
}

.pl-vs-float--good .pl-vs-float-icon {
    color: var(--pl-accent);
    background-color: rgba(32, 125, 233, 0.12);
}

.pl-vs-float--tl {
    top: -16px;
    inset-inline-start: -12px;
}

.pl-vs-float--tr {
    top: -16px;
    inset-inline-end: -12px;
}

.pl-vs-float--bl {
    top: 128px;
    inset-inline-start: -12px;
}

/* --- Phones ---
   Step 3's shell at a quarter of the size. Both screens are drawn
   from the same five blocks; the bad one lets them run past the
   screen's edge and leaves a horizontal scrollbar behind. */

.pl-vs-phone {
    position: absolute;
    z-index: 3;
    top: 64px;
    inset-inline-start: -14px;
    width: 86px;
    height: 176px;
    padding: 5px;
    border-radius: 15px;
    background-color: #1A1A1A;
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.06),
        0 12px 24px rgba(11, 20, 26, 0.18);
    opacity: 0;
    transform: translateY(10px) scale(0.94);
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.pl-vs-phone.is-in {
    opacity: 1;
    transform: none;
}

.pl-vs-phone-notch {
    position: absolute;
    top: 5px;
    left: 50%;
    z-index: 1;
    width: 26px;
    height: 4px;
    margin-left: -13px;
    border-radius: 2px;
    background-color: #1A1A1A;
}

.pl-vs-phone-screen {
    position: relative;
    height: 100%;
    padding: 13px 6px 0;
    border-radius: 11px;
    overflow: hidden;
    background-color: var(--color-white);
}

.pl-vs-mini-head {
    display: flex;
    align-items: center;
    gap: 3px;
    height: 10px;
    margin-bottom: 5px;
}

.pl-vs-mini-head i {
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 2px;
}

.pl-vs-mini-head b {
    height: 3px;
    border-radius: 2px;
}

.pl-vs-mini-hero,
.pl-vs-mini-card {
    border-radius: 3px;
    margin-bottom: 5px;
}

.pl-vs-mini-hero {
    height: 34px;
}

.pl-vs-mini-card {
    height: 24px;
}

.pl-vs-mini-line {
    height: 3px;
    border-radius: 2px;
}

/* Good: everything fits, brand colours. */
.pl-vs-phone--good .pl-vs-mini-head i {
    background-color: var(--pl-accent);
}

.pl-vs-phone--good .pl-vs-mini-head b {
    width: 30px;
    background-color: #9DB7D8;
}

.pl-vs-phone--good .pl-vs-mini-hero {
    background: linear-gradient(115deg, var(--color-primary-blue-dark) 0%, var(--color-primary-blue) 100%);
}

/* The desktop cards, stacked: tinted image, two lines, blue link. */
.pl-vs-phone--good .pl-vs-mini-card {
    display: flex;
    flex-direction: column;
    gap: 3px;
    height: auto;
    margin-bottom: 4px;
    padding: 4px;
    background-color: #F5F6F8;
}

.pl-vs-phone--good .pl-vs-mini-card i {
    display: block;
    height: 14px;
    border-radius: 2px;
    background-color: rgba(32, 125, 233, 0.16);
}

.pl-vs-phone--good .pl-vs-mini-card:nth-of-type(2) i {
    background-color: rgba(49, 189, 55, 0.18);
}

.pl-vs-phone--good .pl-vs-mini-card:nth-of-type(3) i {
    background-color: rgba(242, 183, 5, 0.22);
}

.pl-vs-phone--good .pl-vs-mini-card span {
    display: block;
    height: 2px;
    border-radius: 1px;
    background-color: #C9CDD3;
}

.pl-vs-phone--good .pl-vs-mini-card span:nth-of-type(2) {
    width: 60%;
}

.pl-vs-phone--good .pl-vs-mini-card b {
    width: 40%;
    height: 2px;
    border-radius: 1px;
    background-color: var(--pl-accent);
}

/* Bad: the desktop layout squeezed onto a phone. Blocks wider than
   the screen, a text line running out, and a scrollbar to prove it. */
.pl-vs-phone--bad .pl-vs-phone-screen {
    padding-inline-end: 0;
}

.pl-vs-phone--bad .pl-vs-mini-head i {
    background-color: #9AA0A6;
}

.pl-vs-phone--bad .pl-vs-mini-head b {
    width: 130%;
    background-color: #B4B8BE;
}

.pl-vs-phone--bad .pl-vs-mini-hero {
    width: 160%;
    border-radius: 0;
    background-color: #C3C7CC;
}

.pl-vs-phone--bad .pl-vs-mini-card {
    border-radius: 0;
    background-color: #DADCE0;
}

.pl-vs-phone--bad .pl-vs-mini-card:nth-of-type(1) {
    width: 140%;
}

.pl-vs-phone--bad .pl-vs-mini-card:nth-of-type(2) {
    width: 55%;
    margin-inline-start: 30%;
}

.pl-vs-phone--bad .pl-vs-mini-line {
    width: 190%;
    background-color: #A8ADB4;
}

.pl-vs-phone--bad .pl-vs-phone-screen::after {
    content: '';
    position: absolute;
    bottom: 4px;
    inset-inline-start: 4px;
    width: 38%;
    height: 3px;
    border-radius: 2px;
    background-color: #9AA0A6;
}


/* --- The stat card (right pane) --- */

.pl-vs-stat {
    position: absolute;
    z-index: 3;
    top: 112px;
    inset-inline-end: -12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 150px;
    padding: 11px 12px;
    border-radius: 12px;
    background-color: var(--color-white);
    box-shadow: 0 2px 4px rgba(11, 20, 26, 0.06),
        0 12px 24px rgba(11, 20, 26, 0.12);
    opacity: 0;
    transform: translateY(8px) scale(0.92);
    transition: opacity 0.3s ease, transform 0.45s cubic-bezier(0.34, 1.4, 0.5, 1);
}

.pl-vs-stat.is-in {
    opacity: 1;
    transform: none;
}

.pl-vs-stat-label {
    font-size: 10px;
    font-weight: var(--font-medium);
    line-height: 1;
    color: #8E8E8E;
}

.pl-vs-stat-row {
    display: flex;
    align-items: center;
    gap: 6px;
}

.pl-vs-stat-row strong {
    font-size: 18px;
    font-weight: var(--font-bold);
    line-height: 1;
    letter-spacing: -0.02em;
    color: #1A1A1A;
}

.pl-vs-stat-row em {
    padding: 3px 6px;
    font-size: 10px;
    font-style: normal;
    font-weight: var(--font-semibold);
    line-height: 1;
    color: #1E8E23;
    background-color: rgba(49, 189, 55, 0.14);
    border-radius: 20px;
}

.pl-vs-stat-bars {
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 26px;
}

.pl-vs-stat-bars i {
    flex: 1 1 0;
    border-radius: 2px 2px 0 0;
    background-color: rgba(49, 189, 55, 0.45);
}

.pl-vs-stat-bars i:nth-child(1) {
    height: 30%;
}

.pl-vs-stat-bars i:nth-child(2) {
    height: 42%;
}

.pl-vs-stat-bars i:nth-child(3) {
    height: 38%;
}

.pl-vs-stat-bars i:nth-child(4) {
    height: 55%;
}

.pl-vs-stat-bars i:nth-child(5) {
    height: 64%;
}

.pl-vs-stat-bars i:nth-child(6) {
    height: 78%;
}

.pl-vs-stat-bars i:nth-child(7) {
    height: 100%;
    background-color: var(--color-success);
}

/* Left pane: same card, the numbers going the other way. */
.pl-vs-stat--bad {
    top: 104px;
}

.pl-vs-stat--bad .pl-vs-stat-row em {
    color: #C0263F;
    background-color: rgba(255, 61, 100, 0.14);
}

.pl-vs-stat--bad .pl-vs-stat-bars i {
    background-color: rgba(255, 61, 100, 0.4);
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(1) {
    height: 100%;
    background-color: var(--color-error);
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(2) {
    height: 78%;
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(3) {
    height: 66%;
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(4) {
    height: 54%;
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(5) {
    height: 44%;
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(6) {
    height: 36%;
}

.pl-vs-stat--bad .pl-vs-stat-bars i:nth-child(7) {
    height: 28%;
}


/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-vs-card {
        grid-template-columns: 1fr;
    }

    .pl-vs-pane {
        padding: 32px 28px 0;
    }

    .pl-vs-pane--new {
        border-inline-start: none;
        border-top: 1px solid rgba(211, 216, 217, 0.5);
    }

    .pl-vs-visual {
        height: 230px;
    }
}

@media (max-width: 768px) {

    .pl-vs-pane {
        gap: 1.5rem;
        padding: 28px 20px 0;
    }

    .pl-vs-list li {
        font-size: 0.9375rem;
    }

    .pl-vs-visual {
        width: 100%;
        height: 200px;
    }

    .pl-vs-phone {
        inset-inline-start: 0;
    }

    .pl-vs-float--tr,
    .pl-vs-tag,
    .pl-vs-stat {
        inset-inline-end: 0;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-vs-list.is-armed li {
        opacity: 1;
        filter: none;
        transform: none;
    }

    .pl-vs-wait i,
    .pl-vs-bar--stall.is-in,
    .pl-vs-bar--fill.is-in {
        animation: none;
    }

    .pl-vs-bar--stall {
        width: 38%;
    }

    .pl-vs-bar--fill {
        opacity: 0;
    }
}



/* ===================================
   AGENCY SERVICES (index.html, #services, .pl-svc)
   Two blocks. The intro: copy, a six-row check list and two buttons on
   the left, a card of floating circles on the right, each circle one
   deliverable (the site's own icon set). Below: a centred title and
   four service columns. Lists reveal once with the before/after
   vocabulary (armed from platform.js, so no script = all rows shown).
   =================================== */

.pl-svc {
    position: relative;
    background-color: var(--bg-primary);
    padding: var(--container-section-padding);
}

.pl-svc .container {
    max-width: var(--container-max-width-2);
    margin: 0 auto;
}

/* --- Intro: two columns --- */

.pl-svc-intro {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: 5rem;
    margin-bottom: 6rem;
}

.pl-svc-title {
    margin: 0 0 1.25rem;
    font-size: 2.75rem;
    font-weight: var(--font-extrabold);
    line-height: 1.2;
    letter-spacing: -0.03em;
    color: #1A1A1A;
}

.pl-svc-text {
    margin: 0 0 1.75rem;
    font-size: 1.0625rem;
    font-weight: var(--font-medium);
    line-height: 1.55;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}

.pl-svc-list {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    margin: 0 0 2.25rem;
    padding: 0;
    list-style: none;
}

.pl-svc-list li {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    font-size: 0.95rem;
    line-height: 1.5;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}

.pl-svc-list strong {
    font-weight: var(--font-semibold);
    color: #1A1A1A;
}

.pl-svc-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 20px;
    height: 20px;
    margin-top: 1px;
    color: var(--color-white);
    background-color: rgb(37, 211, 102);
    border-radius: 50%;
}

.pl-svc-check svg {
    width: 12px;
    height: 12px;
}

.pl-svc-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

/* Ghost for a white background. The hero's --light is white-on-black
   and would vanish here. */
.pl-hero-btn--dark {
    color: #1A1A1A;
    background-color: transparent;
    border: 1px solid rgba(26, 26, 26, 0.2);
}

.pl-hero-btn--dark:hover {
    color: #1A1A1A;
    background-color: rgba(26, 26, 26, 0.05);
    border-color: rgba(26, 26, 26, 0.4);
}

/* --- The image ---
   One static picture from Figma. The column, not the file, sets the
   size; the width/height attributes only hold the ratio. */
.pl-svc-visual {
    justify-self: center;
    width: 100%;
    max-width: 520px;
}

.pl-svc-visual img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 24px;
}

/* --- Four service columns --- */

.pl-svc-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 3rem 2.5rem;
}

.pl-svc-tile {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    margin-bottom: 1.5rem;
    border-radius: 8px;
}

.pl-svc-tile svg {
    width: 18px;
    height: 18px;
}

.pl-svc-tile--blue {
    color: var(--pl-accent);
    background-color: rgba(32, 125, 233, 0.12);
}

.pl-svc-tile--green {
    color: #1B7F2A;
    background-color: #E4F7E7;
}

.pl-svc-tile--amber {
    color: #C2570F;
    background-color: #FFF0E6;
}

.pl-svc-tile--purple {
    color: #6B3FD1;
    background-color: #EFE9FC;
}

.pl-svc-item h3 {
    margin: 0 0 0.75rem;
    font-size: 1.125rem;
    font-weight: var(--font-semibold);
    line-height: 1.3;
    letter-spacing: -0.02em;
    color: #1A1A1A;
}

.pl-svc-item p {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.55;
    letter-spacing: -0.01em;
    color: var(--text-secondary);
}

/* --- One-shot reveal (before/after values) --- */

.pl-svc-list.is-armed li,
.pl-svc-grid.is-armed .pl-svc-item {
    opacity: 0;
    filter: blur(4px);
    transform: translateY(-12px);
}

.pl-svc-list.is-revealed li,
.pl-svc-grid.is-revealed .pl-svc-item {
    opacity: 1;
    filter: blur(0);
    transform: translateY(0);
    transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        opacity 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms),
        filter 0.5s cubic-bezier(0.22, 0.61, 0.36, 1) calc(var(--i) * 90ms);
}

.pl-svc-list li:nth-child(1),
.pl-svc-item:nth-child(1) {
    --i: 0;
}

.pl-svc-list li:nth-child(2),
.pl-svc-item:nth-child(2) {
    --i: 1;
}

.pl-svc-list li:nth-child(3),
.pl-svc-item:nth-child(3) {
    --i: 2;
}

.pl-svc-list li:nth-child(4),
.pl-svc-item:nth-child(4) {
    --i: 3;
}

.pl-svc-list li:nth-child(5),
.pl-svc-item:nth-child(5) {
    --i: 4;
}

.pl-svc-list li:nth-child(6),
.pl-svc-item:nth-child(6) {
    --i: 5;
}

/* --- Responsive --- */

@media (max-width: 1024px) {

    .pl-svc-intro {
        grid-template-columns: 1fr;
        gap: 3.5rem;
        margin-bottom: 4.5rem;
    }

    .pl-svc-title {
        font-size: 2.375rem;
    }

    .pl-svc-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 768px) {

    .pl-svc-intro {
        gap: 2.5rem;
        margin-bottom: 3.5rem;
    }

    .pl-svc-title {
        font-size: 1.875rem;
    }

    .pl-svc-text {
        font-size: 1rem;
    }

    .pl-svc-visual img {
        border-radius: 20px;
    }

    .pl-svc-grid {
        grid-template-columns: 1fr;
        gap: 2.25rem;
    }

    .pl-svc-tile {
        margin-bottom: 1rem;
    }
}

@media (prefers-reduced-motion: reduce) {

    .pl-svc-list.is-armed li,
    .pl-svc-grid.is-armed .pl-svc-item {
        opacity: 1;
        filter: none;
        transform: none;
    }
}