@charset "utf-8";
/* ============================================================================
   gdl_motion.css  —  the GDL site-wide motion layer
   ----------------------------------------------------------------------------
   Written 17 September 2026.

   One file, loaded from header.php, that gives every page on the site the same
   small amount of movement: things fade and rise into place, cards lift under
   the cursor, menus open instead of snapping, a red bar runs across the top
   while a page loads, and figures that changed since the last refresh are
   ringed in red for a couple of seconds.

   NOTHING IN HERE HIDES ANYTHING BY ITSELF.
   Everything that starts invisible is behind either .gdl-pre (put on <html> by
   the inline script in header.php, and taken off again after 900ms whether or
   not gdl_motion.js ever loads) or .gdl-r (put on by gdl_motion.js, which only
   ever adds it to elements it is about to animate). If the JavaScript file is
   missing, blocked or broken, the worst that happens is the page appears
   without animation. It can never be left blank.

   Colours are the site's own: #CE122D red, #F16377 light red, #111 black.
   ========================================================================== */

:root {
    --gdl-ease:  cubic-bezier(0.22, 0.61, 0.36, 1);
    --gdl-in:    380ms;
    --gdl-rise:  14px;
    --gdl-red:   #CE122D;
    --gdl-red-2: #F16377;
}


/* ============================================================================
   1.  PRE-HIDE
   ----------------------------------------------------------------------------
   header.php adds .gdl-pre to <html> before the page paints, so content that
   is about to animate does not flash up at full opacity first. The same inline
   script removes it after 900ms no matter what, and gdl_motion.js removes it
   the moment it has taken over.

   KEEP THIS SELECTOR LIST IDENTICAL TO `CANDIDATES` IN gdl_motion.js.
   ========================================================================== */

html.gdl-pre [class*="hero"],
html.gdl-pre [class*="card"],
html.gdl-pre [class*="-wrap"],
html.gdl-pre [class*="page-header"],
html.gdl-pre .container,
html.gdl-pre .boxinside,
html.gdl-pre welcome    > div,
html.gdl-pre home       > div,
html.gdl-pre services   > div,
html.gdl-pre team       > div,
html.gdl-pre portfolio  > div,
html.gdl-pre careers    > div,
html.gdl-pre contact    > div,
html.gdl-pre noaccess   > div {
    opacity: 0;
}


/* ============================================================================
   2.  ENTRANCES
   ----------------------------------------------------------------------------
   .gdl-r  = "this one is going to be revealed" (added by JS, holds it hidden)
   .gdl-f  = fade only, no movement — used for full-width bands whose layout
             relies on negative margins, and for anything holding a map, a
             canvas or an iframe, where a transform can upset the contents
   .gdl-in = go
   JS strips all three off again once the transition has finished, so nothing
   is left carrying a transform or a will-change.
   ========================================================================== */

html.gdl-motion .gdl-r {
    opacity: 0;
    transform: translateY(var(--gdl-rise));
    will-change: opacity, transform;
}

html.gdl-motion .gdl-r.gdl-f {
    transform: none;
    will-change: opacity;
}

html.gdl-motion .gdl-r.gdl-in {
    opacity: 1;
    transform: none;
    transition: opacity var(--gdl-in) var(--gdl-ease),
                transform var(--gdl-in) var(--gdl-ease);
}


/* ============================================================================
   3.  HOVER
   ----------------------------------------------------------------------------
   Only on real pointers — on a phone :hover sticks after a tap and the card
   would stay lifted.
   ========================================================================== */

/* Cards. 17 September 2026 — these used to rise 3px under the cursor and it
   looked messy, so nothing moves now: the shadow deepens a little and that is
   all. To take even that away, delete the .gdl-lift:hover rule below. */
@media (hover: hover) {

    html.gdl-motion .gdl-lift {
        transition: box-shadow 180ms var(--gdl-ease);
    }

    html.gdl-motion .gdl-lift:hover {
        box-shadow: 0 6px 20px rgba(0, 0, 0, 0.14);
    }

    /* Buttons. Excludes the nav bar's own buttons, which have their own look. */
    html.gdl-motion button:not(.dropbtn):not(.submenu-btn):hover,
    html.gdl-motion input[type="submit"]:hover,
    html.gdl-motion input[type="reset"]:hover,
    html.gdl-motion input[type="button"]:hover {
        transform: translateY(-1px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.22);
    }

    /* Table rows. background-image is used rather than background-color so the
       tint sits ON TOP of whatever the row already has — striping, status
       colours, inline styles, even page rules marked !important — instead of
       replacing it. Only tables JS has identified as data tables get this. */
    html.gdl-motion table.gdl-rows > tbody > tr:hover > td {
        background-image: linear-gradient(rgba(206, 18, 45, 0.06),
                                          rgba(206, 18, 45, 0.06));
    }
}

/* Colour changes ease rather than snap. Safe everywhere, touch included. */
html.gdl-motion button:not(.dropbtn):not(.submenu-btn),
html.gdl-motion input[type="submit"],
html.gdl-motion input[type="reset"],
html.gdl-motion input[type="button"] {
    transition: background-color 170ms ease,
                color 170ms ease,
                box-shadow 180ms var(--gdl-ease),
                transform 110ms var(--gdl-ease);
}

html.gdl-motion button:not(.dropbtn):not(.submenu-btn):active,
html.gdl-motion input[type="submit"]:active,
html.gdl-motion input[type="reset"]:active,
html.gdl-motion input[type="button"]:active {
    transform: translateY(0);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
    transition-duration: 60ms;
}

/* Links and form fields. The menu bar is deliberately left out — see part 4. */
html.gdl-motion a { transition: color 150ms ease, background-color 150ms ease; }

html.gdl-motion .navbar a,
html.gdl-motion .dropdown-content a,
html.gdl-motion .dropdown-submenu-content a {
    transition: none;
}

html.gdl-motion input[type="text"],
html.gdl-motion input[type="password"],
html.gdl-motion input[type="number"],
html.gdl-motion input[type="date"],
html.gdl-motion input[type="time"],
html.gdl-motion input[type="email"],
html.gdl-motion input[type="tel"],
html.gdl-motion input[type="search"],
html.gdl-motion select,
html.gdl-motion textarea {
    transition: border-color 150ms ease, box-shadow 150ms ease;
}

html.gdl-motion input[type="text"]:focus,
html.gdl-motion input[type="password"]:focus,
html.gdl-motion input[type="number"]:focus,
html.gdl-motion input[type="date"]:focus,
html.gdl-motion input[type="time"]:focus,
html.gdl-motion input[type="email"]:focus,
html.gdl-motion input[type="tel"]:focus,
html.gdl-motion input[type="search"]:focus,
html.gdl-motion select:focus,
html.gdl-motion textarea:focus {
    box-shadow: 0 0 0 3px rgba(206, 18, 45, 0.16);
}


/* ============================================================================
   4.  THE MENU BAR
   ----------------------------------------------------------------------------
   17 September 2026 — the menus are left exactly as main.css has them. The
   first version of this file animated them open and put position:relative on
   .dropdown so a red underline could be hung off it. That relative was a
   mistake: .dropdown-content is absolutely positioned, and below 1049px
   main.css gives it `min-width: 100%; left: 0` so the panel spans the whole
   menu bar. Making .dropdown the containing block re-pointed that 100% at the
   button instead, and the panels collapsed to the width of their own button —
   1024px wide down to 138px, and on a phone 390px down to 71px.

   So: no animation on the panels, no transitions on the bar, and nothing on
   .dropdown at all. The only thing left is the red underline, and it now hangs
   off the .dropbtn itself. That is safe because the button is a SIBLING of
   .dropdown-content, not its parent — making the button a containing block
   cannot reach the panel. Do not put position on .dropdown again.
   ========================================================================== */

/* A hairline of red under the menu button whose panel is open, so you can see
   at a glance which menu you are in. */
html.gdl-motion .navbar .dropbtn {
    position: relative;   /* anchors the underline below, and nothing else */
}

html.gdl-motion .navbar .dropbtn::after {
    content: "";
    position: absolute;
    left: 10%;
    right: 10%;
    bottom: 4px;
    height: 2px;
    border-radius: 2px;
    background: var(--gdl-red);
    transform: scaleX(0);
    transform-origin: center;
    transition: transform 180ms var(--gdl-ease);
    pointer-events: none;
}

html.gdl-motion .navbar .dropdown.open > .dropbtn::after,
html.gdl-motion .navbar .dropbtn:hover::after {
    transform: scaleX(1);
}


/* ============================================================================
   5.  PAGE LOADING BAR
   ----------------------------------------------------------------------------
   A thin red bar across the very top from the moment a link is clicked until
   the next page paints. Switched off on the screens that refresh themselves —
   see gdl_motion.js — so the office wallboards don't flicker a red line every
   five minutes.
   z-index clears .sticky (2000) and the menu fly-outs (9999).
   ========================================================================== */

.gdl-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 3px;
    z-index: 99999;
    pointer-events: none;
    background: transparent;
    opacity: 1;
    transition: opacity 260ms ease;
}

.gdl-progress.gdl-progress-done { opacity: 0; }

.gdl-progress > i {
    display: block;
    height: 100%;
    width: 0;
    background: linear-gradient(90deg, var(--gdl-red), var(--gdl-red-2));
    box-shadow: 0 0 9px rgba(206, 18, 45, 0.75);
    transition: width 220ms ease;
}


/* ============================================================================
   6.  CHANGED SINCE LAST REFRESH
   ----------------------------------------------------------------------------
   On the pages that sit open on an office screen, a value that has changed
   since the previous refresh gets ringed in red for a couple of seconds and
   then fades back. An outline is used rather than a background so it cannot
   interfere with status colours, striping or anything set inline — an outline
   takes up no space and is drawn over the top.
   ========================================================================== */

@keyframes gdl-flash {
    0%   { outline-color: rgba(206, 18, 45, 0.00); outline-offset: 6px; }
    14%  { outline-color: rgba(206, 18, 45, 0.95); outline-offset: 1px; }
    70%  { outline-color: rgba(206, 18, 45, 0.75); outline-offset: 1px; }
    100% { outline-color: rgba(206, 18, 45, 0.00); outline-offset: 1px; }
}

html.gdl-motion .gdl-flash {
    outline: 2px solid rgba(206, 18, 45, 0);
    outline-offset: 1px;
    border-radius: 3px;
    animation: gdl-flash 2400ms var(--gdl-ease) 1;
}


/* ============================================================================
   7.  COUNTING UP, AND LIVE INDICATORS
   ========================================================================== */

/* Stops the figure jittering in width while it counts */
html.gdl-motion .gdl-counting {
    font-variant-numeric: tabular-nums;
}

/* A slow pulse for anything showing a live/online state. Applied automatically
   to online badges; add class="gdl-live" to anything else you want it on. */
@keyframes gdl-live {
    0%, 100% { opacity: 1;    }
    50%      { opacity: 0.45; }
}

html.gdl-motion .gdl-live::before {
    content: "";
    display: inline-block;
    width: 7px;
    height: 7px;
    margin-right: 6px;
    border-radius: 50%;
    background: currentColor;
    vertical-align: middle;
    animation: gdl-live 2000ms ease-in-out infinite;
}


/* ============================================================================
   8.  GET OUT OF THE WAY
   ----------------------------------------------------------------------------
   Anyone who has asked their machine for less movement gets none, and nothing
   is ever hidden or mid-animation on a printout.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {

    html.gdl-pre [class*="hero"],
    html.gdl-pre [class*="card"],
    html.gdl-pre [class*="-wrap"],
    html.gdl-pre [class*="page-header"],
    html.gdl-pre .container,
    html.gdl-pre .boxinside,
    html.gdl-pre welcome   > div,
    html.gdl-pre home      > div,
    html.gdl-pre services  > div,
    html.gdl-pre team      > div,
    html.gdl-pre portfolio > div,
    html.gdl-pre careers   > div,
    html.gdl-pre contact   > div,
    html.gdl-pre noaccess  > div,
    html.gdl-motion .gdl-r {
        opacity: 1 !important;
        transform: none !important;
    }

    html.gdl-motion .gdl-lift:hover { transform: none !important; }

    html.gdl-motion *,
    html.gdl-motion *::before,
    html.gdl-motion *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

@media print {

    html.gdl-pre [class*="hero"],
    html.gdl-pre [class*="card"],
    html.gdl-pre [class*="-wrap"],
    html.gdl-pre [class*="page-header"],
    html.gdl-pre .container,
    html.gdl-pre .boxinside,
    html.gdl-pre welcome   > div,
    html.gdl-pre home      > div,
    html.gdl-pre services  > div,
    html.gdl-pre team      > div,
    html.gdl-pre portfolio > div,
    html.gdl-pre careers   > div,
    html.gdl-pre contact   > div,
    html.gdl-pre noaccess  > div,
    html.gdl-motion .gdl-r {
        opacity: 1 !important;
        transform: none !important;
    }

    .gdl-progress { display: none !important; }

    html.gdl-motion .gdl-flash {
        outline: none !important;
        animation: none !important;
    }
}
