/* ============================================================================
   Shield Infotech — shared site chrome styles
   Loaded on every page via partials/head.php. Contains ONLY the cross-page
   chrome: design tokens, reset, nav + mobile menu, footer, fade-up utility,
   grain overlay, and the floating widgets (sound toggle, page-wipe, custom
   cursor, WhatsApp button). Page-specific layout CSS stays inline per page.
   ========================================================================== */

:root {
    /* Dark UA widgets/scrollbars sitewide (Gallery already ships this) — without it,
       Windows shows a white page scrollbar against the near-black canvas. */
    color-scheme: dark;
    --bg: #020204; --text-main: #ffffff; --text-muted: #8892b0;
    --accent: #d8b4fe; --accent-dim: rgba(216, 180, 254, 0.15);
    --font-head: 'Syncopate', sans-serif;
    --font-body: 'Rajdhani', sans-serif;
    --font-num: 'Orbitron', sans-serif;
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}
* { margin: 0; padding: 0; box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; -webkit-tap-highlight-color: transparent; }
::selection { background: rgba(216,180,254,0.28); color: #fff; }

/* Touch-scroll fix: pages inline `overflow-x: hidden` on <html> AND <body>. On <body>
   that promotes it to a scroll container, so mobile momentum scroll STICKS on a
   down->up->down direction reversal (must lift finger to resume). `clip` kills the
   same horizontal overflow WITHOUT creating a scroll container. !important because the
   per-page inline <style> loads after site.css and would otherwise win. */
html { overflow-x: clip !important; }
body { overflow-x: clip !important; overscroll-behavior-y: none; }

/* --- Lenis smooth scroll (official CSS from the Lenis README) ---
   site.js starts Lenis on desktop only; these rules only bite once it adds the
   `lenis`/`lenis-smooth`/`lenis-stopped` classes to <html>, so mobile & no-JS are
   untouched. `scroll-behavior:auto` stops native smooth-scroll fighting Lenis;
   `lenis-stopped{overflow:hidden}` is what makes lenis.stop() actually lock the page
   (used when the mobile menu opens on a desktop-width window). */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* --- Nav --- */
nav { position: fixed; top: 0; left: 0; width: 100%; padding: 2rem 5vw; display: flex; justify-content: space-between; align-items: center; z-index: 1000; background: rgba(2,2,4,0.92); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); border-bottom: 1px solid rgba(255,255,255,0.05); }
/* Shield Infotech first-layer header: a compact transparent serpent-and-crystal-shield mark sits
   directly alongside the technical wordmark and blends into the near-black nav without changing
   the navigation flow, mobile menu behavior, or text contrast. */
.logo { font-family: var(--font-head); font-weight: 700; font-size: clamp(1.1rem, 2.1vw, 1.4rem); letter-spacing: 0.15em; display: flex; align-items: center; gap: 0.75rem; text-transform: uppercase; text-decoration: none; color: #fff; white-space: nowrap; }
/* First-render brand mark: kept in the shared CSS rather than added by JavaScript, so every page
   paints the user-supplied serpent-and-crystal-shield visual alongside Shield Infotech immediately. */
.logo::before { content:''; display:block; width:5.75rem; height:5.75rem; min-width:5.75rem; min-height:5.75rem; flex:0 0 5.75rem; background:url('shield-infotech-serpent-logo.png') center / contain no-repeat; filter:saturate(1.32) brightness(1.25) drop-shadow(0 0 0.9rem rgba(189,119,255,0.98)); transform:translateY(-1px); }
.header-logo-mark { display:none !important; }
.nav-links { display: none; }
.nav-right { display: flex; align-items: center; gap: 1.1rem; }
/* Dubai clock — shown in the nav on every page */
.nav-clock { font-family: var(--font-num, 'Rajdhani', 'Orbitron', monospace); font-size: 0.65rem; letter-spacing: 0.2em; color: rgba(255,255,255,0.4); white-space: nowrap; }
.nav-clock-label { color: rgba(255,255,255,0.25); margin-right: 0.4em; }
@media (max-width: 1024px) { .nav-clock { display: none; } }
.hamburger { display: flex; flex-direction: column; gap: 5px; background: none; border: none; cursor: pointer; padding: 4px; z-index: 201; }
.hamburger span { display: block; width: 24px; height: 1.5px; background: #fff; border-radius: 2px; transition: transform 0.4s var(--ease-out), opacity 0.3s; transform-origin: center; }
.hamburger.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.hamburger.open span:nth-child(2) { opacity: 0; transform: scaleX(0); }
.hamburger.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
body.menu-open { overflow: hidden; }
/* z-index 1100 sits ABOVE the fixed nav (1000) and the floating widgets (500) so the
   close button and menu content are visible/clickable and nothing floats over the menu. */
.mobile-menu { position: fixed; inset: 0; background: rgba(2,2,4,0.98); backdrop-filter: blur(30px); z-index: 1100; display: flex; flex-direction: column; justify-content: space-between; align-items: center; padding: 6rem 2rem 3rem; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity 0.5s var(--ease-out), visibility 0s linear 0.5s; overflow-y: hidden; }
.mobile-menu.open { opacity: 1; visibility: visible; pointer-events: all; overflow-y: auto; transition: opacity 0.5s var(--ease-out), visibility 0s linear 0s; }
.mobile-menu-brand { font-family: var(--font-head); font-weight: 700; font-size: 0.9rem; letter-spacing: 0.3em; text-transform: uppercase; color: var(--accent); opacity: 0.6; margin-bottom: 1rem; }
.mobile-menu-links { display: flex; flex-direction: column; align-items: center; gap: 0; flex: 1; justify-content: center; width: 100%; }
.mobile-menu .m-link { font-family: var(--font-head); font-size: clamp(1.4rem, 4vw, 3rem); font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: #fff; text-decoration: none; transition: color 0.3s, transform 0.3s; padding: 1rem 0; display: block; width: 100%; text-align: center; position: relative; opacity: 0; transform: translateY(20px); }
.mobile-menu.open .m-link { opacity: 1; transform: translateY(0); }
.mobile-menu.open .m-link:nth-child(1) { transition: opacity 0.5s 0.1s var(--ease-out), transform 0.5s 0.1s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(2) { transition: opacity 0.5s 0.15s var(--ease-out), transform 0.5s 0.15s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(3) { transition: opacity 0.5s 0.2s var(--ease-out), transform 0.5s 0.2s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(4) { transition: opacity 0.5s 0.25s var(--ease-out), transform 0.5s 0.25s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(5) { transition: opacity 0.5s 0.3s var(--ease-out), transform 0.5s 0.3s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(6) { transition: opacity 0.5s 0.35s var(--ease-out), transform 0.5s 0.35s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(7) { transition: opacity 0.5s 0.4s var(--ease-out), transform 0.5s 0.4s var(--ease-out), color 0.3s; }
.mobile-menu.open .m-link:nth-child(8) { transition: opacity 0.5s 0.45s var(--ease-out), transform 0.5s 0.45s var(--ease-out), color 0.3s; }
.mobile-menu .m-link::after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 40px; height: 1px; background: rgba(255,255,255,0.06); }
.mobile-menu .m-link:last-child::after { display: none; }
.mobile-menu .m-link:hover, .mobile-menu .m-link.active { color: var(--accent); }
.mobile-menu-footer { display: flex; flex-direction: column; align-items: center; gap: 1.5rem; padding-top: 2rem; opacity: 0; transform: translateY(15px); }
.mobile-menu.open .mobile-menu-footer { opacity: 1; transform: translateY(0); transition: opacity 0.5s 0.5s var(--ease-out), transform 0.5s 0.5s var(--ease-out); }
.mobile-menu-socials { display: flex; gap: 2rem; }
.mobile-menu-socials a { color: var(--text-muted); text-decoration: none; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; transition: color 0.3s; }
.mobile-menu-socials a:hover { color: #fff; }
.mobile-menu-whatsapp { display: flex; align-items: center; gap: 8px; color: #4ade80; font-family: var(--font-body); font-size: 0.8rem; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase; text-decoration: none; }
.mobile-menu-whatsapp::before { content: ''; display: block; width: 6px; height: 6px; background: #4ade80; border-radius: 50%; box-shadow: 0 0 8px #4ade80; }
.mobile-close { position: absolute; top: 2rem; right: 2rem; background: none; border: 1px solid rgba(255,255,255,0.15); color: #fff; width: 48px; height: 48px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 1.4rem; transition: border-color 0.3s, color 0.3s, transform 0.3s; z-index: 202; }
.mobile-close:hover { border-color: var(--accent); color: var(--accent); transform: rotate(90deg) scale(1.1); }

/* --- Fade Up Animation (shared reveal utility) --- */
.fade-up { opacity: 0; transform: translateY(40px); transition: opacity 1s var(--ease-out), transform 1s var(--ease-out); }
.fade-up.in-view { opacity: 1; transform: translateY(0); }

/* --- Magnetic button wrapper (shared) ---
   Pairs with the magnetic block in Assets/site.js, which sets `transform` inline on hover. No
   transition is declared here on purpose: the JS wants an untransitioned follow while the pointer
   moves, and applies its own easing only on release. contact.php carries a duplicate of this rule
   inline; index.html has its own copy and its own script. Wrap, do not apply to the button itself —
   the script moves the wrapper by 0.35 of the offset and the inner button by 0.15, and needs both. */
.magnetic { display: inline-block; position: relative; }

/* --- Grain overlay ---
   THIS RULE NEVER RECEIVED EITHER OF THE TWO FIXES index.html DOCUMENTS AT ITS OWN COPY, and it is
   the one every partial-based page actually uses — so the "visible square pixels" complaint stayed
   live on 11 pages while the two pages that were fixed looked fine. SETUP/visual-effects.md said
   "both pages", which was true and misleading: there are four copies of this rule.

   1. NO background-size AT ALL. The data URI has a viewBox but no width/height, so it has an
      intrinsic RATIO and no intrinsic SIZE — and per CSS Images 3, background-size:auto then
      resolves as `contain`. The 200-unit tile was being stretched to the full viewport height,
      roughly a 5x magnification that grew as the window got taller. That is the blockiness.
   2. NO feColorMatrix. feTurbulence generates R, G and B independently, so the noise was chromatic
      — visible colour fringing where film grain is monochrome luminance variation.

   The dppx ladder replaces index.html's two buckets (2dppx / 3dppx). Those missed every fractional
   Windows scaling factor — 1.25, 1.5, 1.75 — which fell back to the DPR-1 size and stayed coarse on
   exactly the laptops most likely to be in use. Pure CSS, so it also self-corrects on browser zoom
   and when a window moves to a differently-scaled monitor. */
.grain { position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none;
    z-index: 9998; opacity: 0.04; background-repeat: repeat; background-size: 340px 340px;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E"); }
@media (min-resolution: 1.25dppx) { .grain { background-size: 272px 272px; } }
@media (min-resolution: 1.5dppx) { .grain { background-size: 226.67px 226.67px; } }
@media (min-resolution: 1.75dppx) { .grain { background-size: 194.29px 194.29px; } }
@media (min-resolution: 2dppx) { .grain { background-size: 170px 170px; } }
@media (min-resolution: 2.5dppx) { .grain { background-size: 136px 136px; } }
@media (min-resolution: 3dppx) { .grain { background-size: 113.33px 113.33px; } }
@media (min-resolution: 4dppx) { .grain { background-size: 85px 85px; } }
@media (max-width: 1024px) { .grain { display: none; } }
/* Scroll performance: backdrop-filter re-samples every scroll frame — brutal on touch
   momentum scroll. Nav bg is already 92% opaque, so dropping the blur on mobile is
   near-invisible but removes the stutter. */
@media (max-width: 768px) {
    nav { background: rgba(2,2,4,0.96); backdrop-filter: none; -webkit-backdrop-filter: none; }
    .logo { font-size:0.98rem; gap:0.62rem; }
    .logo::before { width:3.8rem; height:3.8rem; min-width:3.8rem; min-height:3.8rem; flex-basis:3.8rem; }
}
/* The mix-blend custom cursor never moves on touch devices (JS gates it to desktop),
   but the two fixed blend layers still cost compositing on scroll — hide them. */
@media (hover: none), (pointer: coarse) {
    #si-cursor-dot, #si-cursor-ring, #si-cursor-glow { display: none !important; }
}

/* --- Rich Footer --- */
footer { padding: 5rem 6vw 3rem; border-top: 1px solid rgba(255,255,255,0.05); display: flex; flex-direction: column; gap: 3rem; position: relative; overflow: hidden; }
.footer-wm { position: absolute; bottom: -2rem; left: 0; width: 100%; text-align: center; font-family: var(--font-head); font-size: clamp(4rem, 9vw, 9rem); font-weight: 700; color: rgba(255,255,255,0.025); white-space: nowrap; pointer-events: none; letter-spacing: 0.1em; user-select: none; overflow: hidden; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 3rem; position: relative; z-index: 1; }
.footer-brand { display: flex; flex-direction: column; gap: 1.2rem; }
.footer-brand-name { font-family: var(--font-head); font-size: 1.5rem; font-weight: 700; letter-spacing: 0.1em; }
.footer-brand-desc { font-family: var(--font-body); font-size: 0.95rem; color: var(--text-muted); line-height: 1.7; font-weight: 500; max-width: 320px; }
.footer-col h4 { font-family: var(--font-head); font-size: 0.75rem; font-weight: 700; letter-spacing: 0.25em; text-transform: uppercase; color: var(--accent); margin-bottom: 1.5rem; }
.footer-col a { display: block; font-family: var(--font-body); font-size: 0.95rem; color: var(--text-muted); text-decoration: none; font-weight: 500; padding: 0.4rem 0; transition: color 0.3s, padding-left 0.3s; }
.footer-col a:hover { color: #fff; padding-left: 0.5rem; }
.footer-copy { font-size: 0.9rem; font-weight: 600; color: var(--text-muted); letter-spacing: 0.1em; text-transform: uppercase; }
.footer-top { display: flex; align-items: center; gap: 0.6rem; color: var(--text-muted); text-decoration: none; font-size: 0.85rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; transition: color 0.3s; }
.footer-top:hover { color: var(--accent); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid rgba(255,255,255,0.05); padding-top: 2rem; position: relative; z-index: 1; }
.footer-bottom-links { display: flex; gap: 2rem; }
.footer-bottom-links a { color: var(--text-muted); text-decoration: none; font-size: 0.8rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; transition: color 0.3s; }
.footer-bottom-links a:hover { color: #fff; }
.footer-whatsapp { display: inline-flex; align-items: center; gap: 8px; background: rgba(37,211,102,0.1); border: 1px solid rgba(37,211,102,0.2); color: #25d366; border-radius: 100px; padding: 0.6rem 1.4rem; font-family: var(--font-body); font-weight: 700; font-size: 0.78rem; letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none; transition: background 0.3s, border-color 0.3s; }
.footer-whatsapp:hover { background: rgba(37,211,102,0.2); border-color: rgba(37,211,102,0.4); }
@media (max-width: 1024px) {
    .footer-grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
    .footer-bottom { flex-direction: column; gap: 1.5rem; text-align: center; }
    .footer-bottom-links { flex-wrap: wrap; justify-content: center; }
    .footer-col { text-align: center; }
    .footer-col a:hover { padding-left: 0; }
    .footer-brand { align-items: center; text-align: center; }
    .footer-brand-desc { max-width: 100%; }
    .footer-wm { font-size: clamp(1.8rem, 11vw, 4rem); letter-spacing: 0.05em; }
    footer { overflow: visible; }
}
@media (max-width: 600px) { .footer-grid { grid-template-columns: 1fr; } }

/* --- Floating sound toggle --- */
#sound-toggle { position: fixed; bottom: calc(2.5rem + 54px + 0.75rem); right: 2.5rem; z-index: 500; background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.08); color: #fff; width: 54px; height: 54px; border-radius: 50%; display: flex; align-items: center; justify-content: center; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); transition: background 0.3s, border-color 0.3s; pointer-events: auto; flex-direction: column; gap: 4px; cursor: pointer; }
#sound-toggle:hover { background: rgba(216,180,254,0.15); border-color: var(--accent); }
#sound-toggle .sound-bars { display: flex; gap: 2px; align-items: flex-end; height: 14px; }
#sound-toggle .sound-bar { width: 2px; background: var(--accent); border-radius: 1px; }
#sound-toggle .sound-bar:nth-child(1) { height: 4px;  animation: si-sp 0.8s 0.00s ease-in-out infinite alternate; }
#sound-toggle .sound-bar:nth-child(2) { height: 10px; animation: si-sp 0.8s 0.15s ease-in-out infinite alternate; }
#sound-toggle .sound-bar:nth-child(3) { height: 7px;  animation: si-sp 0.8s 0.30s ease-in-out infinite alternate; }
#sound-toggle .sound-bar:nth-child(4) { height: 12px; animation: si-sp 0.8s 0.10s ease-in-out infinite alternate; }
#sound-toggle .sound-bar:nth-child(5) { height: 5px;  animation: si-sp 0.8s 0.25s ease-in-out infinite alternate; }
@keyframes si-sp { from { transform: scaleY(0.3); } to { transform: scaleY(1); } }
#sound-toggle.muted .sound-bar { animation: none; transform: scaleY(0.3); opacity: 0.25; }
#sound-toggle .sound-label { font-family: var(--font-num, 'Orbitron', sans-serif); font-size: 0.42rem; letter-spacing: 0.15em; color: var(--text-muted); }
@media (max-width: 1024px) { #sound-toggle { bottom: calc(1.5rem + 54px + 0.75rem + env(safe-area-inset-bottom, 0px)); right: 1.5rem; } }

/* --- Page transition wipe --- */
#si-page-wipe { position: fixed; inset: 0; background: #020204; z-index: 99998; transform: translateY(100%); pointer-events: none; transition: transform 0.7s cubic-bezier(0.7, 0, 0.2, 1); }
#si-page-wipe.cover { transform: translateY(0); }
#si-page-wipe.uncover { transform: translateY(-100%); }
#si-page-wipe::before { content: ''; position: absolute; inset: 0; background: radial-gradient(ellipse at center, rgba(216,180,254,0.08) 0%, transparent 60%); }
/* Full-width line box. `left:50%` would cap the shrink-to-fit width at half the
   viewport, wrapping the wordmark onto two left-aligned lines on a phone.
   text-indent cancels the trailing letter-space so the centred line is optically centred. */
#si-page-wipe::after { content: 'SHIELD INFOTECH'; --wipe-ls: clamp(0.16em, 1.1vw, 0.4em); position: absolute; top: 50%; left: 0; right: 0; transform: translateY(-50%); text-align: center; white-space: nowrap; font-family: var(--font-head, 'Syncopate', sans-serif); font-size: clamp(0.78rem, 3.4vw, 2rem); font-weight: 700; letter-spacing: var(--wipe-ls); text-indent: var(--wipe-ls); color: var(--accent); opacity: 0; transition: opacity 0.4s; }
#si-page-wipe.cover::after { opacity: 1; transition-delay: 0.3s; }

/* --- Reduced motion: honour the OS setting across the shared chrome --- */
@media (prefers-reduced-motion: reduce) {
    .fade-up { opacity: 1 !important; transform: none !important; transition: none !important; }
    #si-page-wipe { display: none !important; }
    #sound-toggle .sound-bar { animation: none !important; }
}

/* --- Custom cursor ---
   Gated on .si-cursor-ready, added by site.js only once the replacement cursor is running. Applied
   unconditionally this hid the system pointer for every visitor whose site.js failed to load or who
   is below the 1024px cursor threshold, leaving no visible pointer at all. */
html.si-cursor-ready, html.si-cursor-ready a, html.si-cursor-ready button,
html.si-cursor-ready input, html.si-cursor-ready textarea, html.si-cursor-ready * { cursor: none; }
#si-cursor-dot { position: fixed; top: 0; left: 0; width: 6px; height: 6px; background: #fff; border-radius: 50%; pointer-events: none; z-index: 10000; transform: translate(-50%, -50%); mix-blend-mode: difference; transition: opacity 0.3s; }
#si-cursor-ring { position: fixed; top: 0; left: 0; width: 40px; height: 40px; border: 1px solid rgba(216, 180, 254, 0.6); border-radius: 50%; pointer-events: none; z-index: 9999; transform-origin: center; will-change: transform; mix-blend-mode: difference; transition: border-color 0.3s, background 0.3s, width 0.2s, height 0.2s; }
body.si-hovering #si-cursor-ring { width: 65px; height: 65px; background: rgba(255,255,255,1); border-color: transparent; mix-blend-mode: exclusion; }
body.si-hovering #si-cursor-dot { opacity: 0; }
/* Soft trail-glow that follows the cursor while moving (matches the homepage). */
#si-cursor-glow { position: fixed; top: 0; left: 0; width: 80px; height: 80px; border-radius: 50%; background: radial-gradient(circle, rgba(216,180,254,0.15) 0%, transparent 70%); pointer-events: none; z-index: 9998; transform: translate(-50%, -50%); filter: blur(8px); opacity: 0; transition: opacity 0.3s; }
body:not(.si-hovering) #si-cursor-glow.active { opacity: 1; }
@media (max-width: 1024px) { #si-cursor-dot, #si-cursor-ring, #si-cursor-glow { display: none; } *, a, button, input, textarea { cursor: auto; } }

/* --- Floating WhatsApp button (sits above #sound-toggle) --- */
#wa-float { position: fixed; bottom: calc(2.5rem + 2 * (54px + 0.75rem)); right: 2.5rem; z-index: 500; width: 54px; height: 54px; border-radius: 50%; background: rgba(37,211,102,0.10); border: 1px solid rgba(37,211,102,0.35); color: #25d366; display: flex; align-items: center; justify-content: center; backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); text-decoration: none; transition: background 0.3s, border-color 0.3s, transform 0.3s; pointer-events: auto; }
#wa-float:hover { background: rgba(37,211,102,0.22); border-color: rgba(37,211,102,0.65); transform: scale(1.06); }
#wa-float svg { width: 26px; height: 26px; display: block; object-fit: contain; border-radius: 50%; }
#wa-float::after { content: ''; position: absolute; inset: -3px; border-radius: 50%; border: 1px solid rgba(37,211,102,0.4); animation: waPulse 2.4s ease-out infinite; pointer-events: none; }
@keyframes waPulse { 0% { transform: scale(0.95); opacity: 0.7; } 100% { transform: scale(1.45); opacity: 0; } }
@media (max-width: 1024px) { #wa-float { bottom: calc(1.5rem + 2 * (54px + 0.75rem) + env(safe-area-inset-bottom, 0px)); right: 1.5rem; } }

/* --- Floating package-builder button (sits above #wa-float, which sits above #sound-toggle) ---
   The stack is computed, not hardcoded: each button is 54px with a 0.75rem gap, so this one is two
   slots up. Change a size or gap and all three must move together.
   It is a PILL rather than a 54px circle on purpose — a third identical circle in the corner reads as
   clutter and says nothing, and this is the one float whose destination is not self-evident from an
   icon. The label collapses to the icon alone under 1024px, where three stacked circles would
   otherwise own a third of the screen edge. */
#si-calc-float { position: fixed; bottom: 2.5rem; right: 2.5rem; z-index: 500;
    height: 54px; display: inline-flex; align-items: center; gap: 0.6rem; padding: 0 1.15rem;
    border-radius: 100px; background: rgba(216,180,254,0.10); border: 1px solid var(--accent-dim);
    color: var(--accent); text-decoration: none; backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px); pointer-events: auto;
    font-family: var(--font-body); font-weight: 700; font-size: 0.72rem; letter-spacing: 0.12em;
    text-transform: uppercase; white-space: nowrap;
    transition: background 0.3s, border-color 0.3s, transform 0.3s, color 0.3s; }
#si-calc-float:hover { background: rgba(216,180,254,0.2); border-color: var(--accent); color: #fff; transform: scale(1.04); }
#si-calc-float:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
#si-calc-float svg { width: 20px; height: 20px; display: block; flex-shrink: 0; }
@media (max-width: 1024px) {
    #si-calc-float { bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
        right: 1.5rem; width: 54px; padding: 0; justify-content: center; gap: 0; }
    #si-calc-float .si-calc-label { display: none; }
}
@media (prefers-reduced-motion: reduce) { #si-calc-float:hover { transform: none; } }

@media (prefers-reduced-motion: reduce) { #wa-float::after { animation: none; } }

/* --- Keyboard focus (same accent ring the homepage ships) ---
   :focus-visible never fires on pointer clicks, so mouse/touch aesthetics are
   untouched. Inputs keep their own accent-border focus styles instead. */
*:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; }

/* ═══ Phone country selector (Assets/si-phone.js mountSelector) ═══════════════════════════════════
   Built to inherit the two field styles already on the site rather than look like a bolted-on
   widget: the underline `.input-group` fields on the homepage and /contact, and the bordered
   `.qform` fields on /start. Everything is driven by the existing design tokens, so a theme change
   carries through. It is a plain dropdown on purpose — see .si-cc-select below. */
.si-cc-wrap { display: flex; align-items: stretch; gap: 0.5rem; width: 100%; }
.si-cc-wrap > input[type=tel] { flex: 1 1 auto; min-width: 0; }

/* Pin the floating label up. mountSelector moves the <input> inside .si-cc-wrap, which breaks the
   `input:not(:placeholder-shown) ~ label` rule those fields rely on — the label stopped being the
   input's sibling, never floated, and sat on top of the country button (measured: 1862 px² of overlap
   on /contact). Two classes beat the page's own `.input-group label`, so this wins wherever it loads.
   index.html inlines its CSS and does not load this file — its copy lives in that page. */
.input-group.si-cc-host > label { transform: translateY(-30px); color: var(--accent); font-size: 0.75rem; }

.si-cc { position: relative; flex: 0 0 auto; }

/* Closed control: dial code and caret only. Narrow on purpose — the country name used to sit here and
   at "United Arab Emirates" width it took over the field. Full name is on the button's title. */
.si-cc-btn {
    display: inline-flex; align-items: center; gap: 0.45rem; height: 100%;
    background: transparent; border: none; border-bottom: 1px solid rgba(255,255,255,0.2);
    color: #fff; font-family: var(--font-body); font-size: 1rem; font-weight: 600;
    padding: 1rem 0.4rem 1rem 0; cursor: pointer; white-space: nowrap;
    transition: border-color 0.4s, color 0.25s;
}
.si-cc-btn:hover, .si-cc.open .si-cc-btn { border-bottom-color: var(--accent); color: var(--accent); }
.si-cc-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.si-cc-dial  { font-variant-numeric: tabular-nums; }
.si-cc-caret { flex: 0 0 auto; opacity: 0.6; transition: transform 0.3s var(--ease-out); }
.si-cc.open .si-cc-caret { transform: rotate(180deg); }

/* The .qform fields on /start are boxed, not underlined — match them there. */
.qform .si-cc-btn {
    border: 1px solid rgba(255,255,255,0.12); border-radius: 12px;
    background: rgba(255,255,255,0.03); padding: 1rem 0.9rem;
}
.qform .si-cc-btn:hover, .qform .si-cc.open .si-cc-btn { border-color: var(--accent); }

/* HEIGHT IS DEFINITE, not just capped. The panel once rendered as a search box with nothing under it:
   with only `max-height`, the list is a flex item whose `min-height: auto` resolves to 0 because it
   sets `overflow`, so it is free to collapse. A fixed height plus `flex: 1 1 auto` and a `min-height`
   on the list means the rows always have somewhere to be. Do not swap this back to max-height. */
/* max-height, not height: the panel sizes to however many rows are showing and only stops growing at
   the cap, so filtering to one match leaves a one-row panel rather than a mostly-empty box.
   This was a fixed height for a while as a guard against the panel rendering blank — that turned out
   to be the [hidden] override below, so the guard is no longer needed and the height can adapt. */
.si-cc-pop {
    position: absolute; z-index: 200; top: calc(100% + 6px); left: 0;
    width: 15rem; max-height: min(20rem, 60vh); display: flex; flex-direction: column;
    background: #0b0b11; border: 1px solid rgba(255,255,255,0.14); border-radius: 12px;
    box-shadow: 0 24px 60px rgba(0,0,0,0.65); overflow: hidden;
}
/* ONE RULE FOR THE WHOLE COMPONENT, AND IT IS LOAD-BEARING. Several elements here set `display`
   (.si-cc-pop: flex, .si-cc-opt: grid) and an author `display` declaration beats the browser's own
   `[hidden] { display: none }`. Without this, `el.hidden = true` sets the attribute and changes nothing
   on screen. That single mistake caused two separate reported bugs: the panel shipped permanently open,
   and then filtering silently stopped hiding rows so the list never shrank while typing. Scoping it to
   the whole subtree means anything added inside .si-cc inherits the fix instead of repeating it. */
.si-cc [hidden] { display: none; }
.si-cc-search {
    flex: 0 0 auto; width: 100%; box-sizing: border-box; background: rgba(255,255,255,0.05);
    border: none; border-bottom: 1px solid rgba(255,255,255,0.1); color: #fff;
    font-family: var(--font-body); font-size: 0.9rem; padding: 0.75rem 0.9rem;
}
.si-cc-search::placeholder { color: var(--text-muted); }
.si-cc-search:focus { outline: none; background: rgba(255,255,255,0.08); }

/* `flex: 0 1 auto` + `min-height: 0` is what lets the list be exactly as tall as its visible rows and
   still shrink-and-scroll once the panel hits its cap. `flex: 1 1 auto` would stretch it to fill the
   panel, and any min-height would floor it — either one puts the empty space back. */
.si-cc-list {
    flex: 0 1 auto; min-height: 0; overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
/* Rows are "AE +971" — two columns, nothing else. */
.si-cc-opt {
    display: grid; grid-template-columns: 2.4rem 1fr; align-items: center; gap: 0.6rem;
    padding: 0.55rem 0.9rem; cursor: pointer; font-size: 0.95rem; color: #fff;
}
.si-cc-opt:hover, .si-cc-opt:focus { background: rgba(216,180,254,0.12); }
.si-cc-opt[aria-selected="true"] { background: rgba(216,180,254,0.18); }
.si-cc-opt .si-cc-iso  { font-size: 0.8rem; letter-spacing: 0.06em; opacity: 0.65; }
.si-cc-opt .si-cc-dial { color: var(--accent); }
.si-cc-sep  { height: 1px; margin: 0.35rem 0.9rem; background: rgba(255,255,255,0.12); }
.si-cc-none { padding: 1rem 0.9rem; color: var(--text-muted); font-size: 0.9rem; }

@media (max-width: 520px) { .si-cc-pop { width: min(15rem, 82vw); } }
@media (prefers-reduced-motion: reduce) { .si-cc-caret { transition: none; } }
