/* TSC custom styles */

/* Smooth scrolling */
html {
    scroll-behavior: smooth;
}

/* Reduce top spacing below fixed nav — half of default py-16 / lg:py-24 */
main > section:first-child {
    padding-top: 2rem;   /* 32px, half of 64px (py-16) */
}

@media (min-width: 1024px) {
    main > section:first-child {
        padding-top: 3rem; /* 48px, half of 96px (lg:py-24) */
    }
}

/* Nav shadow on scroll */
.nav-scrolled {
    box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
}

/* Topbar positioning */
.nav-topbar {
    height: 54px;
    transition: transform 0.3s ease;
}
.nav-topbar-inner {
    height: 54px;
}

/* Main nav follows topbar on lg+ */
@media (min-width: 1024px) {
    .nav-main {
        top: 54px;
        transition: top 0.3s ease, box-shadow 0.3s ease;
    }
    .nav-main.topbar-collapsed {
        top: 0;
    }
}

/* Topbar hide on scroll */
.nav-topbar.topbar-collapsed {
    transform: translateY(-100%);
}

/* Spacer responsive heights */
.nav-spacer {
    height: 64px;
}
@media (min-width: 1024px) {
    .nav-spacer {
        height: 118px;
    }
}

/* Hero 7-step circle animation */
.step-circle {
    translate: -50% -50%;
    opacity: 0;
    scale: 0.8;
    animation: stepAppear 0.5s ease-out forwards;
}

@keyframes stepAppear {
    to {
        opacity: 1;
        scale: 1;
    }
}

/* nth-child offset +2: child 1 = center logo, child 2 = arrow SVG */
.step-circle:nth-child(3)  { animation-delay: 0.2s; }
.step-circle:nth-child(4)  { animation-delay: 0.6s; }
.step-circle:nth-child(5)  { animation-delay: 1.0s; }
.step-circle:nth-child(6)  { animation-delay: 1.4s; }
.step-circle:nth-child(7)  { animation-delay: 1.8s; }
.step-circle:nth-child(8)  { animation-delay: 2.2s; }
.step-circle:nth-child(9)  { animation-delay: 2.6s; }

/* Arrow draw-in animation */
.step-arrow {
    fill: none;
    stroke: #8ebe21;
    stroke-width: 1.2;
    stroke-linecap: butt;
    stroke-dasharray: 200;
    stroke-dashoffset: 200;
    animation: drawArrow 0.4s ease-out forwards;
}

@keyframes drawArrow {
    to { stroke-dashoffset: 0; }
}

.step-arrow:nth-of-type(1) { animation-delay: 0.5s; }
.step-arrow:nth-of-type(2) { animation-delay: 0.9s; }
.step-arrow:nth-of-type(3) { animation-delay: 1.3s; }
.step-arrow:nth-of-type(4) { animation-delay: 1.7s; }
.step-arrow:nth-of-type(5) { animation-delay: 2.1s; }
.step-arrow:nth-of-type(6) { animation-delay: 2.5s; }

/* FAQ accordion */
.faq-answer {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
}

.faq-answer.open {
    max-height: 500px;
}

.faq-chevron {
    transition: transform 0.3s ease;
}

.faq-chevron.open {
    transform: rotate(180deg);
}

/* Reference logo grid hover */
.reference-logo {
    filter: grayscale(100%);
    opacity: 0.6;
    transition: all 0.3s ease;
}

.reference-logo:hover {
    filter: grayscale(0%);
    opacity: 1;
}

/* Reference card on /references: the whole card is the hover target, so the logo and its
   caption light up together. The caption is real text in the DOM (not a title attribute),
   which is what actually gets indexed - alt text only feeds image search. */
.logo-card:hover .reference-logo {
    filter: grayscale(0%);
    opacity: 1;
}

.reference-name {
    color: #9a9ea0;
    transition: color 0.3s ease;
}

.logo-card:hover .reference-name {
    color: #212529;
}

/* Homepage logo wall — "breathing grid": the grid itself never moves, each tile cross-fades
   through its own queue of logos (see Client/site/logo-wall.ts).
   `display: contents` is the graceful-degradation path for the no-JS case: every logo drops
   straight into the parent grid, so all of them render as a plain static wall. (Reduced motion
   deliberately does NOT take that path - see the media query at the bottom of this file.)
   Only when html.js is present does a tile become a positioned box stacking its frames. */
.logo-slot {
    display: contents;
}

/* in the fallback the frames are grid items themselves, so they need the breathing room the
   tile's own padding gave them (margin, not padding — padding would shrink the logo box) */
.logo-frame {
    margin: 0.5rem auto;
}

.js .logo-slot {
    position: relative;
    display: flex;
    min-height: 5rem;
}

.js .logo-frame {
    position: absolute;
    inset: 0;
    margin: auto;
    /* overrides `transition: all 0.3s` from .reference-logo so the swap is a slow cross-fade
       while the hover colour-in stays snappy */
    transition: opacity 0.6s ease, transform 0.6s ease, filter 0.3s ease;
}

/* the active frame keeps .reference-logo's own opacity (0.6) and hover behaviour */
.js .logo-frame:not(.is-active) {
    opacity: 0;
    transform: scale(0.96);
    pointer-events: none;
}

/* Scroll reveal animation — armed only when JS is present (html.js set inline in _Layout),
   so content stays visible for non-JS crawlers and when scripts fail to load */
.js .reveal {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

.js .reveal.visible {
    opacity: 1;
    transform: translateY(0);
}

/* Timeline */
.timeline-line {
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    background: #e8e8e8;
    transform: translateX(-50%);
}

@media (max-width: 768px) {
    .timeline-line {
        left: 20px;
    }
}

/* Contact form focus styles */
.form-input:focus {
    outline: none;
    border-color: #8ebe21;
    box-shadow: 0 0 0 3px rgba(142, 190, 33, 0.15);
}

@keyframes tsc-pulse-1 {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.2); }
}

@keyframes tsc-pulse-2 {
    0%, 100% { transform: scale(1); }
    33% { transform: scale(0.85); }
    66% { transform: scale(1.15); }
}

/* ── Explainer film ─────────────────────────────────────────────────────────
   The cover replaces the film's own first frame with something of ours: logo,
   play button, name and running time. It is drawn only under `.js`, because a
   cover that hides the native controls without being able to start playback
   would be a dead end - with scripting off the visitor gets the plain <video>
   with its poster, which plays on its own. */
.film-frame {
    position: relative;
    border-radius: 1rem;
    overflow: hidden;
    background: #0C0F0D;
    box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
}
.film-video {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    background: #0C0F0D;
}

.film-cover {
    display: none;
}
.js .film-cover {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1.5rem;
    border: 0;
    cursor: pointer;
    text-align: center;
    /* The film's own ground. The green stays in the button, not in the backdrop -
       a wash behind it only turns the black olive and swallows the button. */
    background:
        radial-gradient(75% 60% at 50% 42%, rgb(142 190 33 / 0.09), transparent 72%),
        #0C0F0D;
    transition: opacity 0.3s ease, visibility 0s 0.3s;
}
.film-frame.is-playing .film-cover {
    opacity: 0;
    visibility: hidden;
}
.film-cover:focus-visible {
    outline: 3px solid #8ebe21;
    outline-offset: -3px;
}

.film-cover-logo {
    position: absolute;
    top: 1.75rem;
    left: 1.75rem;
    height: 2rem;
    width: auto;
    opacity: 0.85;
    filter: brightness(0) invert(1);
}

.film-play {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 5.25rem;
    height: 5.25rem;
    margin-bottom: 1.25rem;
    border-radius: 9999px;
    background: #8ebe21;
    color: #0C0F0D;
    box-shadow: 0 10px 30px rgb(0 0 0 / 0.55), 0 0 0 0 rgb(142 190 33 / 0.5);
    animation: film-ring 2.6s ease-out infinite;
    transition: transform 0.25s ease, background-color 0.25s ease;
}
.film-play svg {
    width: 2.25rem;
    height: 2.25rem;
    margin-left: 0.2rem;   /* optical centre - the triangle's mass sits left */
}
.film-cover:hover .film-play,
.film-cover:focus-visible .film-play {
    transform: scale(1.08);
    background: #9fd12a;
}

.film-cover-name {
    color: #fff;
    font-size: clamp(1.05rem, 1.7vw, 1.7rem);
    font-weight: 600;
    line-height: 1.3;
    max-width: 28ch;
}
.film-cover-meta {
    color: #8ebe21;
    font-size: clamp(0.62rem, 0.78vw, 0.78rem);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

@media (max-width: 640px) {
    .js .film-cover { gap: 0.3rem; padding: 0.9rem; }
    .film-cover-logo { top: 0.8rem; left: 0.9rem; height: 1rem; }
    .film-play { width: 3rem; height: 3rem; margin-bottom: 0.7rem; }
    .film-play svg { width: 1.3rem; height: 1.3rem; }
    .film-cover-name { font-size: 0.9rem; }
    .film-cover-meta { font-size: 0.58rem; letter-spacing: 0.1em; }
}

@keyframes film-ring {
    0%   { box-shadow: 0 10px 30px rgb(0 0 0 / 0.55), 0 0 0 0 rgb(142 190 33 / 0.5); }
    70%  { box-shadow: 0 10px 30px rgb(0 0 0 / 0.55), 0 0 0 1.6rem rgb(142 190 33 / 0); }
    100% { box-shadow: 0 10px 30px rgb(0 0 0 / 0.55), 0 0 0 0 rgb(142 190 33 / 0); }
}

/* Loading spinner for forms */
.spinner {
    display: inline-block;
    width: 16px;
    height: 16px;
    border: 2px solid rgba(255, 255, 255, 0.3);
    border-radius: 50%;
    border-top-color: white;
    animation: spin 0.6s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* --- 3D yard hotspots -----------------------------------------------------
   Markers are DOM buttons floating over the canvas; yard3d-hotspots.ts writes
   their transform every frame, so the centring is done with margins instead —
   a translate(-50%, -50%) here would be overwritten on the next frame. */
.yard3d-stage {
    aspect-ratio: 5 / 2;
}

.yard3d-marker {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    width: 44px;
    height: 44px;
    margin: -22px 0 0 -22px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
    /* The scene is redrawn underneath continuously; letting the browser keep
       these on their own layer stops a full repaint on every frame. */
    will-change: transform;
}

.yard3d-marker[hidden] {
    display: none;
}

/* Belt and braces: the script hides the markers until it has projected them,
   but it only runs once the scene mounts. Without this they would pile up in
   the corner of an empty box on any client where the mount never happens. */
#tsc-yard-3d:not([data-state="ready"]) .yard3d-marker {
    display: none;
}

.yard3d-marker-dot,
.yard3d-marker-dot::before {
    position: absolute;
    border-radius: 50%;
    content: '';
}

/* The pulsing halo. */
.yard3d-marker-dot {
    left: 50%;
    top: 50%;
    width: 24px;
    height: 24px;
    margin: -12px 0 0 -12px;
    background: #8ebe21;
    opacity: 0.5;
    animation: tsc-pulse-1 3s ease-in-out infinite;
}

.yard3d-marker:nth-of-type(even) .yard3d-marker-dot {
    animation: tsc-pulse-2 4s ease-in-out infinite;
}

/* The solid centre, which does not pulse — it is inside the halo, so it would
   inherit the scale otherwise. */
.yard3d-marker-dot::before {
    left: 50%;
    top: 50%;
    width: 10px;
    height: 10px;
    margin: -5px 0 0 -5px;
    background: #ffffff;
    transition: background-color 0.2s ease;
}

.yard3d-marker:hover .yard3d-marker-dot,
.yard3d-marker.active .yard3d-marker-dot,
.yard3d-marker.hint .yard3d-marker-dot {
    background: #fcd200;
    opacity: 0.7;
    animation: none;
}

.yard3d-marker:hover .yard3d-marker-dot::before,
.yard3d-marker.active .yard3d-marker-dot::before,
.yard3d-marker.hint .yard3d-marker-dot::before {
    background: #fcd200;
}

.yard3d-marker:focus-visible {
    outline: 2px solid #008ad1;
    outline-offset: 2px;
    border-radius: 50%;
}

/* The card. Same shape as the one on the 2D illustration. */
.yard3d-popup {
    position: absolute;
    bottom: 1rem;
    left: 1rem;
    z-index: 3;
    max-width: 24rem;
    padding: 1.5rem;
    border: 1px solid #e8e8e8;
    border-radius: 1rem;
    background: #ffffff;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 8px 10px -6px rgba(0, 0, 0, 0.1);
}

/* Moved aside when the marker that opened it sits in the same corner. */
.yard3d-popup.yard3d-popup-right {
    left: auto;
    right: 1rem;
}

.yard3d-popup[hidden] {
    display: none;
}

.yard3d-popup-close {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border: 0;
    border-radius: 50%;
    background: none;
    color: #707476;
    cursor: pointer;
}

.yard3d-popup-close:hover {
    background: #f3f4f6;
}

.yard3d-popup-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
    /* Room for the close button. */
    padding-right: 2rem;
}

.yard3d-popup-dot {
    flex: 0 0 auto;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: 50%;
}

.yard3d-popup-title {
    font-size: 1.125rem;
    font-weight: 700;
    color: #212529;
}

.yard3d-popup-desc {
    font-size: 0.875rem;
    line-height: 1.625;
    color: #707476;
}

/* The modules with no hardware in the yard. */
.yard3d-rail {
    display: none;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 1rem;
}

#tsc-yard-3d[data-state="ready"] ~ .yard3d-rail {
    display: flex;
}

.yard3d-chip {
    padding: 0.375rem 0.875rem;
    border: 1px solid #e8e8e8;
    border-radius: 999px;
    background: #ffffff;
    font-size: 0.8125rem;
    color: #707476;
    cursor: pointer;
    transition: border-color 0.2s ease, color 0.2s ease;
}

.yard3d-chip:hover,
.yard3d-chip.active {
    border-color: #8ebe21;
    color: #212529;
}

.yard3d-chip:focus-visible {
    outline: 2px solid #008ad1;
    outline-offset: 2px;
}

@media (max-width: 767px) {
    .yard3d-stage {
        aspect-ratio: 4 / 3;
    }
}

