/*
 * Polish and motion. Loaded after site.css.
 *
 * Smoothness rules this file follows:
 *  - Animate only transform and opacity; those run on the compositor. Shadows are
 *    pre-drawn on a pseudo-element and faded in, never transitioned directly.
 *  - One easing curve everywhere (--swd-ease), a decelerating one with no overshoot.
 *  - Reveal state is removed once it has played (see site.js), so it never leaves
 *    a stagger delay or will-change behind to slow later hover transitions.
 */
:root {
    --swd-ease: cubic-bezier(.22, 1, .36, 1);
    --swd-fast: .22s;
    --swd-med: .4s;
    --swd-slow: .7s;
}

html { scroll-behavior: smooth; scroll-padding-top: 4.5rem; }
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
::selection { background: var(--swd-amber); color: var(--swd-on-amber); }

/* Sticky nav: the shadow sits on a pseudo-element and fades in on scroll */
.swd-nav { position: sticky; top: 0; z-index: 1030; }
.swd-nav::after {
    content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; pointer-events: none;
    box-shadow: 0 8px 22px 0 rgba(43, 27, 18, .22); opacity: 0; transition: opacity var(--swd-med) var(--swd-ease);
}
.swd-nav.is-scrolled::after { opacity: 1; }
.swd-nav .nav-link { position: relative; color: var(--swd-ink); }
.swd-nav .nav-link::after {
    content: ""; position: absolute; left: .5rem; right: .5rem; bottom: .25rem; height: 2px;
    background: var(--swd-orange-text); transform: scaleX(0); transform-origin: left; transition: transform var(--swd-med) var(--swd-ease);
}
.swd-nav .nav-link:hover::after, .swd-nav .nav-link:focus-visible::after { transform: scaleX(1); }
/* The five dots turn one place round the roundabout on hover, landing exactly where they started. */
.swd-logo-dots { transition: transform .9s var(--swd-ease); }
.swd-brand:hover .swd-logo-dots, .swd-brand:focus-visible .swd-logo-dots { transform: rotate(72deg); }

/* Buttons: the lift is a transform, the glow is a faded pseudo-element */
.btn { position: relative; isolation: isolate; transition: transform var(--swd-fast) var(--swd-ease), background-color var(--swd-fast) ease, color var(--swd-fast) ease, border-color var(--swd-fast) ease; }
.btn::after {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    box-shadow: 0 10px 20px -10px rgba(194, 65, 12, .6); opacity: 0; transition: opacity var(--swd-fast) ease;
}
.btn:hover { transform: translateY(-2px); }
.btn:hover::after { opacity: 1; }
.btn:active { transform: translateY(0); transition-duration: .08s; }
.btn:focus-visible, a:focus-visible { outline: 3px solid rgba(255, 179, 0, .7); outline-offset: 2px; }
.btn i { display: inline-block; transition: transform var(--swd-med) var(--swd-ease); }
.btn:hover .fa-paper-plane { transform: translate(3px, -3px) rotate(8deg); }
.btn:hover .fa-comment, .btn:hover .fa-phone { transform: rotate(-10deg) scale(1.08); }
.btn[disabled] { pointer-events: none; opacity: .85; }

/* Cards lift; their shadow fades in rather than animating */
.swd-svc, .swd-q { position: relative; isolation: isolate; transition: transform var(--swd-med) var(--swd-ease), border-color var(--swd-med) ease; }
.swd-svc::after, a.swd-q::after {
    content: ""; position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
    box-shadow: 0 16px 28px -18px rgba(43, 27, 18, .5); opacity: 0; transition: opacity var(--swd-med) var(--swd-ease);
}
.swd-svc:hover { transform: translateY(-4px); border-color: var(--swd-line-strong); }
.swd-svc:hover::after, a.swd-q:hover::after { opacity: 1; }
.swd-svc .swd-ic { transition: transform var(--swd-med) var(--swd-ease), background-color var(--swd-med) ease, color var(--swd-med) ease; }
.swd-svc:hover .swd-ic { transform: scale(1.1) rotate(-6deg); background: var(--swd-orange); color: #fff; }
a.swd-q:hover { transform: translateX(4px); }
a.swd-q i { transition: transform var(--swd-med) var(--swd-ease); }
a.swd-q:hover i { transform: translateX(4px); }
.swd-n { transition: transform var(--swd-med) var(--swd-ease); }
.swd-step:hover .swd-n { transform: scale(1.12); }
.swd-contact a { text-decoration: none; background: linear-gradient(currentColor, currentColor) 0 100% / 0 1px no-repeat; transition: background-size var(--swd-med) var(--swd-ease); }
.swd-contact a:hover { background-size: 100% 1px; }

/* Form fields and states */
.form-control { transition: border-color var(--swd-fast) ease, box-shadow var(--swd-fast) ease; }
.form-control:hover { border-color: var(--swd-input-hover); }
.form-control.is-invalid-soft { border-color: #b3261e; animation: swd-shake .4s var(--swd-ease); }
#form-alert:not(.d-none) { animation: swd-pop var(--swd-med) var(--swd-ease); }
.swd-spinner { display: inline-block; width: 1em; height: 1em; margin-right: .5rem; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; vertical-align: -.125em; animation: swd-spin .7s linear infinite; }

@keyframes swd-pop { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }
@keyframes swd-shake { 20% { transform: translateX(-4px); } 40% { transform: translateX(4px); } 60% { transform: translateX(-2px); } 80% { transform: translateX(2px); } }
@keyframes swd-spin { to { transform: rotate(360deg); } }
@keyframes swd-rise { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes swd-float { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(0, -8px, 0); } }

/* Hero entrance, then a slow float on the quote card (only when JS is present) */
.js .swd-hero .swd-tag, .js .swd-hero h1, .js .swd-hero .lead, .js .swd-hero .d-flex, .js .swd-hero .swd-ticks {
    opacity: 0; animation: swd-rise var(--swd-slow) var(--swd-ease) both;
}
.js .swd-hero h1 { animation-delay: .08s; }
.js .swd-hero .lead { animation-delay: .16s; }
.js .swd-hero .d-flex { animation-delay: .24s; }
.js .swd-hero .swd-ticks { animation-delay: .32s; }
/* The entrance is on the column and the float is on the card inside it, so no element ever has two
   animations fighting over its transform. The float starts the instant the entrance ends (.2s + .9s),
   and runs back and forth on a sine-shaped curve so it never stops and starts at the extremes. */
.js .swd-hero .col-lg-5 { opacity: 0; animation: swd-rise .9s .2s var(--swd-ease) both; }
.swd-hero .swd-card { will-change: transform; backface-visibility: hidden; animation: swd-float 3.6s 1.1s cubic-bezier(.37, 0, .63, 1) infinite alternate; }
.swd-hero { position: relative; overflow: hidden; }
.swd-hero::before {
    content: ""; position: absolute; width: 640px; height: 640px; right: -160px; top: -220px; border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 179, 0, .28), rgba(255, 179, 0, 0) 70%); pointer-events: none;
}
.swd-hero .container { position: relative; }
.swd-ticks i { display: inline-block; transition: transform var(--swd-med) var(--swd-ease); }
.swd-ticks li:hover i { transform: scale(1.25); }

/* Scroll reveal: hidden only when JS has run; site.js removes .reveal once it has played */
.js .reveal { opacity: 0; transform: translateY(24px); will-change: opacity, transform; transition: opacity var(--swd-slow) var(--swd-ease), transform var(--swd-slow) var(--swd-ease); transition-delay: var(--d, 0s); }
.js .reveal.is-visible { opacity: 1; transform: none; }

.swd-band b { font-variant-numeric: tabular-nums; }

/* Respect people who ask for less motion */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-duration: .001ms !important; transition-delay: 0s !important; }
    .js .reveal, .js .swd-hero .swd-tag, .js .swd-hero h1, .js .swd-hero .lead, .js .swd-hero .d-flex, .js .swd-hero .swd-ticks, .js .swd-hero .col-lg-5 { opacity: 1; transform: none; }
}
