/* ==========================================================================
   Akshari Gold Buyers — custom layer on top of the Tailwind design tokens
   Colours here are sampled from the production site capture.
   ========================================================================== */

/* Palette sampled from Akshari_Gold_Logo.png — crimson off the wordmark and
   diamond, gold off the laurel wreath and "GOLD BUYERS" lettering. */
:root {
    --brand-red: #8f191d;         /* primary crimson */
    --brand-red-deep: #6d1216;    /* pressed / solid dark */
    --brand-red-lit: #b42628;     /* lit diamond facet */
    --grad-from: #a4202a;
    --grad-to: #8f191d;
    --brand-gold: #ab782a;
    --brand-gold-lit: #ddaf2e;
    --brand-gold-deep: #8a6a22;
    --band-dark: #1c1618;
    --footer-dark: #171213;
    --section-tint: #f7f2ec;
}

html {
    scroll-behavior: smooth;
    scroll-padding-top: 96px;
}

body {
    font-family: "Hanken Grotesk", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* --- Display type --------------------------------------------------------
   Cormorant for headlines, echoing the serif in the Akshari wordmark. Body
   copy stays on Hanken Grotesk — a serif at 17px would cost legibility. */

h1, h2,
.display {
    font-family: "Cormorant", "Hanken Grotesk", Georgia, serif;
    letter-spacing: -0.005em;
}

/* Cormorant runs light at large sizes; lift the weight so headings still
   carry the same authority they did in the grotesk. */
h1 { font-weight: 700; }
h2 { font-weight: 600; }

/* --- Header wordmark ------------------------------------------------------
   Typeset lockup beside the emblem: crimson serif name over a letterspaced
   gold subtitle, matching the proportions in the logo artwork. */

.site-nav__name {
    font-family: "Cormorant", Georgia, serif;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: 0.1em;
    color: var(--brand-red);
    line-height: 1;
}

.site-nav__tag {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.34em;
    color: var(--brand-gold);
    margin-top: 4px;
}

nav.site-nav.is-condensed .site-nav__name { font-size: 26px; }
nav.site-nav.is-condensed .site-nav__tag  { font-size: 9px; }

.site-nav__name,
.site-nav__tag {
    transition: font-size 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* --- Material Symbols ---------------------------------------------------- */

.material-symbols-outlined {
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    font-display: block;
}

.icon-fill {
    font-variation-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
}

/* --- Buttons ------------------------------------------------------------- */

/* The site's primary CTA is a left-to-right red -> orange-red gradient. */
.btn-grad {
    background-image: linear-gradient(to right, var(--grad-from), var(--grad-to));
    transition: filter 200ms ease, transform 200ms ease;
}

.btn-grad:hover {
    filter: brightness(1.08);
}

/* --- Section eyebrow ----------------------------------------------------- */

/* "— OUR SERVICES —" style label. Centred variant gets a rule on both sides. */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.75rem;
    color: var(--brand-red);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

/* Dashes pick up the wreath gold; the label itself stays crimson, mirroring
   the two-colour split in the logo. */
.eyebrow::before,
.eyebrow--center::after {
    content: "";
    width: 28px;
    height: 2px;
    background: var(--brand-gold);
    flex: none;
}

/* --- Hero carousel ------------------------------------------------------- */

.hero-slides {
    position: absolute;
    inset: 0;
    z-index: 0;
}

/* --- Hero copy gutter ----------------------------------------------------
   The prev/next arrows are positioned against the *section* edge (left-4,
   lg:left-8) while this container is centred at max-w-[1720px]. So on any
   viewport narrower than 1720px + its own margins, the copy column starts at
   the same x as the arrow and the arrow lands on top of the headline.

   Reserve exactly the arrow's footprint and no more. Once the viewport is wide
   enough that the centred container already clears the arrow, the max() falls
   back to 1rem and nothing is over-indented. Arrow spans 16-70px below lg and
   32-86px from lg up; the constants are those right edges plus a gap.

   This owns padding-left AND padding-right instead of Tailwind's px-4, because
   the Play CDN injects its styles at runtime and may land after this file,
   which would make .px-4 win on source order. */
.hero-copy {
    padding-right: 1rem;
    padding-left: max(1rem, calc(84px - max(0px, (100vw - 1720px) / 2)));
}

@media (min-width: 1024px) {
    .hero-copy {
        padding-right: 2rem;
        padding-left: max(1rem, calc(110px - max(0px, (100vw - 1720px) / 2)));
    }
}

/* Headline and standfirst crossfade when the slide changes. Opacity only:
   these sit inside [data-entrance], which motion.js animates, and two systems
   writing the same transform is the bug that killed the hover lifts. The swap
   itself is driven from JS via inline opacity so it always outranks whatever
   Motion left behind. */
.hero-line {
    transition: opacity 200ms ease;
}

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

/* Cinematic video layer. Sits above the still slides but below the scrim, so
   if it is removed the slides show through unchanged. object-fit keeps it
   filling the hero at any aspect ratio without letterboxing. */
.hero-video {
    position: absolute;
    inset: 0;
    z-index: 1;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
}

.hero-slide {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    opacity: 0;
    transition: opacity 800ms ease-in-out;
}

.hero-slide.is-active {
    opacity: 1;
}

/* Slow drift keeps the three frames feeling like they scroll rather than cut. */
.hero-slide.is-active {
    animation: heroDrift 6s linear forwards;
}

@keyframes heroDrift {
    from { transform: scale(1.06) translateX(1.2%); }
    to   { transform: scale(1.12) translateX(-1.2%); }
}

.hero-arrow {
    display: grid;
    place-items: center;
    width: 54px;
    height: 54px;
    border: 1px solid rgba(255, 255, 255, 0.75);
    border-radius: 9999px;
    color: #fff;
    transition: background-color 200ms ease, border-color 200ms ease;
}

.hero-arrow:hover {
    background: rgba(221, 175, 46, 0.22);
    border-color: var(--brand-gold-lit);
}

/* --- Wave divider under the stats band ----------------------------------- */

.wave-divider {
    display: block;
    width: 100%;
    height: 90px;
}

/* --- Service cards (dark section) ---------------------------------------- */

.svc-card__media {
    position: relative;
    overflow: hidden;
}

.svc-card__media img {
    transition: transform 600ms cubic-bezier(0.22, 1, 0.36, 1);
}

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

/* --- Service card hover: "Get Details" ----------------------------------- */

/* Scrim + button share one hover state so they move together. Both animate
   opacity/transform only, so nothing here triggers layout. */
.svc-card__overlay {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    background: rgba(10, 5, 3, 0.55);
    opacity: 0;
    transition: opacity 400ms cubic-bezier(0.22, 1, 0.36, 1);
}

.svc-card:hover .svc-card__overlay,
.svc-card:focus-within .svc-card__overlay {
    opacity: 1;
}

.svc-card__cta {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.85rem 1.9rem;
    background-image: linear-gradient(to right, var(--grad-from), var(--grad-to));
    color: #fff;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
    transform: translateY(14px) scale(0.96);
    opacity: 0;
    transition: transform 450ms cubic-bezier(0.22, 1, 0.36, 1),
                opacity 450ms cubic-bezier(0.22, 1, 0.36, 1),
                filter 200ms ease;
}

.svc-card:hover .svc-card__cta,
.svc-card:focus-within .svc-card__cta {
    transform: none;
    opacity: 1;
}

.svc-card__cta:hover {
    filter: brightness(1.1);
}

/* The badge would sit on top of the scrim; fade it out as the CTA arrives. */
.svc-card:hover .svc-badge,
.svc-card:focus-within .svc-badge {
    opacity: 0;
}

/* Red badge with a check, bottom-right of each service image. */
.svc-badge {
    transition: opacity 300ms ease;
}

.svc-badge {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 72px;
    height: 72px;
    display: grid;
    place-items: center;
    background: var(--brand-red);
    color: #fff;
}

/* Underline that runs red for the first fifth, then pale. */
.svc-rule {
    height: 2px;
    background: linear-gradient(to right,
        var(--brand-gold-lit) 0 18%,
        rgba(255, 255, 255, 0.28) 18% 100%);
}

/* --- Quote section: gold ---------------------------------------------------
   Reworked from the flat crimson band into the logo's gold. A deep near-black
   ground lets the metallic gradient read as metal rather than as mustard —
   flat gold on white looks cheap, which is the one thing a gold buyer cannot
   afford. Crimson is kept for the submit button so the brand's second colour
   still anchors the primary action. */

.quote-gold {
    position: relative;
    isolation: isolate;
    background:
        radial-gradient(120% 140% at 8% 0%, rgba(221, 175, 46, 0.22) 0%, rgba(221, 175, 46, 0) 55%),
        linear-gradient(135deg, #191313 0%, #241a12 45%, #14100f 100%);
    overflow: hidden;
}

/* Fine gold hairline top and bottom, like the rules in the logo lockup. */
.quote-gold::before,
.quote-gold::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 1px;
    background: linear-gradient(to right,
        rgba(221, 175, 46, 0) 0%,
        rgba(221, 175, 46, 0.85) 20%,
        rgba(221, 175, 46, 0.85) 80%,
        rgba(221, 175, 46, 0) 100%);
    z-index: 2;
}

.quote-gold::before { top: 0; }
.quote-gold::after  { bottom: 0; }

/* Slow metallic sheen travelling across the panel. Transform only. */
.quote-gold__sheen {
    position: absolute;
    inset: -40% -60%;
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(105deg,
        rgba(255, 255, 255, 0) 42%,
        rgba(255, 240, 200, 0.10) 50%,
        rgba(255, 255, 255, 0) 58%);
    animation: quoteSheen 9s linear infinite;
}

@keyframes quoteSheen {
    from { transform: translateX(-38%); }
    to   { transform: translateX(38%); }
}

.quote-gold__title {
    background-image: linear-gradient(100deg, #f3d98a 0%, #ddaf2e 45%, #b8862a 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.quote-gold__rule {
    height: 2px;
    width: 96px;
    background: linear-gradient(to right, var(--brand-gold-lit), rgba(221, 175, 46, 0));
}

/* Inputs read as engraved rather than pasted on. */
.quote-gold__field {
    width: 100%;
    padding: 14px 18px;
    color: #fdfbf7;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(221, 175, 46, 0.34);
    border-radius: 3px;
    transition: border-color 220ms ease, background-color 220ms ease, box-shadow 220ms ease;
}

.quote-gold__field::placeholder { color: rgba(253, 251, 247, 0.55); }

.quote-gold__field:hover { border-color: rgba(221, 175, 46, 0.6); }

.quote-gold__field:focus {
    outline: none;
    background: rgba(255, 255, 255, 0.09);
    border-color: var(--brand-gold-lit);
    box-shadow: 0 0 0 3px rgba(221, 175, 46, 0.16);
}

.quote-gold__submit {
    background-image: linear-gradient(to right, var(--grad-from), var(--grad-to));
    border: 1px solid rgba(221, 175, 46, 0.5);
    color: #fff;
    transition: filter 220ms ease, box-shadow 220ms ease, transform 220ms ease;
}

.quote-gold__submit:hover {
    filter: brightness(1.1);
    box-shadow: 0 10px 26px rgba(221, 175, 46, 0.22);
}

.quote-gold__submit:active { transform: translateY(1px); }

.quote-gold__submit[disabled] { opacity: 0.75; cursor: progress; }

/* --- Celebration ----------------------------------------------------------
   Fired once a quote is actually submitted. Fixed-position, pointer-events
   none, and torn down afterwards so nothing lingers in the DOM. */

.celebrate-layer {
    position: fixed;
    inset: 0;
    z-index: 90;
    pointer-events: none;
    overflow: hidden;
}

.celebrate-piece {
    position: absolute;
    top: -24px;
    width: 9px;
    height: 14px;
    border-radius: 1px;
    will-change: transform, opacity;
}

.celebrate-toast {
    position: fixed;
    left: 50%;
    bottom: 40px;
    z-index: 95;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 16px 26px;
    border-radius: 999px;
    color: #fdfbf7;
    background: linear-gradient(135deg, #191313, #241a12);
    border: 1px solid rgba(221, 175, 46, 0.55);
    box-shadow: 0 18px 44px rgba(10, 5, 3, 0.42);
    font-weight: 600;
    white-space: nowrap;
    max-width: calc(100vw - 32px);
}

.celebrate-toast .material-symbols-outlined { color: var(--brand-gold-lit); }

/* --- OSTech Apps credit ---------------------------------------------------
   Footer builder credit. Deliberately quiet: a hairline pill that only picks
   up OSTech's own magenta/violet on hover, so it reads as an attribution and
   never competes with Akshari's crimson-and-gold. Both the wordmark and the
   icon point at the same Instagram profile, which keeps the effective tap
   target well past 44px even though the icon disc itself is 40px. */

.ostech-credit {
    display: inline-flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.5rem 0.5rem 0.5rem 1.1rem;
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.04);
    transition: border-color 0.28s ease, background-color 0.28s ease;
}

.ostech-credit:hover {
    border-color: rgba(195, 76, 156, 0.6);
    background: rgba(195, 76, 156, 0.1);
}

.ostech-credit__label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.5);
    white-space: nowrap;
}

.ostech-credit__brand {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 15px;
    font-weight: 700;
    color: #ffffff;
    white-space: nowrap;
    transition: color 0.28s ease;
}

.ostech-credit__brand:hover { color: #e79ccd; }

.ostech-credit__logo {
    height: 26px;
    width: auto;
    display: block;
    border-radius: 5px;
}

.ostech-credit__ig {
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    color: #ffffff;
    background: linear-gradient(135deg, #3b0773, #c34c9c);
    box-shadow: 0 4px 14px rgba(195, 76, 156, 0.28);
    transition: box-shadow 0.28s ease, filter 0.28s ease;
}

.ostech-credit__ig:hover {
    filter: brightness(1.12);
    box-shadow: 0 6px 20px rgba(195, 76, 156, 0.45);
}

@media (max-width: 380px) {
    .ostech-credit { gap: 0.6rem; padding-left: 0.8rem; }
    .ostech-credit__label { display: none; }
}

/* --- Hero + caption scrims ------------------------------------------------
   Written as real CSS, NOT Tailwind gradient utilities. The Play CDN does not
   emit anything for gradient colour-stops that carry an opacity modifier
   (`from-black/88`, `via-black/85` …) — `background-image` silently resolves
   to `none`. That went unnoticed for a long time because the hero photography
   used to be dark enough not to need the scrim. Plain-colour stops such as
   `from-section-mist to-[#eff0f6]` do work, so those are still utilities. */

/* All three are decorative overlays stretched across their parent with
   `inset-0`. They must never intercept a click: they sit above the photograph
   but below the copy, and without this a scrim swallows any button, link or
   input that happens to fall inside its box. */
.hero-scrim,
.figure-scrim,
.banner-gradient {
    pointer-events: none;
}

.hero-scrim {
    background-image: linear-gradient(to right,
        rgba(0, 0, 0, 0.88) 0%,
        rgba(0, 0, 0, 0.68) 45%,
        rgba(0, 0, 0, 0.40) 100%);
}

/* Caption bar over the "What We Buy" figures. */
.figure-scrim {
    background-image: linear-gradient(to top,
        rgba(0, 0, 0, 0.92) 0%,
        rgba(0, 0, 0, 0.72) 45%,
        rgba(0, 0, 0, 0) 100%);
}

/* --- Inner-page banner --------------------------------------------------- */

/* Dark scrim behind the page-title banners on about/services/blogs/etc.
   Without it the white heading sits on a light photo and is unreadable. */
.banner-gradient {
    background: linear-gradient(to right, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0.62) 100%);
}

/* --- Inner-page service cards -------------------------------------------- */

.service-card {
    transition: border-color 200ms ease, transform 300ms cubic-bezier(0.22, 1, 0.36, 1),
                box-shadow 300ms ease;
}

.service-card:hover {
    border-color: var(--brand-red);
    transform: translateY(-4px);
    box-shadow: 0 12px 28px rgba(26, 26, 26, 0.10);
}

.service-card__media {
    overflow: hidden;
}

.service-card__media img {
    transition: transform 500ms cubic-bezier(0.22, 1, 0.36, 1);
}

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

/* Three of the service images are the client's own posters, with their wording
   set right up to the edge of the raster. Any crop eats the words, so they sit
   at their native 16:10 in the card and are held out of the hover zoom — a 6%
   scale would clip the text back off. The overlay CTA still carries the hover,
   so nothing is lost. Photographs keep the zoom; only posters opt out. */
.svc-card:hover .svc-card__media img.is-poster,
.service-card:hover .service-card__media img.is-poster {
    transform: none;
}

/* --- Decorative glow -----------------------------------------------------
   Stands in for a `blur-3xl` circle. A large blur radius makes the compositor
   re-run an expensive filter pass every frame; a radial gradient rasterises
   once and gives the same falloff. */

.glow {
    background-image: radial-gradient(circle closest-side,
        rgba(180, 38, 40, 0.32),
        rgba(180, 38, 40, 0.16) 55%,
        rgba(180, 38, 40, 0) 100%);
    pointer-events: none;
}

/* --- KYC card hover: image reveal + highlight ----------------------------
   The photo is a real <img> child rather than a background on ::before. A
   relative url() inside a custom property resolves against the *stylesheet*
   (/assets/css/), not the document, which silently 404s. An <img src> resolves
   against the document and lazy-loads for free. */

.kyc-card {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    border: 1px solid transparent;
    transition: border-color 300ms ease, transform 400ms cubic-bezier(0.22, 1, 0.36, 1),
                box-shadow 400ms ease;
}

.kyc-card__media {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transform: scale(1.06);
    pointer-events: none;
    transition: opacity 500ms cubic-bezier(0.22, 1, 0.36, 1),
                transform 700ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Scrim between photo and text, so the copy stays legible over any image. */
.kyc-card__scrim {
    position: absolute;
    inset: 0;
    z-index: 1;
    background: linear-gradient(to top, rgba(10, 5, 3, 0.9), rgba(10, 5, 3, 0.7));
    opacity: 0;
    pointer-events: none;
    transition: opacity 500ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Card content must sit above both layers. */
.kyc-card > *:not(.kyc-card__media):not(.kyc-card__scrim) {
    position: relative;
    z-index: 2;
}

.kyc-card:hover,
.kyc-card:focus-within {
    border-color: var(--brand-red);
    transform: translateY(-6px);
    box-shadow: 0 18px 38px rgba(10, 5, 3, 0.28);
}

.kyc-card:hover .kyc-card__media,
.kyc-card:focus-within .kyc-card__media {
    opacity: 1;
    transform: scale(1);
}

.kyc-card:hover .kyc-card__scrim,
.kyc-card:focus-within .kyc-card__scrim {
    opacity: 1;
}

/* Text flips to white once the photo is behind it. */
.kyc-card__eyebrow,
.kyc-card__title,
.kyc-card__icon,
.kyc-card__link {
    transition: color 400ms ease, opacity 400ms ease;
}

.kyc-card:hover .kyc-card__eyebrow,
.kyc-card:focus-within .kyc-card__eyebrow {
    color: #ffb3bf;
}

.kyc-card:hover .kyc-card__title,
.kyc-card:focus-within .kyc-card__title {
    color: #ffffff;
}

.kyc-card:hover .kyc-card__link,
.kyc-card:focus-within .kyc-card__link {
    color: #ffffff;
}

.kyc-card:hover .kyc-card__icon,
.kyc-card:focus-within .kyc-card__icon {
    color: #ffffff;
    opacity: 0.9;
}

/* --- Cards --------------------------------------------------------------- */

.lift {
    transition: transform 300ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 300ms ease;
}

.lift:hover {
    transform: translateY(-4px);
    box-shadow: 0 14px 30px rgba(26, 26, 26, 0.12);
}

/* --- FAQ accordion ------------------------------------------------------- */

.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

.faq-item.is-open .faq-answer {
    max-height: 340px;
}

/* The marker is a "+" that becomes a "−" when open. */
.faq-sign::before { content: "+"; }
.faq-item.is-open .faq-sign::before { content: "\2212"; }

/* --- Offcanvas menu ------------------------------------------------------ */

#offcanvas {
    transform: translateX(100%);
    transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
}

#offcanvas.is-open {
    transform: none;
}

/* `visibility` is stepped, never given a duration. This element covers the
   whole viewport and accepts pointer events, so if a transition on visibility
   ever stalls mid-flight it becomes an invisible sheet over the entire page
   and nothing on the site can be clicked or typed into. Step it: hold
   `visible` for the length of the fade when closing, flip instantly when
   opening. */
#offcanvas-backdrop {
    opacity: 0;
    visibility: hidden;
    transition: opacity 320ms ease, visibility 0s 320ms;
}

#offcanvas-backdrop.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 320ms ease, visibility 0s 0s;
}

/* --- Floating rails ------------------------------------------------------ */

.rail-btn {
    position: relative;
    width: 54px;
    height: 54px;
    display: grid;
    place-items: center;
    border-radius: 9999px;
    color: #fff;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.22);
    transition: transform 200ms ease, filter 200ms ease;
}

.rail-btn:hover {
    transform: translateY(-2px);
    filter: brightness(1.05);
}

/* Label that slides out of the button on hover or keyboard focus.
   The text lives in `data-rail-label` rather than in the DOM so it cannot be
   read twice by a screen reader — the anchor's aria-label already names the
   action, and this pseudo-element is hidden from the accessibility tree. */
.rail-btn::after {
    content: attr(data-rail-label);
    position: absolute;
    left: calc(100% + 12px);
    top: 50%;
    padding: 8px 14px;
    border-radius: 8px;
    background: var(--footer-dark, #171213);
    color: #fdfbf7;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    box-shadow: 0 8px 22px rgba(10, 5, 3, 0.3);
    opacity: 0;
    transform: translate(-8px, -50%);
    transition: opacity 220ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

/* Little arrow joining the label to the button. */
.rail-btn::before {
    content: "";
    position: absolute;
    left: calc(100% + 6px);
    top: 50%;
    width: 0;
    height: 0;
    border: 6px solid transparent;
    border-right-color: var(--footer-dark, #171213);
    opacity: 0;
    transform: translate(-8px, -50%);
    transition: opacity 220ms ease, transform 220ms cubic-bezier(0.22, 1, 0.36, 1);
    pointer-events: none;
}

.rail-btn:hover::after,
.rail-btn:focus-visible::after,
.rail-btn:hover::before,
.rail-btn:focus-visible::before {
    opacity: 1;
    transform: translate(0, -50%);
}

/* Narrow screens have no room for a label beside a left-docked button. */
@media (max-width: 560px) {
    .rail-btn::after,
    .rail-btn::before { display: none; }
}

/* "Go To Top" reads vertically up the right edge, as on the live site. */
.go-top {
    writing-mode: vertical-rl;
    letter-spacing: 0.12em;
    opacity: 0;
    pointer-events: none;
    transition: opacity 250ms ease;
}

.go-top.is-visible {
    opacity: 1;
    pointer-events: auto;
}


/* --- Scroll reveal ------------------------------------------------------- */

/* `.reveal` is now only a selector hook — assets/js/motion.js sets the "from"
   state in JS and animates it. Deliberately NO hidden state here: if the Motion
   CDN is blocked or JS is off, content must never be stranded at opacity 0.
   (The previous CSS-driven version had exactly that failure mode.) */
.reveal {
    /* intentionally empty */
}

/* --- Language switcher ---------------------------------------------------- */

/* The top contact bar must out-rank the sticky nav (z-50), and it must say so
   itself. Its entrance animation applies a transform, and a transform creates
   a stacking context — so the dropdown's own z-index below only ever competes
   inside this bar. Without this the open menu paints beneath the nav and the
   hero, and every click on a language lands on the page behind it. That is
   what "the language switch does nothing" looked like.
   motion.js also clears the transform once the entrance finishes; this rule is
   the half that does not depend on JS having run. */
[data-entrance-bar] {
    position: relative;
    z-index: 60;
}

.lang-switch__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 8px);
    z-index: 5;
    min-width: 168px;
    padding: 6px;
    background: #fff;
    color: var(--footer-dark);
    border-radius: 6px;
    box-shadow: 0 14px 34px rgba(10, 5, 3, 0.24);
}

.lang-switch__item {
    display: block;
    width: 100%;
    padding: 9px 12px;
    text-align: left;
    font-size: 15px;
    border-radius: 4px;
    transition: background-color 160ms ease, color 160ms ease;
}

.lang-switch__item:hover,
.lang-switch__item[aria-selected="true"] {
    background: var(--section-tint);
    color: var(--brand-red);
    font-weight: 700;
}

/* Indic scripts have taller ascenders/descenders than Latin; give the whole
   page a little more line height so translated copy does not feel cramped. */
.lang-indic body,
.lang-indic {
    line-height: 1.75;
}

.lang-indic h1,
.lang-indic h2,
.lang-indic h3 {
    line-height: 1.35;
}

/* --- Nav condense on scroll ---------------------------------------------- */

nav.site-nav {
    transition: padding 260ms cubic-bezier(0.22, 1, 0.36, 1),
                box-shadow 260ms ease;
}

nav.site-nav .site-nav__logo {
    transition: height 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

nav.site-nav.is-condensed {
    box-shadow: 0 6px 24px rgba(10, 5, 3, 0.10);
}

nav.site-nav.is-condensed .site-nav__inner {
    padding-top: 6px;
    padding-bottom: 6px;
}

/* The Akshari mark is portrait, so it cannot shrink as far as the old 5:1
   lockup did before the wordmark stops reading. */
nav.site-nav.is-condensed .site-nav__logo {
    height: 52px;
}

/* --- Focus visibility ---------------------------------------------------- */

a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 2px solid var(--brand-red);
    outline-offset: 2px;
}

.on-dark a:focus-visible,
.on-dark button:focus-visible {
    outline-color: #ffffff;
}

/* --- Photographs: presence and hover --------------------------------------
   `.photo` is added by main.js to every image under sections/ and services/,
   never to brand marks — the logo must not be tinted or zoomed. `.photo-frame`
   goes on its parent and does the clipping, so the zoom has something to crop
   against.

   The base filter is a small lift, not a look: the stock photography is evenly
   lit and reads flat against the ivory bands. Anything stronger starts
   misrepresenting the colour of the metal, which on a gold buyer's site is the
   one thing that must stay honest. */

.photo-frame {
    overflow: hidden;
    position: relative;
}

.photo {
    filter: saturate(1.06) contrast(1.04);
    transition: transform 620ms cubic-bezier(0.22, 1, 0.36, 1),
                filter 320ms ease;
}

/* Hover on the frame, the card or a wrapping link all count — the pointer is
   rarely over the image itself when a card is the target. */
.photo-frame:hover .photo,
.service-card:hover .photo,
.kyc-card:hover .photo,
a:hover > .photo,
a:hover .photo-frame .photo {
    transform: scale(1.065);
    filter: saturate(1.14) contrast(1.07) brightness(1.06);
}

/* Decorative images are positioned, not in flow; scaling them shifts artwork
   around rather than filling a frame. */
.photo[aria-hidden="true"] { transform: none !important; }

@media (prefers-reduced-motion: reduce) {
    .photo { transition: filter 320ms ease; }
    .photo-frame:hover .photo,
    .service-card:hover .photo,
    .kyc-card:hover .photo,
    a:hover > .photo,
    a:hover .photo-frame .photo { transform: none; }
}

/* --- Section entry rule ---------------------------------------------------
   A gold hairline that draws itself left-to-right as a section crosses the
   viewport — the per-section cue that replaces the clip-path heading wipe.
   Injected by motion.js and purely decorative, so a JS-less page simply never
   has one rather than showing an undrawn bar. */

.section-rule {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 2px;
    transform: scaleX(0);
    transform-origin: 0 50%;
    background: linear-gradient(90deg,
        rgba(221, 175, 46, 0) 0%,
        var(--brand-gold-lit, #ddaf2e) 18%,
        var(--brand-gold, #ab782a) 55%,
        rgba(221, 175, 46, 0) 100%);
    pointer-events: none;
    z-index: 3;
}

/* --- Scroll progress -----------------------------------------------------
   Reading position, drawn as a gold rule across the very top. Injected by
   motion.js and driven off the scroll timeline, so it exists only when the
   animation layer actually loaded — no empty bar on a JS-less page. */

.scroll-progress {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    z-index: 100;
    transform: scaleX(0);
    transform-origin: 0 50%;
    background: linear-gradient(90deg, var(--brand-gold-deep), var(--brand-gold-lit), var(--brand-gold));
    pointer-events: none;
}

/* --- Reduced motion ------------------------------------------------------ */

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

    /* motion.js does not run at all under reduced motion, so the bar is never
       injected. Belt and braces in case it is ever added in markup. */
    .scroll-progress { display: none; }

    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        /* Also clear delays, or the quote panel's stepped `visibility 0s 400ms`
           would still wait 400ms before hiding. */
        transition-delay: 0s !important;
        animation-delay: 0s !important;
    }

    .hero-slide.is-active { animation: none; transform: scale(1.04); }
}
