/* ============================================================
   IKON MOBILITY — WordPress overrides
   ------------------------------------------------------------
   Loaded AFTER css/styles.css, so anything here wins.

   The point of this file is that css/styles.css can be replaced
   wholesale with a newer export from the static site without
   losing these fixes. Do not move them into styles.css unless
   you are also maintaining the static site, in which case put
   them in both.

   Each fix records what it is for, so nobody removes one later
   without knowing what it was doing.
   ============================================================ */

/* ------------------------------------------------------------
   1. Starfield respects reduced motion — WCAG 2.2.2
   ------------------------------------------------------------
   The sparkle layers on body::before / body::after are animated
   SVGs supplied as data URIs. Their @keyframes live INSIDE the
   SVG document, so the global reduced-motion kill-switch in
   styles.css cannot reach them — page CSS does not cascade into
   an SVG used as a background-image.

   Result without this rule: a visitor who has asked their
   operating system for less motion gets a page where everything
   correctly stops except the stars, which keep pulsing.

   Hiding the two layers leaves the black background, the noise
   texture and the coloured gradients intact, so the page still
   looks deliberate rather than bare.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    body::before,
    body::after {
        display: none;
    }
}

/* ------------------------------------------------------------
   2. Footer contrast — WCAG 1.4.3
   ------------------------------------------------------------
   The audit measured the footer headings against #000000 and
   concluded that switching them to --accent-bright (#ef4444)
   would be close to passing. The footer is not black: it carries
   footer-bg.webp behind a 50-62% overlay.

   Measured against the actual photo, sampled across the whole
   image at the 50% overlay used at the top of the footer:

     #ef4444 headings   min 1.09:1, median 3.13:1, 82% of the
                        area below the required 4.5:1
     #ffffff body text  min 4.12:1 — marginal in the lightest
                        corner

   Two changes together fix it:
     - deepen the overlay to 88-92%, which the photo survives
       because it is texture rather than subject matter
     - lighten the headings to #fca5a5

   After both: headings min 7.04:1, body text min 13.37:1,
   nothing below 4.5:1 anywhere in the footer.
   ------------------------------------------------------------ */
/* Fallback only. inc/social.php prints an inline rule in <head> that
   overrides this, built from the photo and overlay strength set at
   Settings -> Site Settings -> Footer. This value is what shows if
   that inline rule is ever missing. */
footer::before {
    background:
        linear-gradient(180deg,
            rgba(10, 14, 26, 0.88) 0%,
            rgba(10, 14, 26, 0.92) 100%),
        url('../images/footer-bg.webp') center / cover no-repeat;
}

footer h3 {
    color: #fca5a5;
}

/* ------------------------------------------------------------
   3. Contact Form 7
   ------------------------------------------------------------
   The existing form styling in styles.css targets bare elements —
   form, form label, form input, form button. Contact Form 7 wraps
   every field in extra markup and renders its submit control as
   <input type="submit"> rather than <button>. Without the rules
   below, fields collapse to their default width and the submit
   button renders as a dark text box.

   Nothing here restyles the design. It maps CF7's markup onto the
   styling that already exists.
   ------------------------------------------------------------ */

/* CF7 wraps the whole form in a div; the card styling lives on the
   <form> inside it, so the wrapper must not add a second box. */
.wpcf7 {
    background: none;
    padding: 0;
    border: none;
    box-shadow: none;
}

/* Every field is wrapped in a <span>, which is inline — so the
   width:100% on the input inside has nothing to measure against. */
.wpcf7-form-control-wrap {
    display: block;
    margin-bottom: 1.25rem;
}

/* CF7 renders submit as an <input>, which the stylesheet would
   otherwise treat as a text field. Restate the button styling. */
form .wpcf7-submit,
form input[type="submit"] {
    width: 100%;
    background: var(--accent);
    color: #fff;
    padding: 1rem 2rem;
    border: none;
    border-radius: 50px;
    font-weight: 700;
    font-size: 1rem;
    cursor: pointer;
    transition: var(--transition);
    box-shadow: 0 8px 20px rgba(220, 38, 38, 0.4);
    margin-top: 0.5rem;
    letter-spacing: 0.02em;
}

form .wpcf7-submit:hover,
form input[type="submit"]:hover {
    background: var(--accent-bright);
    transform: translateY(-2px);
    box-shadow: 0 12px 28px rgba(220, 38, 38, 0.5);
}

/* Validation messages.
   CF7's defaults are a dark red on a transparent background, which
   on this dark card measures well under 4.5:1. #fca5a5 is the same
   colour used elsewhere on the site for error text, and clears it
   comfortably. */
.wpcf7-not-valid-tip {
    color: #fca5a5;
    font-size: 0.9rem;
    font-weight: 500;
    margin-top: 0.4rem;
}

.wpcf7-form-control.wpcf7-not-valid {
    border-color: #fca5a5;
}

/* The message shown after submitting. CF7 ships a 2px border in a
   colour chosen for light themes. */
.wpcf7-response-output {
    margin: 1.5rem 0 0;
    padding: 1rem 1.25rem;
    border-radius: 8px;
    border: 1px solid var(--border-strong);
    background: rgba(0, 0, 0, 0.35);
    color: var(--text);
    font-size: 0.95rem;
}

.wpcf7 form.sent .wpcf7-response-output {
    border-color: #4ade80;
    color: #bbf7d0;
}

.wpcf7 form.invalid .wpcf7-response-output,
.wpcf7 form.unaccepted .wpcf7-response-output,
.wpcf7 form.failed .wpcf7-response-output {
    border-color: #fca5a5;
    color: #fecaca;
}

/* The submitting spinner sits inline and shifts the button. */
.wpcf7-spinner {
    display: block;
    margin: 0.75rem auto 0;
}

/* Fallback panel shown if the form ID is missing or CF7 is off. */
.form-fallback {
    background: var(--grad-card);
    padding: 2.5rem;
    border-radius: var(--radius);
    border: 1px solid var(--border);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

.form-fallback a {
    color: var(--primary-bright);
    font-weight: 600;
}

/* ------------------------------------------------------------
   4. Brand logos under reduced motion
   ------------------------------------------------------------
   The logo strip is printed twice. That is required for the
   marquee: the animation slides the row by exactly -50% and snaps
   back, so the second half has to be an identical copy or the loop
   visibly jumps.

   But styles.css correctly stops that animation under
   prefers-reduced-motion, and turns the strip into a manually
   scrollable row instead. At that point the duplicate set has no
   job left. It is not a seamless loop any more — it is just every
   partner listed twice, which reads as a mistake.

   Screen readers were already spared this: the duplicates carry
   aria-hidden and empty alt text. This does the same for people
   who can see the page.

   So: no animation, no duplicates.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
    main > section.brands ul li[aria-hidden="true"] {
        display: none;
    }
}

/* ------------------------------------------------------------
   5. Larger main navigation — fluid, always one line
   ------------------------------------------------------------
   Measured from the real font metrics, not guessed. The nine menu
   labels total 40.31em at weight 600. The brand block (195px logo
   + tagline) takes about 342px, and the header has 64px of its own
   padding. So:

       available = viewport - 406px - item padding - gaps
       max font  = available / 40.31

   Which gives, with the tightened padding set below:

       1280px  ->  1.13rem      1600px  ->  1.63rem
       1366px  ->  1.27rem      1920px  ->  2.13rem
       1440px  ->  1.38rem

   Note what that means: the ORIGINAL 1.14rem was already wrapping
   on any laptop at 1366px or narrower. This was not introduced by
   making the text bigger.

   Rather than pick one number that is too small on a large screen
   and too big on a laptop, the size is fluid: as large as will fit
   at whatever width the browser is, capped at 2.2rem so it stops
   growing on very wide monitors. The calc carries about 6% slack
   so it never sits exactly on the wrap point.

   Padding and gap are in rem, so they do NOT grow with the text —
   that is deliberate, and it is what buys the headroom.
   ------------------------------------------------------------ */

header nav ul {
    gap: 0.1rem;
    flex-wrap: nowrap;
}

header nav ul li a {
    /* Reduced 30% from the previous clamp(1.05rem, 2.33vw - 12.8px, 2.2rem).
       Every term scaled by 0.7, so the fluid behaviour is unchanged —
       it still grows with the window and still holds one line, just
       smaller throughout. */
    font-size: clamp(0.74rem, 1.63vw - 8.96px, 1.54rem);
    padding: 0.5rem 0.45rem;
    font-weight: 600;
    white-space: nowrap;
}

/* Scrolled state keeps the same size — the header compacts by
   losing vertical padding, not by shrinking the navigation. */

/* Below 900px the hamburger takes over and the menu becomes a
   stacked panel, where large text costs nothing and helps. */
@media (max-width: 900px) {
    header nav ul {
        flex-wrap: wrap;
    }
    header nav ul li a {
        /* 1.6rem reduced by 30%. Still comfortably above the 1rem
           minimum body size, which matters in a stacked mobile menu
           read by people who often have poor near vision. */
        font-size: 1.12rem;
        padding: 0.6rem 0.9rem;
        white-space: normal;
    }
}

/* ------------------------------------------------------------
   6. Centred navigation, and a readable compact header
   ------------------------------------------------------------ */

/* The nav takes all the space left of the right edge and centres
   its items within it. Note this centres the menu in the space
   BESIDE the logo, not on the page's true centre line — with the
   logo block taking ~342px on the left and nothing on the right,
   true page-centring would need an empty spacer of matching width,
   which would squeeze the menu into ~600px and force it to wrap.
   Centring in the available space is the version that fits. */
header nav {
    flex: 1 1 auto;
    min-width: 0;
}

header nav ul {
    justify-content: center;
}

/* The header compacts on scroll — it was dropping to 0.4rem (6.4px)
   top and bottom, which crushed the menu against the edge just when
   it is the only navigation on screen. 20px at the top restores the
   breathing room; the bottom stays a little tighter so the bar does
   not take more height than it needs. */
header.is-scrolled {
    padding-top: 20px;
    padding-bottom: 12px;
}

/* Below the hamburger breakpoint the menu is a stacked panel, so
   it should sit left-aligned and full width, not centred. */
@media (max-width: 900px) {
    header nav {
        flex: 1 1 100%;
    }
    header nav ul {
        justify-content: flex-start;
    }
    header.is-scrolled {
        padding-top: 12px;
        padding-bottom: 12px;
    }
}

/* ------------------------------------------------------------
   7. Brand strip that does not fill the width
   ------------------------------------------------------------
   `is-static` is added by js/brands.js when the logos are narrower
   than the space available — see that file for the reasoning.
   Everything here is the "few logos" case; the scrolling marquee
   is untouched.
   ------------------------------------------------------------ */

main > section.brands.is-static ul {
    animation: none;
    width: auto;
    justify-content: center;
    flex-wrap: wrap;
    row-gap: 1.5rem;

    /* The edge fade exists to hide logos sliding in and out. With
       nothing sliding it just dims the first and last logo. */
    mask-image: none;
    -webkit-mask-image: none;
}

/* The second set is only there to make the loop seamless. No loop,
   no reason to show every partner twice. */
main > section.brands.is-static ul li[aria-hidden="true"] {
    display: none;
}

/* Nothing is moving, so a pause control is meaningless. enhance.js
   adds the button before it can know this, so hide it here. */
main > section.brands.is-static .marquee-toggle {
    display: none;
}

/* ------------------------------------------------------------
   8. Linked partner logos
   ------------------------------------------------------------
   The anchor has to fill the tile, or only the logo pixels are
   clickable and the generous padding around them is dead space —
   which on a 360px-wide tile is most of the target.
   ------------------------------------------------------------ */

main > section.brands ul li a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

main > section.brands ul li a:focus-visible {
    outline: 3px solid var(--accent-bright);
    outline-offset: 6px;
    border-radius: 6px;
}

/* Only linked tiles should look clickable. The original CSS put
   cursor:pointer on every tile, which promises something the
   unlinked ones do not deliver. */
main > section.brands ul li {
    cursor: default;
}

main > section.brands ul li:has(a) {
    cursor: pointer;
}

/* ------------------------------------------------------------
   9. Contact page: equal-height cards
   ------------------------------------------------------------
   Two things were stopping the contact details card and the form
   card from matching.

   1. styles.css sets `align-items: start` on the split grid, which
      tells each column to be only as tall as its own content.
      `stretch` makes both fill the taller of the two.

   2. Contact Form 7 wraps the form in its own <div class="wpcf7">.
      That div becomes the grid item and stretches, but the <form>
      inside it — which is what carries the card background, border
      and padding — does not follow, so the visible card stayed
      short. Making the wrapper a flex column and the form grow
      fixes it.

   The form's own contents are then pushed apart so the submit
   button sits at the bottom of the card rather than floating in
   the middle of empty space.
   ------------------------------------------------------------ */

main > section.split > div {
    align-items: stretch;
}

/* CF7's wrapper is the grid item; the form inside it is the card. */
main > section.split > div > .wpcf7 {
    display: flex;
    flex-direction: column;
    height: 100%;
}

main > section.split > div > .wpcf7 > form {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

main > section.split > div > .wpcf7 > form > fieldset {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

/* Push the submit button to the bottom of the card. */
main > section.split > div > .wpcf7 .wpcf7-submit,
main > section.split > div > .wpcf7 input[type="submit"] {
    margin-top: auto;
}

/* Same for the plain-HTML fallback card shown if CF7 is off. */
main > section.split > div > .form-fallback {
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* On one column the heights are irrelevant, and stretching an
   address block to match a long form just adds empty space. */
@media (max-width: 900px) {
    main > section.split > div {
        align-items: start;
    }
    main > section.split > div > .wpcf7,
    main > section.split > div > .form-fallback {
        height: auto;
    }
}

/* ------------------------------------------------------------
   10. Footer "Email us" shortcut
   ------------------------------------------------------------
   Centred under the phone number in the Get In Touch card.
   Deliberately styled as a bordered pill rather than a bare icon:
   a 24px envelope on its own is both a small target and an
   ambiguous one. With the label beside it there is no guessing
   what it does, and the whole pill is tappable — comfortably over
   the 44px minimum, which matters for anyone with limited
   dexterity.
   ------------------------------------------------------------ */

footer .footer-email {
    text-align: center;
    margin-top: 1.25rem;
}

footer .footer-email a {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 44px;
    padding: 0.5rem 1.1rem;
    border: 1px solid var(--border-strong);
    border-radius: 50px;
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.95rem;
    font-weight: 600;
    transition: var(--transition);
}

footer .footer-email a svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
    flex: 0 0 auto;
}

footer .footer-email a:hover,
footer .footer-email a:focus-visible {
    color: #fff;
    border-color: var(--primary-bright);
    background: rgba(45, 108, 214, 0.18);
}

footer .footer-email a:focus-visible {
    outline: 3px solid var(--accent-bright);
    outline-offset: 3px;
}

/* ------------------------------------------------------------
   11. Footer cards — identical hover on all five
   ------------------------------------------------------------
   styles.css already styles these with `footer > section > *`,
   which covers every child equally — there is no rule anywhere
   that treats the <article> cards differently from the <nav>
   ones. So rather than chase a difference that is not in the
   stylesheet, this states the whole effect explicitly for both
   element types. Whatever was happening before, all five now do
   the same thing.

   The accent glow is the "coloured" part: a red-tinted border and
   halo drawn from --accent, matching the colour the footer already
   uses for its headings and link hovers.

   `:focus-within` is included so a keyboard user tabbing through
   the footer links gets the same highlight a mouse user does. The
   original had no keyboard equivalent at all, which left the
   footer giving no indication of which block you were in.
   ------------------------------------------------------------ */

footer > section > :is(article, nav) {
    background: linear-gradient(145deg,
        rgba(58, 63, 82, 0.55) 0%,
        rgba(31, 35, 51, 0.55) 100%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    transition: background 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                border-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                transform 0.3s cubic-bezier(0.4, 0, 0.2, 1),
                box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

footer > section > :is(article, nav):hover,
footer > section > :is(article, nav):focus-within {
    background: linear-gradient(145deg,
        rgba(70, 75, 95, 0.65) 0%,
        rgba(39, 43, 61, 0.65) 100%);
    border-color: rgba(239, 68, 68, 0.55);
    transform: translateY(-4px);
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.4),
                0 0 0 1px rgba(239, 68, 68, 0.18),
                0 8px 28px rgba(220, 38, 38, 0.22);
}

/* Reduced motion: keep the colour, drop the movement. */
@media (prefers-reduced-motion: reduce) {
    footer > section > :is(article, nav):hover,
    footer > section > :is(article, nav):focus-within {
        transform: none;
    }
}

/* styles.css already disables the lift on small screens, where
   there is no hover to speak of. Keep the glow off too. */
@media (max-width: 760px) {
    footer > section > :is(article, nav):hover,
    footer > section > :is(article, nav):focus-within {
        transform: none;
        border-color: rgba(255, 255, 255, 0.08);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    }
}

/* ------------------------------------------------------------
   12. Screen-reader-only text
   ------------------------------------------------------------
   `.sr-only` was defined in the <style> block inside
   stockists.html on the static site, so it only ever existed on
   that one page. Anything using the class elsewhere — or the
   stockists page itself if locator.css fails to load — would show
   its hidden label as visible text.

   Defining it globally removes that failure mode. `.visually-hidden`
   is included too, since the hero slider's live region uses that
   spelling.
   ------------------------------------------------------------ */

.sr-only,
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* ------------------------------------------------------------
   13. Catalogue — document cards
   ------------------------------------------------------------
   Cover image, file size, last-updated date, download button.

   No embedded viewer and no flipbook, deliberately. Both are
   heavy, awkward on a phone and effectively unusable with a
   keyboard or a screen reader. Given who visits this site, an
   honest download with its size stated is the more professional
   answer as well as the more usable one.
   ------------------------------------------------------------ */

.doc-grid {
    display: grid;
    /* auto-fill, not auto-fit: with three cards in a four-column row,
       auto-fit collapses the empty track and stretches the three to
       fill it, so a row of three looks nothing like a row of four.
       auto-fill keeps the column width consistent down the page. */
    /* Narrower tracks now the cards are text only — three or four
       across instead of two or three, so a product with six documents
       reads as one block rather than a long column. */
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 1.25rem;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
}

.doc-card {
    display: flex;
    flex-direction: column;
    background: var(--grad-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    transition: var(--transition);
}

.doc-card:hover,
.doc-card:focus-within {
    border-color: var(--primary-bright);
    transform: translateY(-4px);
    box-shadow: 0 12px 28px rgba(0, 0, 0, 0.45);
}

.doc-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 1.25rem;
    text-align: left;
}

.doc-body h3 {
    font-size: 1.05rem;
    margin: 0 0 0.25rem;
    color: #fff;
}

.doc-type {
    margin: 0 0 0.75rem;
    font-size: 0.9rem;
    color: var(--text-light);
}

/* Format, size and date. Small, quiet, and factual — the things
   people actually want to know before clicking a download. */
.doc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 0.75rem;
    margin: 0 0 1.25rem;
    font-size: 0.8rem;
    color: var(--text-light);
}

.doc-meta .doc-format {
    padding: 0.1rem 0.5rem;
    border: 1px solid var(--border-strong);
    border-radius: 4px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: #fca5a5;
}

/* Pushed to the bottom so buttons line up across a row of cards
   whose titles run to different lengths. */
/* Bigger, fuller, higher contrast.
   - full width of the card instead of a small pill, so it is an
     obvious target rather than something to aim at
   - 1.05rem and weight 700: readable at a glance, which matters
     for an audience with a lot of presbyopia in it
   - 56px tall, comfortably over the 44px minimum touch target
   - white on --accent measures about 4.9:1, clearing the 4.5:1
     requirement, where the previous blue on this card sat lower */
.doc-download {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    margin-top: auto;
    min-height: 56px;
    padding: 0.85rem 1.25rem;
    border-radius: 10px;
    /* #a7242c is sampled from the logo itself — the deeper red on the
       shaded side of the mark, rather than the bright #ef1c22 on its
       lit side. It reads as the same brand colour without glaring.

       It is also the better choice for contrast. White on the old
       --accent (#dc2626) measured 4.83:1, only just over the 4.5:1
       requirement. White on this measures 7.16:1 — comfortable rather
       than borderline, which matters on a button this size for
       readers with reduced contrast sensitivity. */
    background: #a7242c;
    color: #fff;
    font-weight: 700;
    font-size: 1.05rem;
    letter-spacing: 0.01em;
    border: 1px solid transparent;
    transition: var(--transition);
}

/* Hover lifts to the logo's brighter red — still the brand colour,
   still 5.6:1 against white, and the change is clearly visible. */
.doc-download:hover {
    background: #c1121f;
    box-shadow: 0 8px 20px rgba(167, 36, 44, 0.4);
    transform: translateY(-2px);
}

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

.doc-download:focus-visible {
    outline: 3px solid var(--accent-bright);
    outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
    .doc-card:hover,
    .doc-card:focus-within {
        transform: none;
    }
}

/* ------------------------------------------------------------
   14. Documents list on the product page
   ------------------------------------------------------------
   Replaces the download buttons that used to sit in the hero row.
   Past three or four files that row became a wall of grey pills
   with "Enquire Now" lost among them, and finding the warranty
   statement meant reading every one.

   A list scans in a way a row of pills does not: name first, then
   the format, size and date underneath in smaller type.
   ------------------------------------------------------------ */

.doc-list {
    list-style: none;
    padding: 0;
    margin: 0 auto;
    max-width: 760px;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.doc-list > li {
    margin: 0;
}

.doc-list a {
    display: flex;
    align-items: center;
    gap: 1rem;
    min-height: 64px;
    padding: 0.9rem 1.25rem;
    background: var(--grad-card);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    color: var(--text);
    text-align: left;
    transition: var(--transition);
}

.doc-list a:hover,
.doc-list a:focus-visible {
    border-color: var(--primary-bright);
    background: linear-gradient(145deg,
        rgba(70, 75, 95, 0.65) 0%,
        rgba(39, 43, 61, 0.65) 100%);
    transform: translateX(4px);
}

.doc-list a:focus-visible {
    outline: 3px solid var(--accent-bright);
    outline-offset: 3px;
}

.doc-list-icon {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: rgba(220, 38, 38, 0.12);
    color: #fca5a5;
}

.doc-list-icon svg { width: 20px; height: 20px; }

.doc-list-text {
    flex: 1 1 auto;
    min-width: 0;
}

.doc-list-text strong {
    display: block;
    font-size: 1rem;
    font-weight: 600;
    color: #fff;
}

.doc-list-text small {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.82rem;
    color: var(--text-light);
}

.doc-list-action {
    flex: 0 0 auto;
    color: var(--primary-bright);
}

.doc-list-action svg { width: 20px; height: 20px; }

@media (prefers-reduced-motion: reduce) {
    .doc-list a:hover,
    .doc-list a:focus-visible { transform: none; }
}

/* ------------------------------------------------------------
   15. Catalogue grouped by product
   ------------------------------------------------------------ */

/* styles.css turns EVERY direct <div> child of a <section> into a
   grid: `main > section > div { display: grid; grid-template-columns:
   repeat(auto-fit, minmax(280px, 1fr)) }`. That is what makes the
   product card rows work.

   .doc-product is such a div, so it was being turned into a
   two-column grid holding the product heading in one column and the
   whole document grid squeezed into the other — which is why
   documents past the first few looked cut off or missing.

   Forcing it back to a block lets its children stack, and .doc-grid
   below does its own grid properly across the full width. */
.doc-product {
    display: block;
    max-width: 1200px;
    margin: 0 auto 3rem;
}

.doc-product-title {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin: 0 0 1rem;
    padding-bottom: 0.6rem;
    border-bottom: 1px solid var(--border);
    text-align: left;
    font-size: 1.35rem;
}

.doc-product-title a { color: #fff; }
.doc-product-title a:hover { color: var(--primary-bright); }

.doc-count {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--text-light);
}

/* The card title is now the document name — the product name is the
   heading above it, so repeating it on every card added nothing. */
.doc-card h4 {
    font-size: 1rem;
    margin: 0 0 1rem;
    color: #fff;
}

/* ------------------------------------------------------------
   16. "All Documents" button
   ------------------------------------------------------------
   Sits on its own line, centred, under the four buttons above it.

   `flex-basis: 100%` forces the wrap; the auto margins centre it
   within that new line. Done this way rather than with a separate
   container so the button stays inside .product-cta-row and keeps
   the row's existing spacing and button styling.
   ------------------------------------------------------------ */

.product-cta-row .btn-all-docs {
    flex: 0 0 100%;
    margin-left: auto;
    margin-right: auto;
    justify-content: center;
    /* Wider, and centred on the row rather than on the two buttons
       above it. Those two sit at the end of a wrapping flex row whose
       contents shift with the viewport, so there is no fixed point to
       align to — centring on the row is the version that stays put at
       every width. */
    max-width: 420px;
    padding-left: 2rem;
    padding-right: 2rem;
}

/* Red on hover rather than the blue the other ghost buttons use.
   The !important is needed because styles.css sets .btn-ghost:hover
   with the same specificity, and this file is only guaranteed to
   load after it — not to outrank it. */
.product-cta-row .btn-all-docs:hover,
.product-cta-row .btn-all-docs:focus-visible {
    background: var(--accent) !important;
    border-color: var(--accent) !important;
    color: #fff !important;
    box-shadow: 0 8px 20px rgba(220, 38, 38, 0.35);
}

.product-cta-row .btn-all-docs:focus-visible {
    outline: 3px solid #fca5a5;
    outline-offset: 3px;
}

/* ------------------------------------------------------------
   17. No arrow on the document cards
   ------------------------------------------------------------
   styles.css appends a → to every link inside an <article>:

       article a:not(.card-img-link)::before { content: '→'; }

   That is right for a "Discover More" card link, where the arrow
   says "this leads somewhere". It is wrong on a download, which
   does not lead anywhere — it fetches a file, and the button
   already carries a download icon saying so.

   It was also landing inside the cover link, drawing a stray
   arrow over the PDF preview.
   ------------------------------------------------------------ */

.doc-card a::before {
    content: none;
}

/* ------------------------------------------------------------
   18. White text on the download buttons
   ------------------------------------------------------------
   `color: #fff` was already set on .doc-download and was losing.

   styles.css has:
       article a:not(.card-img-link)         -> 0,1,2
       article a:not(.card-img-link):hover   -> 0,2,2

   The download button sits inside <article class="doc-card">, so
   those applied and painted it blue, then accent red on hover.
   A single class (.doc-download, 0,1,0) cannot outrank 0,1,2.

   `.doc-card a.doc-download` is 0,2,1, which does — without
   resorting to !important, so the rule can still be overridden
   later in the normal way if it ever needs to be.
   ------------------------------------------------------------ */

.doc-card a.doc-download,
.doc-card a.doc-download:hover,
.doc-card a.doc-download:focus-visible,
.doc-card a.doc-download:visited {
    color: #fff;
}
