/* ==========================================================================
   HEATLINE INDUSTRIES â€” cinematic scroll layer
   Pinned scenes, parallax, kinetic type, macro product staging.
   ========================================================================== */

/* --- HOME: opening scene ------------------------------------------------ */
.hero {
    position: relative;
    min-height: 100vh;      /* fallback for browsers without svh */
    min-height: 100svh;
    display: flex;
    align-items: center;
    /* The nav is transparent over the hero, so only clear the logo â€” not the
       full bar height â€” which buys back vertical room for the content. */
    padding-top: calc(var(--nav-h) * 0.62);
    overflow: clip;
    background: var(--paper);
}

/* Text column sits above the decorative sweeps at every width. */
.hero__inner > div:first-child { position: relative; z-index: 4; }

/* Diagonal red sweep echoing the brochure cover.
   Kept to the far right so it frames the product plate without covering it. */
.hero__sweep {
    position: absolute;
    top: -28%;
    right: -20%;
    width: 46vw;
    height: 150vh;
    background: linear-gradient(148deg, var(--red) 0%, var(--red-deep) 58%, #7C0D13 100%);
    clip-path: polygon(44% 0, 100% 0, 100% 78%, 0 100%);
    opacity: .96;
    z-index: 1;
    will-change: transform;
}

/* Charcoal companion sweep behind it */
.hero__sweep--ink {
    top: -34%;
    right: -28%;
    width: 42vw;
    background: linear-gradient(148deg, #2A2A2E 0%, var(--ink) 100%);
    clip-path: polygon(56% 0, 100% 0, 100% 66%, 8% 96%);
    opacity: .92;
}

.hero__inner {
    position: relative;
    z-index: 3;
    width: 100%;
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--gutter);
    padding-block: clamp(1rem, 2.5vh, 2rem) clamp(2.5rem, 6vh, 4rem);
    display: grid;
    /* The product plate carries the hero, so the image column takes the
       larger share and the copy column stays at a comfortable measure. */
    grid-template-columns: 0.82fr 1.18fr;
    gap: clamp(2rem, 4vw, 4rem);
    align-items: center;
}

/* Sized against viewport height as well as width so the headline, lead,
   buttons, component index and stat rail all fit one screen without clipping. */
.hero__title {
    font-size: clamp(2.2rem, min(5.6vw, 6.8vh), 4.9rem);
    letter-spacing: -0.045em;
    line-height: 0.94;
}

.hero__title .accent { color: var(--red); }

.hero__meta {
    margin-top: clamp(0.9rem, 1.9vh, 1.5rem);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 2.5rem;
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: clamp(1rem, 2.1vh, 1.6rem);
}

/* Hero component index â€” the five families and their sub-category */
.hero__index {
    margin-top: clamp(1rem, 2.2vh, 1.75rem);
    padding-top: clamp(0.8rem, 1.6vh, 1.2rem);
    border-top: 1px solid var(--hairline);
}

.hero__index-label {
    display: block;
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-faint);
    margin-bottom: 0.9rem;
}

.hero__index-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.hero__chip {
    position: relative;
    display: flex;
    align-items: baseline;
    gap: 0.55rem;
    padding: 0.55rem 0.9rem;
    border: 1px solid var(--hairline);
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.55);
    overflow: clip;
    isolation: isolate;
    transition: border-color .4s var(--ease-out), color .4s var(--ease-out);
}

/* Red fill sweeps up on hover, matching the button language. */
.hero__chip::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--red);
    transform: translateY(101%);
    transition: transform .45s var(--ease-out);
}

.hero__chip:hover { border-color: var(--red); color: #fff; }
.hero__chip:hover::after { transform: translateY(0); }

.hero__chip-no {
    font-family: var(--font-mono);
    font-size: 0.58rem;
    letter-spacing: 0.12em;
    color: var(--red);
    transition: color .4s var(--ease-out);
}
.hero__chip:hover .hero__chip-no { color: #fff; }

.hero__chip-body { display: grid; gap: 0.1rem; }

.hero__chip-name {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.86rem;
    letter-spacing: -0.015em;
    line-height: 1.15;
    white-space: nowrap;
}

.hero__chip-sub {
    font-family: var(--font-body);
    font-size: 0.8rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-faint);
    white-space: nowrap;
    transition: color .4s var(--ease-out);
}
.hero__chip:hover .hero__chip-sub { color: rgba(255, 255, 255, 0.8); }

/* Hero stat rail */
.hero__stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));
    gap: clamp(1.25rem, 3vw, 3rem);
    margin-top: clamp(1rem, 2.2vh, 1.75rem);
    padding-top: clamp(0.8rem, 1.6vh, 1.2rem);
    border-top: 1px solid var(--hairline);
}

.stat__num {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(1.6rem, 3vw, 2.6rem);
    letter-spacing: -0.03em;
    line-height: 1;
}

.stat__num sup { font-size: 0.5em; color: var(--red); top: -0.7em; }

.stat__label {
    margin-top: 0.4rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-mute);
}

/* Hero product plate (floating macro shot) */
.hero__plate {
    position: relative;
    /* Matches hero-heater-scene.jpg (3:2) so the scene fills the frame. */
    aspect-ratio: 3 / 2;
    width: 100%;
    max-width: 65rem;
    margin-left: auto;
    border-radius: 2px;
    overflow: clip;
    /* The hero PNG is cut out with a transparent background, so the plate
       carries no fill or shadow of its own — the product floats on the page. */
    background: transparent;
    will-change: transform;
}

/* The source photograph carries a wide white margin around the tank. Scaling
   the object-fit box (not the element) tightens onto the heater without
   fighting the .mask-img reveal, which owns the img transform. */
/* Full-bleed scene image; the plate matches its 3:2 ratio so nothing crops. */
.hero__plate img {
    width: 100%;
    height: 100%;
    /* contain, not cover: this is a cut-out product shot, and cover would
       crop the tank and fittings at the frame edge. */
    object-fit: contain;
    object-position: center center;
}

.hero__plate-tag {
    position: absolute;
    left: 0; bottom: 0;
    z-index: 2;
    background: var(--paper);
    padding: 0.85rem 1.35rem;
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink);
}
.hero__plate-tag b { color: var(--red); font-weight: 500; }

/* Scroll cue */
.scroll-cue {
    position: absolute;
    left: var(--gutter);
    bottom: 1.35rem;
    z-index: 4;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-mute);
}

/* Hidden on short screens where it would collide with the stat rail. */
@media (max-height: 780px) {
    .scroll-cue { display: none; }
}

/* Short laptop screens: let the hero grow past the fold rather than
   compress the component index into something unreadable. */
@media (min-width: 1081px) and (max-height: 800px) {
    .hero { min-height: auto; padding-bottom: clamp(2rem, 5vh, 3.5rem); }
    .hero__plate { max-width: 32rem; }
}

.scroll-cue__rail {
    position: relative;
    width: 3.5rem;
    height: 1px;
    background: var(--hairline);
    overflow: clip;
}

.scroll-cue__rail::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--red);
    transform-origin: left center;
    animation: cue 2.4s var(--ease-in-out) infinite;
}

@keyframes cue {
    0%   { transform: scaleX(0); transform-origin: left center; }
    45%  { transform: scaleX(1); transform-origin: left center; }
    55%  { transform: scaleX(1); transform-origin: right center; }
    100% { transform: scaleX(0); transform-origin: right center; }
}

/* --- Marquee ribbon ----------------------------------------------------- */
.ribbon {
    position: relative;
    background: var(--ink);
    color: #fff;
    padding-block: 1.15rem;
    overflow: clip;
    border-block: 1px solid rgba(255,255,255,.08);
}

.ribbon__track {
    display: flex;
    width: max-content;
    gap: 3rem;
    animation: marquee 42s linear infinite;
    will-change: transform;
}

.ribbon:hover .ribbon__track { animation-play-state: paused; }

.ribbon__item {
    display: inline-flex;
    align-items: center;
    gap: 3rem;
    font-family: var(--font-mono);
    font-size: 0.74rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    white-space: nowrap;
    color: rgba(255,255,255,.82);
}

.ribbon__dot { width: 5px; height: 5px; border-radius: 50%; background: var(--red); flex: none; }

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

/* --- Pinned product film ------------------------------------------------ */
/* Each product = one full-viewport scene inside a tall pinned track. */

.film {
    position: relative;
    background: var(--paper-warm);
}

.film__stage { position: relative; }

.js .film__stage {
    position: sticky;
    top: 0;
    height: 100vh;          /* fallback for browsers without svh */
    height: 100svh;
    overflow: clip;
    display: flex;
    align-items: center;
}

/* Without JS the scenes stack and read as a normal list of products. */
.film__scene {
    display: flex;
    align-items: center;
    padding-block: 3rem;
}

/* Inactive scenes are fully removed from paint and hit-testing. Fading
   `visibility` leaves the outgoing scene painted mid-transition, which reads
   as two products ghosted over each other â€” so it switches instantly while
   only opacity animates. */
.js .film__scene {
    position: absolute;
    inset: 0;
    padding-block: 0;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity .55s var(--ease-out);
}

.js .film__scene.is-active {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}

.film__grid {
    width: 100%;
    max-width: var(--maxw);
    margin-inline: auto;
    padding-inline: var(--gutter);
    display: grid;
    grid-template-columns: 0.95fr 1.05fr;
    gap: clamp(2rem, 5vw, 5.5rem);
    align-items: center;
}

/* Scene copy column */
.film__copy { position: relative; }

.film__index {
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    color: var(--red);
    margin-bottom: 1.1rem;
    display: block;
}

.film__name {
    font-size: clamp(2.1rem, 5vw, 4.25rem);
    line-height: 0.95;
    margin-bottom: 1.25rem;
}

.film__lead {
    color: var(--ink-mute);
    max-width: 42ch;
    font-size: clamp(0.98rem, 1.25vw, 1.1rem);
    margin-bottom: 2rem;
}

/* Inline spec strip inside a scene */
.film__specs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--hairline);
    border: 1px solid var(--hairline);
    margin-bottom: 2rem;
}

.film__spec { background: var(--paper-warm); padding: 1rem 1.1rem; }

.film__spec dt {
    font-family: var(--font-body);
    font-size: 0.58rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-faint);
    margin-bottom: 0.4rem;
}

.film__spec dd {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: -0.02em;
}

/* Scene image column â€” macro product plate */
.film__plate {
    position: relative;
    aspect-ratio: 5 / 4;
    overflow: clip;
    background: var(--paper-deep);
    box-shadow: 0 3rem 6rem -2rem rgba(10,10,11,.34);
}

.film__plate img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: scale(1.06);
    transition: transform 1.4s var(--ease-out);
}

.film__scene.is-active .film__plate img { transform: scale(1); }

/* Oversized ghost numeral behind the plate */
.film__ghost {
    position: absolute;
    right: -1.5vw;
    top: 50%;
    transform: translateY(-50%);
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 26vw;
    line-height: 0.75;
    letter-spacing: -0.06em;
    color: rgba(10,10,11,.038);
    pointer-events: none;
    z-index: 0;
    user-select: none;
}

/* Progress rail for the pinned film */
.film__rail {
    position: absolute;
    right: var(--gutter);
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    display: grid;
    gap: 0.85rem;
}

.film__tick {
    position: relative;
    width: 1.6rem;
    height: 2px;
    background: rgba(10,10,11,.16);
    transition: background .4s var(--ease-out), width .4s var(--ease-out);
}

.film__tick.is-on { background: var(--red); width: 2.75rem; }

/* --- Product index grid ------------------------------------------------- */
.pgrid {
    display: grid;
    grid-template-columns: repeat(12, 1fr);
    gap: clamp(1rem, 2vw, 1.75rem);
}

.pcard {
    position: relative;
    grid-column: span 4;
    display: block;
    background: var(--paper);
    overflow: clip;
    isolation: isolate;
}

/* Feature the first two cards larger */
.pcard--wide { grid-column: span 6; }

.pcard__media {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: clip;
    /* White, matching the photographs' own background, so the tile reads as
       the product rather than as a grey box containing one. */
    background: var(--paper);
}

.pcard--wide .pcard__media { aspect-ratio: 16 / 10; }

/* contain, not cover: these are product photographs and cropping them cuts
   the component off at the edge of the tile. The padded neutral field keeps
   every tile the same shape, so the grid still reads evenly. */
.pcard__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 1.1s var(--ease-out), filter .8s var(--ease-out);
}

.pcard:hover .pcard__media img { transform: scale(1.04); }

/* Red wipe that sweeps across on hover. Now that tiles show the whole
   product on a light field, a multiply blend would stain that field — so
   this is a soft tint from the base instead. */
.pcard__wipe {
    position: absolute;
    inset: auto 0 0 0;
    height: 45%;
    background: linear-gradient(to top, var(--red-glow), transparent);
    opacity: 0;
    transform: translateY(101%);
    transition: transform .7s var(--ease-out), opacity .7s var(--ease-out);
}

.pcard:hover .pcard__wipe { transform: translateY(0); opacity: 1; }

.pcard__index {
    position: absolute;
    top: 1rem; left: 1rem;
    z-index: 2;
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.18em;
    color: #fff;
    background: rgba(10,10,11,.62);
    backdrop-filter: blur(6px);
    padding: 0.35rem 0.7rem;
}

.pcard__body {
    padding: 1.5rem 0 0;
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1.5rem;
}

.pcard__name {
    font-size: clamp(1.15rem, 1.8vw, 1.6rem);
    letter-spacing: -0.025em;
    transition: color .35s var(--ease-out);
}

.pcard:hover .pcard__name { color: var(--red); }

.pcard__kicker {
    margin-top: 0.4rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-mute);
    line-height: 1.5;
}

.pcard__arrow {
    flex: none;
    width: 2.5rem; height: 2.5rem;
    border: 1px solid var(--hairline);
    border-radius: 50%;
    display: grid;
    place-items: center;
    transition: background .4s var(--ease-out), border-color .4s var(--ease-out), transform .4s var(--ease-out);
}

.pcard__arrow svg { width: .95rem; height: .95rem; transition: transform .4s var(--ease-out); }
.pcard:hover .pcard__arrow { background: var(--red); border-color: var(--red); color: #fff; }
.pcard:hover .pcard__arrow svg { transform: translate(2px, -2px); }

/* --- Horizontal scroll gallery ------------------------------------------ */
/* No overflow:hidden here â€” an overflow on the ancestor of a sticky element
   stops the stickiness. The inner .hscroll__stage does the clipping. */
.hscroll { position: relative; }

/* Without JS this degrades to a normal swipeable row. */
.hscroll__stage {
    padding-block: 3rem;
    overflow-x: auto;
}

.js .hscroll__stage {
    position: sticky;
    top: 0;
    height: 100vh;          /* fallback for browsers without svh */
    height: 100svh;
    display: flex;
    align-items: center;
    overflow: clip;
    padding-block: 0;
}

.hscroll__track {
    display: flex;
    gap: clamp(1rem, 2.5vw, 2.5rem);
    padding-inline: var(--gutter);
    will-change: transform;
}

.hslide {
    position: relative;
    flex: none;
    width: clamp(17rem, 30vw, 30rem);
}

.hslide__media {
    aspect-ratio: 3 / 4;
    overflow: clip;
    background: var(--paper-deep);
}

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

.hslide__cap {
    margin-top: 1rem;
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-mute);
}

.hslide__cap b { color: var(--red); font-weight: 500; }

/* Intro panel that sits first in the horizontal track */
.hslide--intro {
    width: clamp(18rem, 34vw, 34rem);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

/* --- Parallax figure ---------------------------------------------------- */
.parallax {
    position: relative;
    overflow: clip;
}

.parallax img {
    width: 100%;
    height: 118%;
    object-fit: cover;
    /* Hold the components in frame as the band scrolls. */
    object-position: center 45%;
    will-change: transform;
}

/* --- Counter / capability band ------------------------------------------ */
.band {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    background: rgba(255,255,255,.12);
    border-block: 1px solid rgba(255,255,255,.12);
}

.band__cell {
    background: var(--ink);
    padding: clamp(2rem, 4vw, 3.25rem) clamp(1.25rem, 2vw, 2rem);
}

.band__num {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: clamp(2.1rem, 4.6vw, 3.9rem);
    letter-spacing: -0.035em;
    line-height: 1;
    color: #fff;
}

.band__num .unit { color: var(--red); }

.band__label {
    margin-top: 0.75rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    letter-spacing: 0;
    text-transform: none;
    color: rgba(255,255,255,.62);
}

/* --- Split feature rows ------------------------------------------------- */
.split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: clamp(2rem, 5vw, 5rem);
    align-items: center;
}

.split--flip .split__media { order: 2; }

.split__media {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: clip;
}

/* --- Process ladder ----------------------------------------------------- */
.ladder { border-top: 1px solid var(--hairline); }

.rung {
    position: relative;
    display: grid;
    grid-template-columns: 5rem 1fr 1.15fr;
    gap: clamp(1.25rem, 3vw, 3rem);
    padding-block: clamp(1.75rem, 3.5vw, 2.75rem);
    border-bottom: 1px solid var(--hairline);
    align-items: start;
    transition: background .5s var(--ease-out);
}

.rung::before {
    content: '';
    position: absolute;
    left: 0; top: 0;
    width: 0;
    height: 1px;
    background: var(--red);
    transition: width .8s var(--ease-out);
}

.rung.is-in::before { width: 100%; }
.rung:hover { background: var(--paper-warm); }

.rung__num {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    letter-spacing: 0.18em;
    color: var(--red);
    padding-top: 0.35rem;
}

.rung__title { font-size: clamp(1.2rem, 2.1vw, 1.75rem); letter-spacing: -0.025em; }
.rung__text { color: var(--ink-mute); font-size: 0.95rem; }

/* --- Page masthead (inner pages) ---------------------------------------- */
.masthead {
    position: relative;
    padding-top: calc(var(--nav-h) + clamp(4rem, 10vh, 8rem));
    padding-bottom: clamp(3rem, 7vh, 6rem);
    overflow: clip;
    background: var(--paper);
}

.masthead__inner { position: relative; z-index: 2; }

.masthead__title {
    font-size: clamp(2.4rem, 7.4vw, 6.5rem);
    letter-spacing: -0.045em;
    line-height: 0.96;
}

.masthead__lead { margin-top: 1.75rem; }

/* Diagonal red edge on inner-page mastheads */
.masthead__edge {
    position: absolute;
    top: -45%;
    right: -12%;
    width: 46vw;
    height: 130%;
    background: linear-gradient(150deg, var(--red) 0%, var(--red-deep) 100%);
    clip-path: polygon(46% 0, 100% 0, 100% 68%, 0 100%);
    opacity: .95;
    z-index: 1;
    will-change: transform;
}

.masthead__edge--ink {
    right: -20%;
    background: linear-gradient(150deg, #2A2A2E, var(--ink));
    clip-path: polygon(58% 0, 100% 0, 100% 56%, 8% 92%);
    opacity: .9;
}

/* Breadcrumb */
.crumb {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-faint);
    margin-bottom: 1.5rem;
}

.crumb a:hover { color: var(--red); }
.crumb span { color: var(--red); }

/* --- Product detail ----------------------------------------------------- */
.pdetail {
    display: grid;
    grid-template-columns: 1.05fr 0.95fr;
    gap: clamp(2rem, 5vw, 5rem);
    align-items: start;
}

/* Sticky viewer */
.pviewer { position: sticky; top: calc(var(--nav-h) + 2rem); }

.pviewer__main {
    position: relative;
    aspect-ratio: 4 / 3;
    /* clip, not hidden: `hidden` makes this a scroll container and Chrome
       then paints ::scroll-button() arrows over the photograph. */
    overflow: clip;
    background: transparent;
}

/* Images are pre-trimmed, so cover fills the frame with no letterbox. */
.pviewer__main img {
    width: 100%; height: 100%;
    object-fit: cover;
    transition: opacity .5s var(--ease-out);
}

.pviewer__thumbs {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
    gap: 0.6rem;
    margin-top: 0.75rem;
}

.pthumb {
    position: relative;
    aspect-ratio: 1;
    overflow: clip;
    background: var(--paper);
    border: 1px solid var(--hairline);
    transition: border-color .35s var(--ease-out), opacity .35s var(--ease-out);
    opacity: .58;
}

.pthumb img { width: 100%; height: 100%; object-fit: cover; }
.pthumb:hover { opacity: 1; }
.pthumb.is-on { opacity: 1; border-color: var(--red); }

/* Spec table */
.spectable { border-top: 1px solid var(--ink); }

.specrow {
    display: grid;
    grid-template-columns: 12rem 1fr;
    gap: 1.5rem;
    padding-block: 1.05rem;
    border-bottom: 1px solid var(--hairline);
    align-items: baseline;
}

/* Spec labels in the body face, sentence case. Wide-tracked uppercase mono
   at 0.65rem was hard to read against the values beside it. */
.specrow dt {
    font-family: var(--font-body);
    font-size: 0.88rem;
    font-weight: 500;
    letter-spacing: 0.005em;
    text-transform: none;
    color: var(--ink-mute);
}

.specrow dd { margin: 0; color: var(--ink); font-size: 1rem; }

/* Material chips */
.chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.45rem 0.95rem;
    border: 1px solid var(--hairline);
    border-radius: 999px;
    font-family: var(--font-body);
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink-soft);
    transition: border-color .35s var(--ease-out), color .35s var(--ease-out);
}

.chip::before {
    content: '';
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--red);
    flex: none;
}

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

/* Made-to-order note sitting under the product card actions. The red rule
   marks it as a build condition rather than another line of body copy. */
.madenote {
    margin: 1.75rem 0 0;
    padding-left: 1rem;
    border-left: 2px solid var(--red);
    max-width: 46ch;
}

.madenote__text {
    margin: 0;
    font-family: var(--font-body);
    font-size: 0.92rem;
    line-height: 1.65;
    color: var(--ink-mute);
}

/* Text-link CTA — deliberately lighter than the two buttons above it, so it
   reads as the next step on the note rather than a third competing action. */
.madenote__cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.7rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--red);
    text-decoration: none;
    transition: gap .35s var(--ease-out);
}

.madenote__cta svg { width: 15px; height: 15px; flex: none; }

.madenote__cta span {
    background-image: linear-gradient(currentColor, currentColor);
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 0 1px;
    transition: background-size .4s var(--ease-out);
}

.madenote__cta:hover { gap: 0.8rem; }
.madenote__cta:hover span { background-size: 100% 1px; }

@media (prefers-reduced-motion: reduce) {
    .madenote__cta,
    .madenote__cta span { transition: none; }
}

/* Commercial terms cards */
.terms {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1px;
    background: var(--hairline);
    border: 1px solid var(--hairline);
}

.term { background: var(--paper); padding: 1.35rem 1.4rem; }

.term dt {
    font-family: var(--font-body);
    font-size: 0.85rem;
    font-weight: 500;
    letter-spacing: 0.005em;
    text-transform: none;
    color: var(--ink-mute);
    margin-bottom: 0.45rem;
}

.term dd {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.3rem;
    letter-spacing: -0.025em;
}

/* Highlight trio on detail pages */
.hilite {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.25rem, 3vw, 2.5rem);
}

.hilite__item { position: relative; padding-top: 1.5rem; border-top: 2px solid var(--ink); }
.hilite__item h4 { font-size: 1.15rem; letter-spacing: -0.02em; margin-bottom: 0.6rem; }
.hilite__item p { color: var(--ink-mute); font-size: 0.92rem; }

/* Prev / next product pager */
.pager {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: var(--hairline);
    border-block: 1px solid var(--hairline);
}

.pager__link {
    position: relative;
    background: var(--paper);
    padding: clamp(2rem, 4vw, 3.5rem) clamp(1.5rem, 3vw, 2.5rem);
    overflow: clip;
    transition: color .45s var(--ease-out);
}

.pager__link:last-child { text-align: right; }

.pager__link::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--ink);
    transform: translateY(101%);
    transition: transform .6s var(--ease-out);
    z-index: 0;
}

.pager__link:hover::after { transform: translateY(0); }
.pager__link:hover { color: #fff; }
.pager__link > * { position: relative; z-index: 1; }

.pager__dir {
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--red);
    margin-bottom: 0.6rem;
    display: block;
}

.pager__name { font-size: clamp(1.4rem, 3vw, 2.35rem); letter-spacing: -0.03em; }

/* --- Global markets ----------------------------------------------------- */
.markets {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: rgba(255,255,255,.12);
}

.market {
    position: relative;
    background: var(--ink);
    padding: clamp(1.75rem, 3vw, 2.5rem);
    overflow: clip;
    transition: background .5s var(--ease-out);
}

.market:hover { background: #141416; }

.market__code {
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.2em;
    color: var(--red);
    margin-bottom: 1rem;
    display: block;
}

.market__name {
    font-size: clamp(1.3rem, 2.2vw, 1.85rem);
    letter-spacing: -0.025em;
    color: #fff;
    margin-bottom: 0.6rem;
}

.market__note { color: rgba(255,255,255,.55); font-size: 0.9rem; }

/* Map plot */
.plot {
    position: relative;
    aspect-ratio: 16 / 9;
    background: var(--ink);
    overflow: clip;
}

/* Specificity note: the global icon guard is
   `svg:not([width]):not([height])` = (0,2,1), which outranks a plain
   `.plot svg` = (0,1,1) and would collapse this map to 1em. Matching the
   attribute selectors here raises it to (0,3,1) so the map fills its box. */
.plot svg:not([width]):not([height]) { width: 100%; height: 100%; }

.plot__pin { transform-origin: center; }

.plot__pin circle.core { fill: var(--red); }

.plot__pin circle.halo {
    fill: none;
    stroke: var(--red);
    stroke-width: 1;
    opacity: .8;
    animation: ping 2.8s var(--ease-out) infinite;
}

@keyframes ping {
    0%   { r: 3; opacity: .9; }
    70%  { r: 16; opacity: 0; }
    100% { r: 16; opacity: 0; }
}

.plot__pin--origin circle.core { fill: #fff; }

/* --- 3D WebGL globe (three.js + globe.gl) --------------------------------
   A real sphere the visitor can grab and spin; it also drifts on its own. */
.globe { position: relative; background: none; border: 0; }

.globe__stage {
    position: relative;
    aspect-ratio: 1;
    display: grid;
    place-items: center;
    /* Red halo behind the planet, echoing the brand. */
    background: radial-gradient(circle at 50% 50%,
        rgba(215, 25, 32, .16) 0%,
        rgba(215, 25, 32, .07) 42%,
        rgba(215, 25, 32, 0) 68%);
}

.globe__canvas {
    width: 100%;
    aspect-ratio: 1;
    cursor: grab;
    touch-action: pan-y;        /* vertical page scroll still works */
    opacity: 0;
    transition: opacity .8s var(--ease-out);
}

.globe__canvas.is-ready { opacity: 1; }
.globe__canvas:active { cursor: grabbing; }
.globe__canvas canvas { display: block; border-radius: 50%; }

/* Fallback flat map if WebGL never initialises. */
.globe__stage noscript img,
.globe__stage > img {
    width: 100%;
    border-radius: 50%;
}

/* Floating address pill under the planet */
.globe__badge {
    position: relative;
    z-index: 2;
    margin: -1.5rem auto 0;
    width: max-content;
    max-width: 100%;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.7rem 1.15rem;
    border-radius: 999px;
    background: var(--paper);
    box-shadow: 0 0.9rem 2.2rem -0.6rem rgba(10, 10, 11, .22);
}

.globe__badge-pin {
    flex: none;
    width: 1.6rem;
    height: 1.6rem;
    color: var(--red);
}
.globe__badge-pin svg { width: 100%; height: 100%; }

.globe__badge b {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.92rem;
    letter-spacing: -0.015em;
    line-height: 1.2;
    color: var(--ink);
}

.globe__badge em {
    font-family: var(--font-body);
    font-style: normal;
    font-size: 0.85rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink-mute);
}

/* Caption plate under the globe */
.globe__tag {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    margin-top: 1.25rem;
    padding: 0.9rem 1.1rem;
    border-left: 3px solid var(--red);
    background: var(--paper);
    font-size: 0.82rem;
    line-height: 1.55;
    color: var(--ink-mute);
}

.globe__tag b {
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 0.95rem;
    letter-spacing: -0.015em;
    color: var(--ink);
}

.globe__dot {
    position: relative;
    flex: none;
    width: 9px;
    height: 9px;
    margin-top: 0.4rem;
    border-radius: 50%;
    background: var(--red);
}

.globe__dot::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 1px solid var(--red);
    animation: globePing 2.6s var(--ease-out) infinite;
}

@keyframes globePing {
    0%   { transform: scale(.55); opacity: .9; }
    70%  { transform: scale(2.3); opacity: 0; }
    100% { transform: scale(2.3); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .globe__dot::after { animation: none; opacity: .35; }
}
/* --- Forms -------------------------------------------------------------- */
.form { display: grid; gap: 1.5rem; }

.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }

.field { position: relative; display: grid; gap: 0.5rem; }

.field label {
    font-family: var(--font-mono);
    font-size: 0.63rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--ink-mute);
}

.field label .req { color: var(--red); }

.field input,
.field select,
.field textarea {
    width: 100%;
    padding: 0.95rem 0;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--hairline);
    border-radius: 0;
    font-size: 1rem;
    transition: border-color .4s var(--ease-out);
    appearance: none;
}

.field select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' stroke='%236B6B72' stroke-width='1.4' fill='none'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .25rem center;
    background-size: .7rem;
    padding-right: 1.5rem;
    cursor: pointer;
}

.field textarea { resize: vertical; min-height: 7rem; }

.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-bottom-color: var(--red);
}

.field input::placeholder,
.field textarea::placeholder { color: var(--ink-faint); }

.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-bottom-color: var(--red); }

.field__error {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.1em;
    color: var(--red);
    min-height: 1rem;
}

/* Honeypot */
.field--trap {
    position: absolute;
    left: -9999px;
    width: 1px; height: 1px;
    overflow: clip;
}

/* Alerts */
.alert {
    display: flex;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    border-left: 3px solid var(--red);
    background: var(--paper-warm);
    font-size: 0.95rem;
    margin-bottom: 2rem;
}

.alert--ok { border-left-color: #12805C; }
.alert strong { display: block; margin-bottom: 0.25rem; }

/* Quote summary aside */
.qaside {
    background: var(--ink);
    color: rgba(255,255,255,.72);
    padding: clamp(1.75rem, 3vw, 2.5rem);
    position: sticky;
    top: calc(var(--nav-h) + 2rem);
}

.qaside h3 { color: #fff; font-size: 1.5rem; margin-bottom: 1.25rem; }

.qaside__list { display: grid; gap: 1rem; margin-top: 1.5rem; }

.qaside__row {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid rgba(255,255,255,.12);
    font-size: 0.88rem;
}

.qaside__row b { color: #fff; font-weight: 500; }

/* --- Contact ------------------------------------------------------------ */
.ccards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1px;
    background: var(--hairline);
    border: 1px solid var(--hairline);
}

.ccard {
    background: var(--paper);
    padding: clamp(1.75rem, 3vw, 2.5rem);
    transition: background .45s var(--ease-out);
}

.ccard:hover { background: var(--paper-warm); }

.ccard__icon {
    width: 2.75rem; height: 2.75rem;
    display: grid; place-items: center;
    border: 1px solid var(--hairline);
    border-radius: 50%;
    margin-bottom: 1.35rem;
    color: var(--red);
}

.ccard__icon svg { width: 1.1rem; height: 1.1rem; }

/* Card headings read as labels, but at a legible size in the body face
   rather than wide-tracked uppercase mono. */
.ccard h3 {
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 600;
    letter-spacing: 0.005em;
    text-transform: none;
    color: var(--ink-soft);
    margin-bottom: 0.7rem;
}

.ccard p, .ccard address {
    font-style: normal;
    font-size: 1.02rem;
    line-height: 1.65;
    color: var(--ink-soft);
}

.ccard a:hover { color: var(--red); }

/* --- CTA slab ----------------------------------------------------------- */
.cta {
    position: relative;
    background: var(--ink);
    color: #fff;
    overflow: clip;
    padding-block: clamp(4.5rem, 11vh, 8.5rem);
}

.cta__edge {
    position: absolute;
    top: -25%;
    right: -8%;
    width: 44vw;
    height: 150%;
    background: linear-gradient(150deg, var(--red) 0%, var(--red-deep) 100%);
    clip-path: polygon(44% 0, 100% 0, 100% 70%, 0 100%);
    opacity: .92;
    will-change: transform;
}

.cta__inner { position: relative; z-index: 2; max-width: 46rem; }

.cta__title {
    font-size: clamp(2.2rem, 6vw, 4.75rem);
    letter-spacing: -0.04em;
    line-height: 0.95;
    color: #fff;
    margin-bottom: 1.5rem;
}

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 1080px) {
    .hero { min-height: auto; }
    .hero__inner {
        grid-template-columns: 1fr;
        gap: clamp(2rem, 5vh, 3rem);
        padding-block: clamp(2rem, 5vh, 3.5rem) clamp(3rem, 7vh, 5rem);
    }
    .hero__plate {
        max-width: 100%;
        aspect-ratio: 3 / 2;
        margin-left: 0;
    }
    .hero__title { font-size: clamp(2.4rem, 7.2vw, 4.25rem); }
    .film__grid { grid-template-columns: 1fr; gap: 2rem; }
    .film__plate { aspect-ratio: 16/10; }
    .film__ghost { display: none; }
    .film__rail { display: none; }
    .pdetail { grid-template-columns: 1fr; }
    .pviewer { position: static; }
    .split { grid-template-columns: 1fr; }
    .split--flip .split__media { order: 0; }
    .markets { grid-template-columns: repeat(2, 1fr); }
    .band { grid-template-columns: repeat(2, 1fr); }
    .ccards { grid-template-columns: 1fr; }
    .hilite { grid-template-columns: 1fr; gap: 1.75rem; }
    .qaside { position: static; }
}

@media (max-width: 860px) {
    .pcard, .pcard--wide { grid-column: span 6; }
    .rung { grid-template-columns: 3.5rem 1fr; }
    .rung__text { grid-column: 2; }
}

@media (max-width: 620px) {
    /* Keep the sweeps as a compact corner accent, clear of the body copy. */
    .hero__sweep {
        width: 54vw;
        right: -16%;
        top: -18%;
        height: 46vh;
        opacity: .9;
    }
    .hero__sweep--ink {
        width: 48vw;
        right: -24%;
        top: -22%;
        height: 42vh;
    }

    /* Give the lead paragraph a clean white backdrop on small screens. */
    .hero__meta { position: relative; z-index: 4; }

    /* Chips become one swipeable row instead of a tall stack. */
    .hero__index-list {
        flex-wrap: nowrap;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        margin-inline: calc(var(--gutter) * -1);
        padding-inline: var(--gutter);
        padding-bottom: 0.35rem;
    }
    .hero__index-list::-webkit-scrollbar { display: none; }
    .hero__index-list > li { scroll-snap-align: start; flex: none; }

    .hero__stats { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; }
    .pcard, .pcard--wide { grid-column: span 12; }
    .film__specs { grid-template-columns: 1fr; }
    .film__spec { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
    .film__spec dt { margin-bottom: 0; }
    .markets { grid-template-columns: 1fr; }
    .band { grid-template-columns: 1fr; }
    .terms { grid-template-columns: 1fr; }
    .form__row { grid-template-columns: 1fr; }
    .specrow { grid-template-columns: 1fr; gap: 0.35rem; }
    .pager { grid-template-columns: 1fr; }
    .pager__link:last-child { text-align: left; }
    .masthead__edge { width: 88vw; right: -30%; }
    .cta__edge { width: 90vw; right: -35%; }
}

/* --- Reduced motion -----------------------------------------------------
   Placed last in the file so these rules win over the .js-prefixed pinning
   rules above. The pinned film and horizontal gallery unstack into plain,
   readable sections. !important is used deliberately: the JS also writes
   inline heights on these wrappers when motion is allowed. */
@media (prefers-reduced-motion: reduce) {
    .ribbon__track { animation: none; }
    .scroll-cue__rail::after { animation: none; transform: scaleX(1); }
    .plot__pin circle.halo { animation: none; opacity: .35; }

    .film { height: auto !important; }

    .film__stage {
        position: relative !important;
        top: auto !important;
        height: auto !important;
        display: block !important;
        overflow: visible !important;
    }

    .film__scene {
        position: relative !important;
        inset: auto !important;
        opacity: 1 !important;
        visibility: visible !important;
        padding-block: clamp(2.5rem, 6vh, 4rem) !important;
    }

    .film__plate img { transform: none !important; }
    .film__rail { display: none !important; }

    .hscroll { height: auto !important; }

    .hscroll__stage {
        position: relative !important;
        top: auto !important;
        height: auto !important;
        display: block !important;
        overflow-x: auto !important;
        padding-block: 3rem !important;
    }

    .hscroll__track { transform: none !important; }
}

/* ==========================================================================
   REQUEST A QUOTE (quote.php)
   Scoped to .rfq* — no other page uses these classes.
   ========================================================================== */

/* --- Masthead ----------------------------------------------------------- */
.rfq-head {
    position: relative;
    padding-top: calc(var(--nav-h) + clamp(2.5rem, 6vh, 4.5rem));
    padding-bottom: clamp(2rem, 4vh, 3rem);
    background: var(--paper);
    overflow: clip;
}

.rfq-head__inner { position: relative; z-index: 2; }

/* Brand graphic: three red rules stepping off the right edge, aligned to
   the page grid rather than floating as a decorative blob. */
.rfq-head__mark {
    position: absolute;
    top: 0;
    right: 0;
    width: min(38vw, 26rem);
    height: 100%;
    z-index: 1;
    pointer-events: none;
    display: grid;
    align-content: center;
    gap: clamp(0.7rem, 1.4vw, 1.15rem);
}

.rfq-head__bar {
    display: block;
    height: clamp(0.5rem, 1vw, 0.85rem);
    background: linear-gradient(90deg, var(--red) 0%, var(--red-deep) 100%);
    transform-origin: right center;
    will-change: transform;
}

/* --rfq-o carries each bar's resting opacity so the reveal animation can
   settle on it instead of forcing every bar to full strength. */
.rfq-head__bar:nth-child(1) { width: 100%; --rfq-o: 1;   opacity: var(--rfq-o); }
.rfq-head__bar:nth-child(2) { width: 74%;  --rfq-o: .62; opacity: var(--rfq-o); margin-left: 26%; }
.rfq-head__bar:nth-child(3) { width: 46%;  --rfq-o: .30; opacity: var(--rfq-o); margin-left: 54%; }

.js .rfq-head__bar {
    opacity: 0;
    transform: translateX(2.5rem);
    animation: rfqBar .95s var(--ease-out) forwards;
}

.js .rfq-head__bar:nth-child(1) { animation-delay: .10s; }
.js .rfq-head__bar:nth-child(2) { animation-delay: .20s; }
.js .rfq-head__bar:nth-child(3) { animation-delay: .30s; }

@keyframes rfqBar {
    to { opacity: var(--rfq-o); transform: translateX(0); }
}

.rfq-head__title {
    font-size: clamp(2.4rem, 7vw, 5.6rem);
    letter-spacing: -0.045em;
    line-height: 0.96;
}

.rfq-head__lead {
    margin-top: 1.5rem;
    max-width: 46ch;
    font-size: clamp(1rem, 1.25vw, 1.15rem);
    line-height: 1.65;
    color: var(--ink-mute);
}

/* --- Layout ------------------------------------------------------------- */
.rfq {
    position: relative;
    padding-top: clamp(2rem, 5vh, 3.5rem);
    padding-bottom: clamp(4rem, 10vh, 7rem);
    background: var(--paper);
}

.rfq > .shell { position: relative; z-index: 2; }

.rfq__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 0.65fr);
    gap: clamp(2.5rem, 5vw, 5rem);
    align-items: start;
}

/* --- Form --------------------------------------------------------------- */
.rfq__form { gap: 1.65rem; }

/* Numbered section rule */
.rfq__legend {
    display: flex;
    align-items: center;
    gap: 0.9rem;
    padding-bottom: 0.9rem;
    border-bottom: 1px solid var(--ink);
}

.rfq__legend--gap { margin-top: 1.35rem; }

/* The section number stays mono — it reads as a technical index, and a short
   numeral is legible at this size. */
.rfq__legend-no {
    font-family: var(--font-mono);
    font-size: 0.82rem;
    font-weight: 500;
    letter-spacing: 0.06em;
    color: var(--red);
}

/* Section and field labels use the body face in sentence case. Wide-tracked
   uppercase mono is hard to read at label sizes, so only the numeral keeps it. */
.rfq__legend-text {
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink);
}

/* ------------------------------------------------------------------------
   .form--readable
   Legible form typography, shared by the RFQ and Contact forms. The site
   default sets labels in wide-tracked uppercase mono at 0.63rem, which is
   hard to read at label size — here they use the body face in sentence case.
   Opt-in, so no other form is affected.
   ------------------------------------------------------------------------ */
.form--readable .field label {
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.005em;
    text-transform: none;
    color: var(--ink-soft);
}

/* The upload drop area is itself a <label>; it must not inherit the above. */
.form--readable .field label.rfq-file { font-size: inherit; font-weight: 400; }

.form--readable .field { gap: 0.35rem; }

/* Error text should be readable too, not a mono caption. */
.form--readable .field__error {
    font-family: var(--font-body);
    font-size: 0.8rem;
    letter-spacing: 0;
}

/* Larger, more comfortable inputs than the site default */
.form--readable .field input,
.form--readable .field select,
.form--readable .field textarea {
    padding: 1.05rem 0.15rem;
    font-family: var(--font-body);
    font-size: 1.05rem;
    color: var(--ink);
}

.form--readable .field textarea { min-height: 9rem; line-height: 1.65; }

/* Placeholders were too faint to read against white. */
.form--readable .field input::placeholder,
.form--readable .field textarea::placeholder {
    color: #9497A0;
    opacity: 1;
}

/* Red focus state with a weight change, not a glow */
.form--readable .field input:focus,
.form--readable .field select:focus,
.form--readable .field textarea:focus {
    border-bottom-color: var(--red);
    box-shadow: 0 1px 0 0 var(--red);
}

/* --- File upload -------------------------------------------------------- */
.rfq-file__input {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: clip;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.rfq-file {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1.15rem 1.25rem;
    border: 1px dashed var(--hairline);
    background: var(--paper-warm);
    cursor: pointer;
    transition: border-color .35s var(--ease-out),
                background .35s var(--ease-out);
}

.rfq-file:hover {
    border-color: var(--red-line);
    background: #fff;
}

.rfq-file__input:focus-visible + .field__error,
.rfq-file__input:focus-visible ~ .rfq-file { outline: 2px solid var(--red); outline-offset: 2px; }

.rfq-file__icon {
    flex: 0 0 auto;
    width: 2.4rem; height: 2.4rem;
    display: grid;
    place-items: center;
    background: var(--paper);
    border: 1px solid var(--hairline);
    color: var(--red);
}

.rfq-file__icon svg { width: 1.15rem; height: 1.15rem; }

.rfq-file__text { display: grid; gap: 0.2rem; min-width: 0; }

.rfq-file__text b {
    font-size: 0.92rem;
    font-weight: 500;
    color: var(--ink);
    overflow-wrap: anywhere;
}

.rfq-file__text em {
    font-family: var(--font-body);
    font-style: normal;
    font-size: 0.8rem;
    letter-spacing: 0;
    color: var(--ink-mute);
}

.rfq-file.has-file { border-style: solid; border-color: var(--red-line); background: #fff; }
.rfq-file.has-file .rfq-file__icon { border-color: var(--red-line); }

/* --- Submit ------------------------------------------------------------- */
.rfq__submit {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1.25rem 1.75rem;
    margin-top: 0.85rem;
    padding-top: 1.85rem;
    border-top: 1px solid var(--hairline);
}

.rfq__send { padding-inline: 2.4rem; }

.rfq__submit-note {
    font-size: 0.85rem;
    color: var(--ink-mute);
    max-width: 34ch;
    line-height: 1.6;
}

/* --- Aside -------------------------------------------------------------- */
.rfq__aside { position: sticky; top: calc(var(--nav-h) + 2rem); }

.qaside__intro {
    font-size: 0.95rem;
    line-height: 1.7;
    color: rgba(255, 255, 255, .62);
}

/* Readable aside rows: label and value both step up a little. */
.rfq__aside .qaside__row { font-size: 0.95rem; padding-bottom: 0.95rem; }
.rfq__aside .qaside__row span { color: rgba(255, 255, 255, .62); }
.rfq__aside .qaside__row b { font-weight: 600; }

/* Breadcrumb: keep the mono character but make it legible. */
.rfq-head .crumb { font-size: 0.85rem; letter-spacing: 0.01em; }

.qaside__talk {
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgba(255, 255, 255, .12);
    display: grid;
    gap: 0.45rem;
}

.qaside__talk span {
    font-family: var(--font-body);
    font-size: 0.85rem;
    letter-spacing: 0;
    text-transform: none;
    color: rgba(255, 255, 255, .55);
}

.qaside__talk a {
    color: #fff;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.2rem;
    letter-spacing: -0.02em;
    transition: color .3s var(--ease-out);
}

.qaside__talk a:hover { color: var(--red); }

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 62rem) {
    .rfq__grid { grid-template-columns: 1fr; }
    .rfq__aside { position: static; }
    .rfq-head__mark { width: 46vw; opacity: .9; }
}

@media (max-width: 40rem) {
    .rfq__form .form__row { grid-template-columns: 1fr; gap: 1.65rem; }
    .rfq-head__mark { width: 58vw; }
    .rfq__submit { gap: 1rem; }
    .rfq__send { width: 100%; justify-content: center; }
    .rfq__submit-note { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
    .js .rfq-head__bar { animation: none; opacity: var(--rfq-o); transform: none; }
}

/* ==========================================================================
   THEME / ATMOSPHERE
   A layered backdrop for light and dark sections: a fine engineering grid,
   measure ticks along the edge, and a soft heat bloom in the brand red.
   All layers are decorative, pointer-events:none, and sit behind content.
   ========================================================================== */

/* --- Blueprint field ----------------------------------------------------
   A two-tier grid: 1.4rem minor cells inside 7rem major cells, so it reads
   as drafting paper rather than a flat CSS checkerboard. */
.bp {
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    overflow: clip;
}

.bp::before {
    content: '';
    position: absolute;
    inset: -2px;
    background-image:
        /* major */
        linear-gradient(to right,  rgba(10,10,11,.055) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(10,10,11,.055) 1px, transparent 1px),
        /* minor */
        linear-gradient(to right,  rgba(10,10,11,.028) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(10,10,11,.028) 1px, transparent 1px);
    background-size:
        7rem 7rem,
        7rem 7rem,
        1.4rem 1.4rem,
        1.4rem 1.4rem;
    mask-image: radial-gradient(ellipse 90% 70% at 50% 35%, #000 25%, transparent 75%);
    -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 35%, #000 25%, transparent 75%);
}

/* Heat bloom — the one warm gesture. Kept very low opacity so it reads as
   atmosphere, never as a coloured panel. */
.bp::after {
    content: '';
    position: absolute;
    width: 62vw;
    height: 62vw;
    max-width: 46rem;
    max-height: 46rem;
    top: -18%;
    right: -12%;
    border-radius: 50%;
    background: radial-gradient(circle,
                rgba(215,25,32,.085) 0%,
                rgba(215,25,32,.035) 42%,
                transparent 70%);
    filter: blur(10px);
}

/* Dark variant — the grid itself is defined once, in the depth pass below,
   where the brushed-metal grain is layered onto the same background-image. */
.bp--dark::after {
    background: radial-gradient(circle,
                rgba(241,42,42,.20) 0%,
                rgba(215,25,32,.08) 45%,
                transparent 72%);
}

/* Bloom anchored bottom-left instead, for alternating sections */
.bp--flip::after { top: auto; bottom: -20%; right: auto; left: -14%; }

/* --- Measure rule -------------------------------------------------------
   Calibration ticks down the left edge — a vernier scale, the kind printed
   on an engineering drawing. Hidden on narrow screens where it would crowd
   the gutter. */
.measure {
    position: absolute;
    top: 0;
    bottom: 0;
    left: calc(var(--gutter) * 0.34);
    width: 1.1rem;
    z-index: 1;
    pointer-events: none;
    background-image:
        linear-gradient(to bottom, rgba(10,10,11,.16) 1px, transparent 1px);
    background-size: 100% 1.4rem;
    background-position: 0 0;
    mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
    -webkit-mask-image: linear-gradient(to bottom, transparent, #000 18%, #000 82%, transparent);
}

/* Every fifth tick runs full width and turns red — the index mark. */
.measure::after {
    content: '';
    position: absolute;
    inset: 0;
    background-image: linear-gradient(to bottom, var(--red) 1px, transparent 1px);
    background-size: 100% 7rem;
    opacity: .5;
}

.measure--dark { background-image: linear-gradient(to bottom, rgba(255,255,255,.2) 1px, transparent 1px); }

@media (max-width: 60rem) { .measure { display: none; } }

/* --- Corner registration marks -----------------------------------------
   Crop marks of the kind used to register a drawing sheet. Purely a frame
   device; they sit at the section's inner corners. */
.regmark {
    position: absolute;
    width: 0.9rem;
    height: 0.9rem;
    z-index: 1;
    pointer-events: none;
    opacity: .55;
}

.regmark::before,
.regmark::after {
    content: '';
    position: absolute;
    background: var(--red);
}

.regmark::before { left: 0; top: 0; width: 100%; height: 1px; }
.regmark::after  { left: 0; top: 0; width: 1px;  height: 100%; }

.regmark--tl { top: 1.5rem; left: var(--gutter); }
.regmark--tr { top: 1.5rem; right: var(--gutter); transform: scaleX(-1); }
.regmark--bl { bottom: 1.5rem; left: var(--gutter); transform: scaleY(-1); }
.regmark--br { bottom: 1.5rem; right: var(--gutter); transform: scale(-1); }

@media (max-width: 60rem) { .regmark { display: none; } }

/* --- Section content sits above every backdrop layer -------------------- */
.section > .shell,
.section--dark > .shell,
.masthead__inner,
.rfq-head__inner { position: relative; z-index: 2; }

/* --- Backdrop motion ----------------------------------------------------
   The bloom breathes very slowly. Long duration and tiny amplitude keep it
   subliminal — you notice the page feels alive, not that something moves. */
@keyframes bpBreathe {
    0%, 100% { transform: scale(1)    translate3d(0, 0, 0);      opacity: .9; }
    50%      { transform: scale(1.08) translate3d(0, 1.5%, 0);   opacity: 1;  }
}

.js .bp::after {
    animation: bpBreathe 14s ease-in-out infinite;
    will-change: transform, opacity;
}

/* The grid fades up once on first paint rather than snapping in. */
@keyframes bpFade { from { opacity: 0; } to { opacity: 1; } }

.js .bp::before { animation: bpFade 1.2s var(--ease-out) both; }

/* Registration marks tick in after the grid has settled. */
@keyframes regIn {
    from { opacity: 0; transform: translate3d(0, -0.4rem, 0); }
}

.js .regmark { animation: regIn .8s var(--ease-out) .5s both; }
.js .regmark--tr { animation-name: regInTr; }
.js .regmark--bl { animation-name: regInBl; }
.js .regmark--br { animation-name: regInBr; }

/* Each corner keeps its own flip transform while animating in. */
@keyframes regInTr { from { opacity: 0; } to { opacity: .55; transform: scaleX(-1); } }
@keyframes regInBl { from { opacity: 0; } to { opacity: .55; transform: scaleY(-1); } }
@keyframes regInBr { from { opacity: 0; } to { opacity: .55; transform: scale(-1);  } }

@media (prefers-reduced-motion: reduce) {
    .js .bp::after,
    .js .bp::before,
    .js .regmark { animation: none; }
}

/* ==========================================================================
   THEME — DEPTH PASS
   Adds dimension on top of the .bp backdrop: edge seams between sections,
   a cursor-tracked sheen, scanning highlights and material texture.
   ========================================================================== */

/* --- Section seams ------------------------------------------------------
   A hairline with a short red index tick where two sections meet, so the
   page reads as a stack of drawing sheets rather than one long scroll. */
.section,
.section--dark,
.rfq { --seam: var(--hairline); }

.section--dark { --seam: rgba(255,255,255,.14); }

.section + .section,
.section + .section--dark,
.section--dark + .section,
.section--warm + .section,
.section + .rfq { position: relative; }

.section + .section::before,
.section--dark + .section::before,
.section + .section--dark::before {
    content: '';
    position: absolute;
    top: 0;
    left: var(--gutter);
    right: var(--gutter);
    height: 1px;
    background: var(--seam);
    z-index: 1;
}

/* The index tick that sits on the seam */
.section + .section::after,
.section--dark + .section::after,
.section + .section--dark::after {
    content: '';
    position: absolute;
    top: 0;
    left: var(--gutter);
    width: 3.25rem;
    height: 2px;
    background: var(--red);
    z-index: 2;
}

/* --- Cursor sheen -------------------------------------------------------
   A very soft radial highlight that tracks the pointer across dark slabs.
   Driven by --mx/--my set in JS; defaults keep it harmless without JS. */
.sheen {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    opacity: 0;
    transition: opacity .6s var(--ease-out);
    background: radial-gradient(
        26rem circle at var(--mx, 50%) var(--my, 50%),
        rgba(241,42,42,.16) 0%,
        rgba(215,25,32,.06) 38%,
        transparent 68%);
}

.has-sheen:hover .sheen { opacity: 1; }

/* --- Material texture ---------------------------------------------------
   A faint brushed-metal grain over dark slabs. Pure CSS, no image request.
   Applied to .bp--dark rather than the section itself, because ::after on
   the section is already spoken for by the seam tick above. */
.bp--dark::before {
    background-image:
        linear-gradient(to right,  rgba(255,255,255,.07) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255,255,255,.07) 1px, transparent 1px),
        linear-gradient(to right,  rgba(255,255,255,.032) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255,255,255,.032) 1px, transparent 1px),
        repeating-linear-gradient(
            104deg,
            rgba(255,255,255,.02) 0px,
            rgba(255,255,255,.02) 1px,
            transparent 1px,
            transparent 3px);
    background-size:
        7rem 7rem,
        7rem 7rem,
        1.4rem 1.4rem,
        1.4rem 1.4rem,
        auto;
}

/* --- Stat & band emphasis ----------------------------------------------- */
.band__cell { position: relative; overflow: clip; }

/* A red rule wipes across each band cell as it enters view. */
.band__cell::after {
    content: '';
    position: absolute;
    left: 0; bottom: 0;
    width: 100%;
    height: 2px;
    background: var(--red);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 1s var(--ease-out);
}

.band__cell.is-in::after,
.band:hover .band__cell::after { transform: scaleX(1); }

/* --- Product card lift -------------------------------------------------- */
.pcard {
    transition: transform .6s var(--ease-out), box-shadow .6s var(--ease-out);
}

.pcard:hover {
    transform: translateY(-0.4rem);
    box-shadow: 0 1.75rem 3.5rem -1.5rem rgba(10,10,11,.28);
}

/* Corner bracket that draws itself on hover — a machinist's datum mark. */
.pcard__media::after {
    content: '';
    position: absolute;
    top: 0.85rem; right: 0.85rem;
    width: 1.5rem; height: 1.5rem;
    border-top: 2px solid #fff;
    border-right: 2px solid #fff;
    opacity: 0;
    transform: translate3d(-0.5rem, 0.5rem, 0);
    transition: opacity .5s var(--ease-out), transform .5s var(--ease-out);
    z-index: 2;
}

.pcard:hover .pcard__media::after { opacity: .9; transform: none; }

/* --- Market tiles ------------------------------------------------------- */
.market { position: relative; transition: transform .5s var(--ease-out); }
.market:hover { transform: translateY(-0.25rem); }

.market__code {
    transition: color .4s var(--ease-out), letter-spacing .4s var(--ease-out);
}

.market:hover .market__code { color: var(--red); letter-spacing: 0.2em; }

/* --- Reduced motion ----------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    .pcard, .market { transition: none; }
    .pcard:hover { transform: none; }
    .market:hover { transform: none; }
    .band__cell::after { transition: none; transform: scaleX(1); }
}

/* ==========================================================================
   BROWSER SCROLL-BUTTON SUPPRESSION
   Chrome renders ::scroll-button() carousel arrows over scroll containers.
   They were appearing as ←/→ discs on the product photographs. Nothing here
   is a carousel, so switch them off.

   Each selector gets its OWN rule on purpose: a browser that does not know
   one of these pseudo-elements discards the entire rule it appears in, so
   grouping them would take the working ones down with the unknown ones.
   ========================================================================== */
/* Defensive: some browser extensions (image viewers, "download image" and
   gallery helpers) inject their own prev/next overlay buttons as direct
   children of any element wrapping an <img>. Our media boxes only ever
   contain the image itself plus our own labelled spans, so anything else
   sitting in there is not ours and is hidden. */
.pcard__media > *:not(img):not(.pcard__index):not(.pcard__wipe),
.pviewer__main > *:not(img),
.split__media > *:not(img),
.hero__plate  > *:not(img):not(.hero__plate-tag) {
    display: none !important;
}

/* Same guard, one level deeper — several extensions wrap their controls in
   a positioned container before injecting the buttons. */
.pcard__media *:not(img):not(.pcard__index):not(.pcard__wipe),
.pviewer__main *:not(img),
.split__media *:not(img) {
    display: none !important;
}

/* Common class/attribute names used by image-viewer and gallery extensions.
   Hidden document-wide so an overlay anchored to <body> is caught too. */
[class*="imagus"], [class*="hoverzoom"], [class*="HoverZoom"],
[class*="image-viewer"], [class*="imageViewer"],
[class*="gallery-nav"], [class*="galleryNav"],
[class*="lightbox-nav"], [class*="photo-nav"],
[id*="imagus"], [id*="hoverZoom"],
[data-extension], [data-gallery-nav] {
    display: none !important;
}

::scroll-button(*)      { display: none !important; }
::scroll-button(left)   { display: none !important; }
::scroll-button(right)  { display: none !important; }
::scroll-button(up)     { display: none !important; }
::scroll-button(down)   { display: none !important; }
::scroll-button(inline-start) { display: none !important; }
::scroll-button(inline-end)   { display: none !important; }
::scroll-button(block-start)  { display: none !important; }
::scroll-button(block-end)    { display: none !important; }
::scroll-marker         { display: none !important; }
::scroll-marker-group   { display: none !important; }
::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

/* The real fix: Chrome only attaches that UI to a scroll container. These
   tiles clip their content instead of scrolling it, so no scroll UI is ever
   created. `clip` (not `hidden`) is what makes the box a non-scroller. */
.pcard__media,
.split__media,
.pviewer__main,
.mask-img,
.hslide__media,
.hero__plate {
    overflow: clip;
    scrollbar-width: none;
    scroll-behavior: auto;
    overflow-anchor: none;
}

.pcard__media::-webkit-scrollbar,
.split__media::-webkit-scrollbar,
.pviewer__main::-webkit-scrollbar,
.mask-img::-webkit-scrollbar { display: none; }

/* ==========================================================================
   PRODUCT PAGE (product.php)
   Treats the page as a component datasheet: a stamped part index, a spec
   table that reads as a drawing block, and a dark engineering-notes slab.
   ========================================================================== */

/* --- Stamped part index -------------------------------------------------
   The oversized numeral behind the title. Outlined rather than filled so it
   frames the headline instead of fighting it. */
.pdt-head { position: relative; }

.pdt-head__ghost {
    position: absolute;
    right: clamp(1rem, 6vw, 7rem);
    bottom: -2.5rem;
    z-index: 1;
    font-family: var(--font-display);
    font-weight: 900;
    font-size: clamp(9rem, 26vw, 24rem);
    line-height: 0.72;
    letter-spacing: -0.05em;
    color: transparent;
    -webkit-text-stroke: 1px rgba(215, 25, 32, .16);
    pointer-events: none;
    user-select: none;
    will-change: transform;
}

@media (max-width: 60rem) {
    .pdt-head__ghost { right: -0.5rem; bottom: -1.5rem; opacity: .7; }
}

/* --- Detail / spec block ------------------------------------------------ */
.pdt-detail { position: relative; }
.pdt-detail > .shell { position: relative; z-index: 2; }

/* The spec list reads as a drawing title block: ruled rows, mono values. */
.pdt-detail .spectable {
    border-top: 2px solid var(--ink);
    background:
        linear-gradient(180deg, rgba(247,246,244,.7) 0%, transparent 60%);
}

.pdt-detail .specrow {
    transition: background .35s var(--ease-out), padding-left .35s var(--ease-out);
}

/* Hovering a spec row highlights it and steps it in, like a cursor moving
   down a printed table. */
.pdt-detail .specrow:hover {
    background: rgba(215, 25, 32, .04);
    padding-left: 0.6rem;
}

/* --- Engineering notes slab --------------------------------------------
   Inverted from the old warm panel so the page has a strong dark break. */
.pdt-notes { position: relative; overflow: clip; }

.pdt-notes .hilite__item {
    border-top-color: var(--red);
    padding-top: 1.6rem;
    transition: transform .5s var(--ease-out);
}

.pdt-notes .hilite__item:hover { transform: translateY(-0.3rem); }

.pdt-notes .hilite__item h4 { color: #fff; }
.pdt-notes .hilite__item p  { color: rgba(255, 255, 255, .62); }

/* A hairline runs the full width behind the items, so the red rules read as
   ticks on a shared datum rather than three unrelated bars. */
.pdt-notes .hilite {
    position: relative;
    padding-top: 1px;
}

.pdt-notes .hilite::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: rgba(255, 255, 255, .16);
}

/* --- Gallery ------------------------------------------------------------ */
.pdt-gallery { position: relative; }
.pdt-gallery > .shell { position: relative; z-index: 2; }

@media (max-width: 60rem) {
    .pdt-notes .hilite { grid-template-columns: 1fr; }
}

/* --- Product page: readable section labels ------------------------------
   The global .eyebrow is 0.7rem uppercase mono at 0.24em tracking. On the
   datasheet it sits directly above dense spec content, so it gets the body
   face at a legible size while keeping the red rule that identifies it. */
.pdt-detail .eyebrow,
.pdt-notes .eyebrow,
.pdt-gallery .eyebrow {
    font-family: var(--font-body);
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    text-transform: none;
    color: var(--ink);
}

.pdt-notes .eyebrow { color: rgba(255, 255, 255, .82); }

/* Engineering-notes body copy on the dark slab. */
.pdt-notes .hilite__item h4 { font-size: 1.2rem; }
.pdt-notes .hilite__item p  { font-size: 0.95rem; line-height: 1.7; }

/* The note under the spec table. */
.pdt-detail .t-body { font-size: 0.95rem; line-height: 1.7; color: var(--ink-mute); }

/* =========================================================================
   WhatsApp widget
   A launcher pinned bottom-right, and a chat-styled panel that composes the
   message before handing it to WhatsApp.
   ========================================================================= */
.wa {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    z-index: 900;

    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .85rem;
}

/* --- Launcher ------------------------------------------------------------ */
.wa-float {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 0;

    width: 68px;
    height: 68px;
    padding: 0;
    justify-content: center;
    border: 0;
    border-radius: 50%;

    /* Transparent here: the fill is painted by ::before so the pulse ring can
       sit between the fill and the icon rather than behind the whole button. */
    background: transparent;
    color: #fff;
    font: inherit;
    text-decoration: none;
    cursor: pointer;

    isolation: isolate;

    box-shadow: 0 6px 16px rgba(37, 211, 102, .18), 0 2px 6px rgba(0, 0, 0, .14);
    transition: transform .28s cubic-bezier(.22, 1, .36, 1), box-shadow .28s ease;
}

.wa-float::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: linear-gradient(145deg, #2CE06E 0%, #25D366 55%, #1EBE5A 100%);
    z-index: 1;
    transition: filter .2s ease;
}

.wa-float:hover::before,
.wa-float:focus-visible::before { filter: brightness(1.12); }

.wa-float:hover,
.wa-float:focus-visible {
    transform: translateY(-3px);
    box-shadow: 0 10px 22px rgba(37, 211, 102, .26), 0 3px 8px rgba(0, 0, 0, .16);
}

.wa-float:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 3px;
}

svg.wa-float__icon {
    position: relative;
    z-index: 2;
    width: 56px;
    height: 56px;
    flex: none;
    transition: transform .3s cubic-bezier(.22, 1, .36, 1), opacity .2s ease;
}

/* The close glyph is stacked on the WhatsApp mark; they cross-fade on open. */
svg.wa-float__icon--x {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 27px;
    height: 27px;
    margin-left: -13.5px;
    margin-top: -13.5px;
    opacity: 0;
    transform: rotate(-90deg) scale(.6);
}

.wa.is-open .wa-float__icon--wa { opacity: 0; transform: rotate(90deg) scale(.6); }
.wa.is-open .wa-float__icon--x  { opacity: 1; transform: rotate(0) scale(1); }

.wa-float__label {
    position: relative;
    z-index: 2;
    display: none;
    font-size: .92rem;
    font-weight: 600;
    letter-spacing: -.01em;
    white-space: nowrap;

    /* Collapsed by default; expands on hover. */
    max-width: 0;
    opacity: 0;
    overflow: hidden;
    transition: max-width .34s cubic-bezier(.22, 1, .36, 1), opacity .24s ease;
}

/* No expanding halo: the launcher reads as a clean solid circle. */
.wa-float__pulse { display: none; }

/* --- Panel --------------------------------------------------------------- */
.wa__panel {
    width: 340px;
    max-width: calc(100vw - 2rem);
    border-radius: 18px;
    overflow: hidden;
    background: var(--paper);
    box-shadow: 0 24px 60px rgba(0, 0, 0, .26), 0 4px 14px rgba(0, 0, 0, .12);

    transform: translateY(14px) scale(.96);
    transform-origin: bottom right;
    opacity: 0;
    transition: transform .26s cubic-bezier(.22, 1, .36, 1), opacity .2s ease;
}

.wa.is-shown .wa__panel { transform: translateY(0) scale(1); opacity: 1; }

.wa__head {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .95rem 1rem;
    background: #075E54;
    color: #fff;
}

.wa__avatar {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    flex: none;
    border-radius: 50%;
    background: #25D366;
    color: #fff;
}
.wa__avatar svg { width: 26px; height: 26px; }

.wa__id { flex: 1; min-width: 0; line-height: 1.3; }
.wa__id strong { display: block; font-size: .95rem; font-weight: 600; }
.wa__id span {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .76rem;
    color: rgba(255, 255, 255, .72);
}

.wa__dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: #25D366;
    flex: none;
}

.wa__close {
    flex: none;
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: rgba(255, 255, 255, .8);
    cursor: pointer;
    transition: background-color .2s ease, color .2s ease;
}
.wa__close svg { width: 15px; height: 15px; }
.wa__close:hover { background: rgba(255, 255, 255, .14); color: #fff; }

/* The faint paper texture of a WhatsApp thread, drawn without an image. */
.wa__body {
    padding: 1.35rem 1rem 1.5rem;
    background-color: #ECE5DD;
    background-image:
        radial-gradient(rgba(0, 0, 0, .035) 1px, transparent 1px),
        radial-gradient(rgba(0, 0, 0, .035) 1px, transparent 1px);
    background-size: 22px 22px;
    background-position: 0 0, 11px 11px;
}

.wa__bubble {
    position: relative;
    max-width: 88%;
    padding: .7rem .85rem 1.35rem;
    border-radius: 0 10px 10px 10px;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
    font-size: .88rem;
    line-height: 1.55;
    color: var(--ink-soft);
}

/* The little tail on the top-left of an incoming bubble. */
.wa__bubble::before {
    content: '';
    position: absolute;
    top: 0;
    left: -8px;
    border: 8px solid transparent;
    border-top-color: #fff;
    border-right: 0;
}

.wa__bubble p { margin: 0 0 .5rem; }
.wa__bubble p:last-of-type { margin-bottom: 0; }

.wa__time {
    position: absolute;
    right: .75rem;
    bottom: .5rem;
    font-size: .68rem;
    color: var(--ink-faint);
}

.wa__compose {
    display: flex;
    align-items: flex-end;
    gap: .55rem;
    padding: .7rem;
    background: var(--paper);
    border-top: 1px solid var(--paper-deep);
}

.wa__input {
    flex: 1;
    min-width: 0;
    height: 40px;
    max-height: 96px;
    padding: .6rem .9rem;
    border: 1px solid var(--paper-deep);
    border-radius: 20px;
    background: var(--paper-warm);
    color: var(--ink);
    font: inherit;
    font-size: .9rem;
    line-height: 1.4;
    resize: none;
    overflow-y: auto;
    transition: border-color .2s ease, background-color .2s ease;
}

.wa__input::placeholder { color: var(--ink-faint); }

.wa__input:focus {
    outline: none;
    border-color: #25D366;
    background: var(--paper);
}

.wa__send {
    flex: none;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: #25D366;
    color: #fff;
    cursor: pointer;
    transition: background-color .2s ease, transform .2s ease;
}
.wa__send svg { width: 19px; height: 19px; margin-left: -2px; }
.wa__send:hover { background: #1EBE5A; transform: scale(1.06); }
.wa__send:focus-visible { outline: 2px solid #075E54; outline-offset: 2px; }

/* --- Touch devices ------------------------------------------------------- */
@media (max-width: 700px) {
    .wa { right: 1rem; bottom: 1rem; }

    /* Slightly smaller on a phone, same proportions. */
    .wa-float { width: 61px; height: 61px; }
    svg.wa-float__icon { width: 50px; height: 50px; }
    svg.wa-float__icon--x {
        width: 23px;
        height: 35px;
        margin-left: -17.5px;
        margin-top: -17.5px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .wa__panel { transition: opacity .01ms; transform: none; }
    .wa.is-shown .wa__panel { transform: none; }
}

/* =========================================================================
   Brochure block (home)
   Copy on the left, a rendered "stack of pages" cover on the right.
   ========================================================================= */
.brochure { background: var(--paper-cool); overflow: hidden; }

.broch {
    display: grid;
    grid-template-columns: 1.05fr .95fr;
    gap: clamp(2.5rem, 6vw, 6rem);
    align-items: center;
}

.broch__list {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem .6rem;
    margin: 2rem 0 0;
    padding: 0;
    list-style: none;
}

.broch__list li {
    padding: .45rem .85rem;
    border: 1px solid var(--paper-deep);
    border-radius: 999px;
    background: var(--paper);
    font-size: .84rem;
    font-weight: 500;
    color: var(--ink-soft);
}

.broch__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .9rem;
    margin-top: 2.5rem;
}

/* --- The cover ----------------------------------------------------------- */
.broch__visual { display: flex; justify-content: center; }

.broch__stack {
    position: relative;
    width: min(100%, 25rem);
    aspect-ratio: 1 / 1.414;   /* A4 */
}

/* Two sheets peeking out behind the cover. */
.broch__sheet {
    position: absolute;
    inset: 0;
    border-radius: 4px;
    background: var(--paper);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .10);
}
.broch__sheet--2 { transform: rotate(-3deg) translate(-2%, 1.5%); }
.broch__sheet--3 { transform: rotate(-6deg) translate(-4%, 3%); opacity: .6; }

.broch__cover {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;

    border-radius: 4px;
    overflow: hidden;
    background: var(--paper);
    box-shadow: 0 26px 60px rgba(0, 0, 0, .20), 0 4px 12px rgba(0, 0, 0, .08);

    transition: transform .5s var(--ease-out);
}

.broch__stack:hover .broch__cover { transform: translateY(-6px) rotate(.6deg); }

/* The red/charcoal diagonal of the printed cover, drawn in CSS. */
.broch__band {
    position: absolute;
    top: -32%;
    left: -22%;
    width: 150%;
    height: 46%;
    background: linear-gradient(105deg,
        var(--ink) 0%, var(--ink) 34%,
        var(--red) 34%, var(--red-deep) 100%);
    transform: rotate(-38deg);
    transform-origin: top left;
}

/* Mirrored sliver along the bottom edge. */
.broch__cover::after {
    content: '';
    position: absolute;
    right: -20%;
    bottom: -26%;
    width: 120%;
    height: 32%;
    background: linear-gradient(105deg, var(--red) 0%, var(--red-deep) 62%, var(--ink) 62%);
    transform: rotate(-38deg);
    transform-origin: bottom right;
}

.broch__logo {
    position: relative;
    z-index: 2;
    width: 58%;
    height: auto;
    object-fit: contain;
}

.broch__tagline {
    position: relative;
    z-index: 2;
    text-align: center;
    font-size: .82rem;
    font-weight: 700;
    line-height: 1.6;
    letter-spacing: .02em;
    color: var(--ink-soft);
}

/* --- Responsive ---------------------------------------------------------- */
@media (max-width: 900px) {
    .broch {
        grid-template-columns: 1fr;
        gap: 3rem;
    }
    /* Cover first would push the copy below the fold on a phone. */
    .broch__visual { order: 2; }
    .broch__stack  { width: min(100%, 19rem); }
}

@media (prefers-reduced-motion: reduce) {
    .broch__stack:hover .broch__cover { transform: none; }
}

/* The cover doubles as a link to the PDF once the file is in place. */
a.broch__stack { display: block; text-decoration: none; cursor: pointer; }

.broch__read {
    position: absolute;
    left: 50%;
    bottom: 1.5rem;
    z-index: 3;
    transform: translate(-50%, .5rem);

    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .6rem 1.1rem;
    border-radius: 999px;

    background: var(--ink);
    color: #fff;
    font-size: .8rem;
    font-weight: 600;
    white-space: nowrap;

    opacity: 0;
    transition: opacity .3s ease, transform .3s var(--ease-out);
}

.broch__read svg { width: 16px; height: 16px; }

a.broch__stack:hover .broch__read,
a.broch__stack:focus-visible .broch__read {
    opacity: 1;
    transform: translate(-50%, 0);
}

a.broch__stack:focus-visible { outline: 2px solid var(--red); outline-offset: 6px; }

/* Touch devices have no hover, so the cue stays visible. */
@media (hover: none) {
    .broch__read { opacity: 1; transform: translate(-50%, 0); }
}

/* =========================================================================
   Catalogue viewer
   Full-screen overlay holding the brochure PDF, so reading it never takes
   the visitor off the site.
   ========================================================================= */
.bview {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: grid;

    place-items: center;
}

/* `display: grid` above outranks the browser default [hidden] rule, which
   would otherwise leave this overlay on top of the page eating every click. */
.bview[hidden] { display: none; }

.bview__scrim {
    position: absolute;
    inset: 0;
    background: rgba(10, 10, 11, .82);
    opacity: 0;
    transition: opacity .26s ease;
}
.bview.is-shown .bview__scrim { opacity: 1; }

.bview__panel {
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;

    width: 100%;
    height: 100%;

    overflow: hidden;
    background: var(--paper);

    opacity: 0;
    transition: opacity .24s ease;
}
.bview.is-shown .bview__panel { opacity: 1; }

.bview__bar {
    display: flex;
    align-items: center;
    gap: .9rem;
    flex: none;
    padding: .85rem 1rem .85rem 1.25rem;
    background: var(--ink);
    color: #fff;
}

.bview__title {
    flex: 1;
    min-width: 0;
    font-size: .92rem;
    font-weight: 600;
    line-height: 1.35;
}

.bview__meta {
    display: block;
    font-size: .74rem;
    font-weight: 400;
    color: rgba(255, 255, 255, .58);
}

.bview__btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .5rem .9rem;
    border-radius: 999px;
    background: var(--red);
    color: #fff;
    font-size: .82rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color .2s ease;
}
.bview__btn svg { width: 15px; height: 15px; }
.bview__btn:hover { background: var(--red-deep); }

.bview__close {
    flex: none;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .1);
    color: #fff;
    cursor: pointer;
    transition: background-color .2s ease;
}
.bview__close svg { width: 15px; height: 15px; }
.bview__close:hover { background: rgba(255, 255, 255, .22); }

.bview__stage { flex: 1; min-height: 0; background: var(--paper-deep); }

.bview__frame {
    display: block;
    width: 100%;
    height: 100%;
    border: 0;
}

@media (max-width: 700px) {
    .bview__title { font-size: .84rem; }
}

@media (prefers-reduced-motion: reduce) {
    .bview__panel { transition: opacity .01ms; }
}

/* =========================================================================
   How-it-works steps (home, dark section)
   Four numbered cards replacing the country grid — what a buyer needs to
   know before they enquire, rather than a list of export markets.
   ========================================================================= */
.steps {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1px;
    background: rgba(255, 255, 255, .12);
}

.step {
    position: relative;
    background: var(--ink);
    padding: clamp(1.6rem, 2.8vw, 2.25rem);
    transition: background .5s var(--ease-out);
}

.step:hover { background: #141416; }

.step__n {
    display: block;
    font-family: var(--font-mono);
    font-size: .68rem;
    letter-spacing: .2em;
    color: var(--red);
    margin-bottom: .9rem;
    transition: letter-spacing .5s var(--ease-out);
}

.step:hover .step__n { letter-spacing: .3em; }

.step__head {
    font-size: clamp(1.05rem, 1.6vw, 1.3rem);
    letter-spacing: -.02em;
    line-height: 1.3;
    color: #fff;
    margin-bottom: .65rem;
}

.step__body {
    font-size: .9rem;
    line-height: 1.65;
    color: rgba(255, 255, 255, .58);
    margin: 0;
}

@media (max-width: 700px) {
    .steps { grid-template-columns: 1fr; }
}

/* =========================================================================
   Monospace tuning
   The part-number and index labels now render in a true monospace face.
   JetBrains Mono sets wider than Inter at the same size, so the tracking
   that suited a proportional face is eased back and the weight lifted a
   little to keep these small labels crisp.
   ========================================================================= */
.mono,
.submenu__no,
.drawer__num,
.drawer__chip-no,
.pcard__index,
.market__code,
.step__n {
    font-feature-settings: 'tnum' 1, 'zero' 1;   /* tabular figures, slashed zero */
    letter-spacing: .08em;
}

/* The oversized ghost numeral on product mastheads reads as a drawing stamp;
   monospace suits it, but it needs no extra tracking at that size. */
.pdt-head__ghost { letter-spacing: 0; }
