/* Animation for float effect */
@keyframes pulse {
    0% {
        transform: translateY(0px);
    }

    50% {
        transform: translateY(-5px);
    }

    100% {
        transform: translateY(0px);
    }
}

/* Global Styles
 *
 * The design tokens live in header.css, which is the only stylesheet every
 * page loads - this file reaches just four pages, so a token declared only
 * here would never reach the rest of the site. The copy below is kept because
 * it is identical to the one in header.css and harmless; keep the two in step,
 * and add anything new to header.css.
 */
:root {
    --primary-color: #154360;
    --primary-dark: #0f3247;
    /* Brand orange, kept for accents, rules and icons where it sits on a light
       surface. White text on it is only 2.85:1, so it must not be used as a
       button fill with white text - see --secondary-cta. */
    --secondary-color: #e67e22;
    /* Darkened until white text clears 4.5:1 (measured 4.58:1). This is the
       fill for solid calls to action. */
    --secondary-cta: #b45f14;
    --secondary-cta-dark: #964f10;
    --dark-color: #2c3e50;
    --light-color: #f4f6f7;
    --text-color: #333;
    --text-muted: #5b6770;
    --grey-color: #6c6d72;
    --border-color: #e3e8ea;

    /* One type stack for everything. The old rule set 'Segoe UI' on * , which
       only Windows has - so headings and body text resolved to two different
       typefaces on macOS, iOS and Android. */
    --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
        Arial, "Noto Sans", sans-serif;

    /* Fluid modular scale, ~1.25 ratio. Replaces the ad-hoc 54.4/32/20px. */
    --step-0: clamp(1rem, 0.96rem + 0.20vw, 1.125rem);
    --step-1: clamp(1.25rem, 1.18rem + 0.35vw, 1.5rem);
    --step-2: clamp(1.5rem, 1.36rem + 0.70vw, 2rem);
    --step-3: clamp(1.875rem, 1.63rem + 1.20vw, 2.75rem);
    --step-4: clamp(2.25rem, 1.80rem + 2.25vw, 3.5rem);

    /* Vertical rhythm. Sections previously alternated 48px and 80px padding
       with no rule behind which got which. */
    --section-y: clamp(3rem, 2rem + 4vw, 5rem);
    --space-xs: 0.5rem;
    --space-sm: 1rem;
    --space-md: 1.5rem;
    --space-lg: 2rem;
    --space-xl: 3rem;

    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;

    --shadow-sm: 0 1px 2px rgba(16, 32, 44, 0.06), 0 2px 8px rgba(16, 32, 44, 0.06);
    --shadow-md: 0 4px 12px rgba(16, 32, 44, 0.10);
    --shadow-lg: 0 12px 32px rgba(16, 32, 44, 0.14);

    --transition: 0.25s ease;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.6;
    color: var(--text-color);
    -webkit-font-smoothing: antialiased;
}

/* Headings inherit the body stack. Weights are monotonic: an h3 must never be
   heavier than the h2 above it, which is what the old 500/700 pairing did. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-sans);
    line-height: 1.2;
    color: var(--heading-color);
    text-wrap: balance;
}

h1 { font-size: var(--step-4); font-weight: 700; letter-spacing: -0.02em; }
h2 { font-size: var(--step-3); font-weight: 700; letter-spacing: -0.01em; }
h3 { font-size: var(--step-2); font-weight: 600; }
h4 { font-size: var(--step-1); font-weight: 600; }

p { max-width: 68ch; }

/* Keyboard focus was invisible everywhere; this is the only visible focus
   affordance on the site. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
    outline: 3px solid var(--secondary-color);
    outline-offset: 2px;
    border-radius: 2px;
}

body a {
    color: var(--primary-color);
}

/* Links carry an underline again. Colour alone could not do the job: the link
   navy against body text measures 1.21:1, well under the 3:1 WCAG 1.4.1 asks
   for before colour is the only thing distinguishing a link. That left 2,135
   in-sentence links and 25,000 table links looking exactly like plain text. */
p a,
li a,
td a,
dd a,
figcaption a,
.ss-content a {
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 0.07em;
}

p a:hover,
li a:hover,
td a:hover,
dd a:hover,
figcaption a:hover,
.ss-content a:hover {
  text-decoration-thickness: 0.14em;
  color: var(--secondary-cta);
}

/* Chrome that already reads as interactive from shape or position: a button, a
   nav item, a breadcrumb, a sidebar list of sibling products, a search result,
   the footer columns. Underlining these adds noise, not information. Listed
   after the block above so equal-specificity selectors like `footer a` win. */
.btn,
.navbar a,
.nav-link,
.dropdown-item,
.breadcrumb a,
.link-list a,
.site-search__results a,
.card a,
.pagination a,
.contact-item,
.social-links a,
footer a,
footer li a,
footer p a {
  text-decoration: none;
}


ul {
    list-style: none;
}

img {
    width: 100%;
    height: auto;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
}

/* One definition each. .btn and .btn-primary were previously declared three
   times across this file with conflicting backgrounds and hover colours, so
   which one applied depended on source order. */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* 44px floor: 37 of the 154 tap targets on the homepage were under the
       44px minimum on a 375px viewport. */
    min-height: 44px;
    background: var(--secondary-cta);
    color: #fff;
    padding: 0.75rem 1.75rem;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: 600;
    font-size: 1rem;
    line-height: 1.2;
    text-align: center;
    transition: background-color var(--transition), transform var(--transition),
        box-shadow var(--transition);
}

.btn:hover {
    background: var(--secondary-cta-dark);
    color: #fff;
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}

.btn-primary {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: #fff;
}

.btn-primary:hover {
    /* Was orange-on-navy, which sits at roughly 3.5:1 and fails AA for body
       text. Darkening the navy and keeping white text stays well above 4.5:1. */
    background: var(--primary-dark);
    border-color: var(--primary-dark);
    color: #fff;
}

/* Features Section */
.features {
    padding: var(--section-y) 0;
    background: var(--light-color);
}

.section-title-h1,
.section-title-h2 {
    text-align: center;
    margin-bottom: var(--space-xl);
    padding-bottom: var(--space-md);
    position: relative;
}

.section-title-h1:after,
.section-title-h2:after {
    content: '';
    position: absolute;
    width: 56px;
    height: 3px;
    background: var(--secondary-color);
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
}

/* Centred intro copy is the one place the 68ch measure must not left-align it. */
.section-title-h1 > p,
.section-title-h2 > p {
    max-width: 60ch;
    margin-inline: auto;
    color: var(--text-muted);
}

/* .section-title-h2 sits in .products-preview. That section used to run a
   #ccc-#888 grey gradient with near-white heading text, which measures 3.27:1
   at the dark end - below AA. Navy on that same gradient is no better (2.96:1),
   so the background itself is the problem; .products-preview is now a light
   surface, where navy measures 9.24:1. */
.section-title-h2,
.section-title-h2 h2 {
    color: var(--primary-color);
}

.section-title-h2 > p {
    color: var(--dark-color);
}

.features-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 30px;
}

/* The reveal used to start at opacity:0 and wait for script.js to add
   .visible. That makes four cards of homepage copy invisible until a script
   runs and an IntersectionObserver fires - if either fails, the section is
   blank. The entrance is now a pure CSS animation, so the content is visible
   with or without JavaScript. .visible is kept harmless for the existing JS. */
.feature-card {
    background: #fff;
    padding: var(--space-lg);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    text-align: center;
    box-shadow: var(--shadow-sm);
    transition: transform var(--transition), box-shadow var(--transition);
}

.feature-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow-lg);
}

@media (prefers-reduced-motion: no-preference) {
    .feature-card {
        animation: card-rise 0.5s ease both;
    }

    .features-grid > :nth-child(2) { animation-delay: 0.08s; }
    .features-grid > :nth-child(3) { animation-delay: 0.16s; }
    .features-grid > :nth-child(4) { animation-delay: 0.24s; }
}

@keyframes card-rise {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: none; }
}

.feature-icon {
    color: var(--secondary-color);
    margin-bottom: var(--space-sm);
}

.feature-icon .icon {
    width: 40px;
    height: 40px;
    fill: currentColor;
}

.feature-card h3 {
    margin-bottom: 15px;
    color: var(--primary-color);
}

/* Products Preview */

.products-preview {
    padding: var(--section-y) 0;
    background: #eef1f3;
}

.product-overlay .product-title.white {
    color: var(--light-color);
    margin: 0;
}

.products-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
}

.product-card {
    position: relative;
    overflow: hidden;
    border-radius: 5px;
    height: 250px;
}

.product-card img {
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.product-card:hover img {
    transform: scale(1.1);
}

.product-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    padding: 20px;
    transform: translateY(100%);
    transition: transform 0.3s ease;
}

.product-card:hover .product-overlay {
    transform: translateY(0);
}

/* product track */

.products-preview-1 {
    padding: var(--section-y) 0;
    background: linear-gradient(to bottom, #e0e0e0, rgba(255, 255, 255, 0.05));
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
}

.product-card-1 img {
    width: 100%;
    height: 180px;
    /* Fix uniform height */
    object-fit: cover;
    /* Crop to fit without distortion */
    border-radius: 8px;
}

.product-slider {
    overflow: hidden;
    position: relative;
}

.product-track {
    display: flex;
    gap: 20px;
    animation: scrollLoop 15s linear infinite;
}

.product-card-1 {
    background: white;
    border-radius: 12px;
    min-width: 220px;
    text-align: center;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.product-card-1:hover {
    transform: translateY(-5px) scale(1.02);
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
}

@keyframes scrollLoop {
    0% {
        transform: translateX(0);
    }

    100% {
        transform: translateX(-100%);
    }
}

/* Once script.js has cloned the cards, one copy is half the track, so travelling
   -50% lands the clone exactly where the original began - no snap. Without JS the
   single set still scrolls under scrollLoop above, so this is additive. */
.product-track.is-cloned {
    animation-name: scrollLoopSeamless;
}

@keyframes scrollLoopSeamless {
    0% {
        transform: translateX(0);
    }

    100% {
        transform: translateX(-50%);
    }
}

@media (prefers-reduced-motion: reduce) {
    .product-track {
        animation: none;
    }
}

/* Carousal Slider */
.apple-slider .slide-content {
    height: 450px;
    background-size: cover;
    background-position: center;
    position: relative;
    transition: transform 0.5s ease-in-out;
}

.apple-slider .carousel-item {
    transition: transform 1s ease-in-out, opacity 1s ease-in-out;
    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
    ;
}

.apple-slider .text-overlay {
    background: rgba(0, 0, 0, 0.35);
    padding: 40px;
    border-radius: 20px;
    max-width: 600px;
}

.carousel-indicators [data-bs-target] {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: white;
    opacity: 0.7;
}

.carousel-indicators .active {
    opacity: 1;
}

.carousel-control-prev-icon,
.carousel-control-next-icon {
    background-size: 100%, 100%;
    background-image: none;
}

.carousel-control-prev-icon::after,
.carousel-control-next-icon::after {
    content: '';
    display: inline-block;
    width: 25px;
    height: 25px;
    border-top: 3px solid white;
    border-right: 3px solid white;
}

.carousel-control-prev-icon::after {
    transform: rotate(-135deg);
}

.carousel-control-next-icon::after {
    transform: rotate(45deg);
}


/* About Us Page Content */

.vmgv-card {
    border: none;
    border-radius: 12px;
    background: #fff;
    transition: all 0.4s ease;
    opacity: 0;
    transform: translateY(40px);
}

.vmgv-card.visible {
    opacity: 1;
    transform: translateY(0);
}

.vmgv-card:hover {
    transform: translateY(-8px) scale(1.02);
    box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
}

.feature-icon {
    transition: transform 0.5s ease;
}

.vmgv-card:hover .feature-icon {
    transform: rotate(360deg);
}

.company-overview h2 {
    color: var(--dark-color);
}

.company-overview p {
    color: var(--text-color);
    line-height: 1.7;
}

.company-overview img {
    transition: transform 0.4s ease;
}

.company-overview img:hover {
    transform: scale(1.05);
}

.company-overview .btn-primary {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
}

.company-overview .btn-primary:hover {
    background-color: var(--secondary-cta);
    border-color: var(--secondary-cta);
}

/* Contact Page */

/* There was a `.contact_container` rule here, spelled with an underscore while
   the page has always written the class with a hyphen - so it matched nothing
   and <main> ran the full width of the viewport. On a 1920px screen that made
   the form fields over 1000px wide, and the .row inside pulled its negative
   gutters past the left edge, so the heading sat against the window frame. The
   page now uses Bootstrap's own .container, which is what the shared header and
   footer use, so all three line up at every breakpoint. */

.header {
    background: linear-gradient(135deg, #1a5276 0%, #2c3e50 100%);
    color: white;
    /* Both headings in here - the h1 banner title and the display-4 - were
       rendering navy on this gradient, 1.05:1 to 1.25:1. This is the quality
       and contact page banner. */
    --heading-color: currentColor;
    padding: 5rem 0;
    margin-bottom: 3rem;
}

/* The banner text is centred with .text-center, but `p { max-width: 68ch }`
   leaves the lead narrower than its column, and a narrower block still sits at
   the column's left edge - so the paragraph rendered a few dozen pixels left of
   the heading it sits under. Both banners that use .header had this. */
.header .lead {
    margin-inline: auto;
}

/* The location card sits directly beside the enquiry form, so it borrows the
   form's border, radius and shadow - it had border-0, which on a white page
   left one of the two panels with no edge at all. Its headings ran at the
   document h2/h3 sizes, so "Location Details" came out half again the size of
   "Request a Quotation" next to it: two panels of equal standing reading as a
   heading and a footnote. */
.contact-details {
    border: 1px solid #e3e6e8;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.contact-details h2 {
    font-size: 1.5rem;
}

.contact-details h3 {
    font-size: 1.15rem;
}

.map-container {
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    margin-bottom: 2rem;
}

.info-card {
    background: white;
    border-radius: 10px;
    padding: 1.5rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.directions-btn {
    transition: all 0.3s ease;
}

.directions-btn:hover {
    transform: translateY(-2px);
    color: #e67e22;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* Quality Page */
/* A bare `h2` here set --dark-color and, sitting after the heading block above
   at the same specificity, won on every page this stylesheet reaches - not the
   quality page it was labelled for. --dark-color is #2c3e50, which is exactly
   the dark end of the .header gradient, so "Quality Excellence" was rendering
   at 1.00:1: the text was the background. Headings resolve through
   --heading-color; there is no reason for this rule to exist. */

.quality_img img {
    max-width: 70%;
    height: auto;
    margin: 0 auto;
    display: block;
}

.pdf-container {
    border: 1px solid #e9ecef;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    margin-bottom: 30px;
    height: 100%;
    min-height: 500px;
}

.pdf-viewer {
    height: 100%;
    width: 100%;
    min-height: 500px;
}

/* The duplicate .feature-card, .feature-icon and .btn-primary blocks that used
   to sit here have been folded into their definitions above. The .feature-icon
   copy referenced an accent-color custom property that is not defined anywhere
   in the site, so the icons fell back to the inherited text colour instead of
   the intended accent. */

.btn-outline-primary {
    color: var(--primary-color);
    border-color: var(--primary-color);
    min-height: 44px;
}

.btn-outline-primary:hover {
    background-color: var(--primary-color);
    border-color: var(--primary-color);
    /* Was declared twice, orange then white; white is the one that applied. */
    color: #fff;
}