/*
 * The shell every page shares: base type, the header with its phone menu,
 * the footer, buttons, the page head over the Beams, and motion. Every value
 * comes from tokens.css. The breakpoints are --breakpoint-sm (40rem),
 * --breakpoint-md (48rem) and --breakpoint-lg (56.25rem).
 *
 * Motion runs only with prefers-reduced-motion: no-preference, so a system
 * set to reduce motion gets none of it: no page transitions, reveals, moving
 * beams or progress line.
 */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/* The scrollbar's space is kept on every page, so going from a short page to a
   long one doesn't move the header sideways. */
html {
    block-size: 100%;
    scrollbar-gutter: stable;
    /* A link to a part of a page lands below the sticky header, not under it. */
    scroll-padding-block-start: var(--space-20);
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    display: flex;
    flex-direction: column;
    min-block-size: 100%;
    margin: 0;
    background: var(--background);
    color: var(--foreground);
    font-family: var(--font-sans);
    font-size: var(--text-body);
    line-height: var(--leading-normal);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

main {
    flex: 1;
}

/* Tomorrow at its medium weight; a heading asking for more takes the
   heaviest loaded, never a bold the browser makes up. */
h1,
h2,
h3 {
    font-family: var(--font-heading);
    line-height: var(--leading-tight);
    font-weight: var(--weight-medium);
    font-synthesis: none;
    text-wrap: balance;
}

img,
svg {
    display: block;
    max-inline-size: 100%;
}

a {
    color: inherit;
}

:focus-visible {
    outline: var(--focus-width) solid var(--ring);
    outline-offset: var(--focus-offset);
}

.wrap {
    max-inline-size: var(--container-6xl);
    margin-inline: auto;
    padding-inline: var(--space-4);
}

/* Above the sticky header, which it sits over when focused. */
.skip-link {
    position: absolute;
    z-index: calc(var(--z-header) + var(--z-raised));
    inset-block-start: var(--space-2);
    inset-inline-start: var(--space-2);
    padding-block: var(--space-2);
    padding-inline: var(--space-4);
    border-radius: var(--radius-md);
    background: var(--primary);
    color: var(--primary-foreground);
    font-weight: var(--weight-medium);
}

.skip-link:not(:focus) {
    clip-path: inset(50%);
}

.icon {
    inline-size: var(--icon-size);
    block-size: var(--icon-size);
    flex: none;
}

/* Words kept on one line, such as Dallas–Fort Worth. */
.nw {
    white-space: nowrap;
}

/* ---- Header ---- */

/* Sticky, frosted over what scrolls under it. Named for view transitions, so
   it holds still while the page under it cross-fades. */
.site-header {
    position: sticky;
    inset-block-start: 0;
    z-index: var(--z-header);
    border-block-end: var(--border-width) solid var(--border);
    background: color-mix(in srgb, var(--background) 84%, transparent);
    backdrop-filter: saturate(1.5) blur(var(--blur-md));
    view-transition-name: site-header;
}

.site-header .wrap {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    min-block-size: var(--space-16);
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    min-block-size: var(--tap-target);
    text-decoration: none;
}

/* The wordmark SVG, --logo-height tall, in its own white and Neon. */
.brand-logo {
    inline-size: auto;
    block-size: var(--logo-height);
}

.menu-button,
.menu-close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-block-size: var(--tap-target);
    min-inline-size: var(--tap-target);
    padding-inline: var(--space-3);
    border: var(--border-width) solid var(--border);
    border-radius: var(--radius-md);
    background: var(--background);
    color: var(--foreground);
    font: inherit;
    font-size: var(--text-sm);
    font-weight: var(--weight-medium);
    box-shadow: var(--shadow-xs);
    cursor: pointer;
}

/* Up to --breakpoint-lg the nav is a popover: a drawer from the start edge,
   with Book a consultation, Neon, under the links. */
.site-nav {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    inset-inline-end: auto;
    inline-size: min(var(--container-xs), calc(100% - var(--space-12)));
    block-size: auto;
    margin: 0;
    padding: var(--space-4);
    border: 0;
    border-inline-end: var(--border-width) solid var(--border);
    background: var(--background);
    color: var(--foreground);
    box-shadow: var(--shadow-sm);
}

.site-nav::backdrop {
    background: var(--overlay);
}

.menu-close {
    margin-block-end: var(--space-4);
    margin-inline-start: auto;
}

.site-nav:popover-open {
    display: flex;
    flex-direction: column;
}

.site-nav ul {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-nav ul a {
    display: flex;
    align-items: center;
    min-block-size: var(--tap-target);
    min-inline-size: var(--tap-target);
    padding-inline: var(--space-3);
    border-radius: var(--radius-md);
    color: var(--muted-foreground);
    font-weight: var(--weight-medium);
    text-decoration: none;
}

.site-nav ul a:hover,
.site-nav ul a[aria-current="page"] {
    color: var(--foreground);
}

.site-nav ul a[aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: var(--focus-width);
    text-underline-offset: var(--space-2);
}

.site-nav .button {
    margin-block-start: var(--space-4);
}

@media (min-width: 48rem) {
    .wrap {
        padding-inline: var(--space-8);
    }
}

@media (min-width: 56.25rem) {
    .menu-button,
    .menu-close {
        display: none;
    }

    /* From --breakpoint-lg the popover is always shown, inline in the bar. */
    .site-nav {
        display: flex;
        align-items: center;
        gap: var(--space-6);
        position: static;
        inset: auto;
        inline-size: auto;
        padding: 0;
        border: 0;
        background: none;
        box-shadow: none;
        overflow: visible;
    }

    .site-nav ul {
        flex-direction: row;
    }

    .site-nav ul a {
        font-size: var(--text-ui);
    }

    /* Beside the links, outlined and a tap target tall, so the page's own
       Neon button stays the loudest. */
    .site-nav .button {
        min-block-size: var(--tap-target);
        margin: 0;
        padding-inline: var(--space-4);
        border-color: var(--border-strong);
        background: transparent;
        color: var(--foreground);
        font-weight: var(--weight-medium);
    }

    .site-nav .button:hover {
        border-color: var(--muted-foreground);
        background: transparent;
    }
}

/* ---- Footer ---- */

/* The one-line description, three columns of links, a base line with
   © Logixcel LLC, then the Logixcel name across the whole container, fading
   out at the bottom. At phone width Company and Policies share a row and Get
   in touch takes the next, so the address fits; from --breakpoint-lg the
   description and the columns share one row. */
.site-footer {
    margin-block-start: var(--space-16);
    border-block-start: var(--border-width) solid var(--border);
    background: var(--background);
    color: var(--muted-foreground);
    font-size: var(--text-base);
}

.site-footer .wrap {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-8) var(--space-6);
    padding-block-start: var(--space-16);
}

.footer-brand,
.footer-contact,
.footer-base,
.footer-name {
    grid-column: 1 / -1;
}

.footer-brand {
    max-inline-size: var(--container-xs);
    margin: 0;
    color: var(--foreground);
    font-size: var(--text-body);
    text-wrap: balance;
}

.footer-col h2 {
    margin-block: 0 var(--space-1);
    color: var(--foreground);
    font-size: var(--text-base);
}

.footer-col ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.site-footer a {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--tap-target);
    min-inline-size: var(--tap-target);
    color: var(--muted-foreground);
    text-decoration: none;
    text-underline-offset: var(--space-1);
}

.site-footer a:hover,
.site-footer a[aria-current="page"] {
    color: var(--foreground);
}

.site-footer a[aria-current="page"] {
    text-decoration: underline;
    text-decoration-thickness: var(--focus-width);
}

.footer-base {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-2) var(--space-6);
    padding-block-start: var(--space-5);
    border-block-start: var(--border-width) solid var(--border);
}

.footer-base p {
    margin: 0;
}

/* The wordmark, faint, fading out towards the bottom. A mask reads only alpha. */
.footer-name {
    opacity: 0.2;
    mask-image: linear-gradient(var(--foreground) 40%, transparent);
}

.footer-name img {
    inline-size: 100%;
    block-size: auto;
}

@media (min-width: 40rem) {
    .site-footer .wrap {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .footer-contact {
        grid-column: auto;
    }
}

/* Columns as wide as their longest word at least, so the address never
   spills out of its own. */
@media (min-width: 56.25rem) {
    .site-footer .wrap {
        grid-template-columns: minmax(0, 2fr) repeat(3, 1fr);
    }

    .footer-brand {
        grid-column: auto;
    }
}

/* ---- Buttons ---- */

/* The one button to press is Neon, as in the logo's L: tall, tight-cornered
   and semibold. A clear border keeps it the size of an outlined one. */
.button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-block-size: var(--button-height);
    padding-inline: var(--space-6);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-sm);
    background: var(--primary);
    color: var(--primary-foreground);
    font-size: var(--text-ui);
    font-weight: var(--weight-semibold);
    line-height: var(--leading-none);
    text-decoration: none;
}

.button:hover {
    background: var(--primary-hover);
}

/* ---- Page head: a Neon kicker, a large Tomorrow title and a muted lead
   over the Beams ---- */

.page-head {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.page-head .wrap {
    padding-block: var(--space-14) var(--space-6);
}

.kicker {
    margin: 0;
    color: var(--green-text);
    font-size: var(--text-ui);
    font-weight: var(--weight-semibold);
}

.page-head h1 {
    margin-block: var(--space-3) 0;
    font-size: var(--text-display-md);
    line-height: var(--leading-display);
    letter-spacing: var(--tracking-heading);
}

.lead {
    /* 46ch, never wider than a column of text, in the system sans too. */
    max-inline-size: min(var(--measure), var(--container-2xl));
    margin-block: var(--space-5) 0;
    color: var(--muted-foreground);
    font-size: var(--text-lead);
    line-height: var(--leading-relaxed);
    text-wrap: pretty;
}

.page-head .button {
    margin-block-start: var(--space-8);
}

@media (min-width: 40rem) {
    .page-head .wrap {
        padding-block: var(--space-20) var(--space-9);
    }
}

/* The Beams: a faint grid, a soft glow, and lights running down the grid
   lines. Behind the text and deaf to the pointer; aria-hidden in the page.
   All of it fades out towards the bottom, so nothing ends on a hard edge.
   A mask reads only alpha. */
.beams {
    position: absolute;
    inset: 0;
    z-index: var(--z-behind);
    overflow: hidden;
    pointer-events: none;
    mask-image: linear-gradient(to bottom, var(--foreground) 60%, transparent);
}

/* The grid, gone by the lower part. */
.beams::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(var(--grid-line) var(--border-width), transparent var(--border-width)),
        linear-gradient(to right, var(--grid-line) var(--border-width), transparent var(--border-width));
    background-size: var(--space-11) var(--space-11);
    background-position: calc(var(--border-width) * -1) calc(var(--border-width) * -1);
    mask-image: linear-gradient(to bottom, var(--foreground) 35%, transparent 95%);
}

/* The glow, off the top end corner at any height: a block margin in % is
   a share of the width, as the glow's size is. Faint enough that the lead
   keeps AA where the glow drifts behind it. */
.beams::after {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline-end: -14%;
    inline-size: 64%;
    aspect-ratio: 1;
    margin-block-start: -20%;
    border-radius: var(--radius-full);
    background: radial-gradient(circle, color-mix(in srgb, var(--primary) 60%, transparent), transparent 68%);
    opacity: 0.3;
}

/* A beam: a line that brightens to a green head. Shown only while it moves. */
.beams i {
    display: none;
    position: absolute;
    inset-block-start: 0;
    inline-size: var(--border-width);
    block-size: calc(var(--space-12) * 3);
    background: linear-gradient(transparent, color-mix(in srgb, var(--primary) 85%, transparent));
    translate: 0 -100%;
}

.beams i::after {
    content: "";
    position: absolute;
    inset-block-end: calc(var(--space-1-5) / -2);
    inset-inline-start: calc((var(--border-width) - var(--space-1-5)) / 2);
    inline-size: var(--space-1-5);
    aspect-ratio: 1;
    border-radius: var(--radius-full);
    background: var(--green);
    filter: drop-shadow(0 0 var(--space-2) var(--green));
}

/* Each on a grid line at any width, spread across the head. */
.beams i:nth-child(1) { inset-inline-start: calc(round(down, 7%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(2) { inset-inline-start: calc(round(down, 19%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(3) { inset-inline-start: calc(round(down, 31%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(4) { inset-inline-start: calc(round(down, 44%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(5) { inset-inline-start: calc(round(down, 56%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(6) { inset-inline-start: calc(round(down, 69%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(7) { inset-inline-start: calc(round(down, 81%, var(--space-11)) - var(--border-width)); }
.beams i:nth-child(8) { inset-inline-start: calc(round(down, 93%, var(--space-11)) - var(--border-width)); }

/* ---- Motion ---- */

/* Reveal: add .reveal to a section and it rises in as it scrolls into view,
   driven by the scroll with no script. Where scroll-driven animations aren't
   supported, it is simply there. */
@keyframes reveal {
    from {
        opacity: 0;
        translate: 0 var(--space-9);
        scale: 0.98;
    }
}

/* The reading progress, a line along the bottom of the header. */
@keyframes scroll-progress {
    to {
        scale: 1;
    }
}

@keyframes page-out {
    to {
        opacity: 0;
        translate: 0 calc(var(--space-2) * -1);
    }
}

@keyframes page-in {
    from {
        opacity: 0;
        translate: 0 var(--space-4);
    }
}

@keyframes beam-fall {
    70%,
    to {
        translate: 0 calc(var(--space-32) * 9);
    }
}

@keyframes glow-drift {
    to {
        translate: -16% 14%;
        scale: 1.14;
    }
}

@media (prefers-reduced-motion: no-preference) {
    a,
    .button {
        transition:
            color var(--duration-fast) var(--ease-standard),
            background-color var(--duration-fast) var(--ease-standard);
    }

    /* Going from page to page cross-fades the content; the header, captured
       on its own, shows the new page's at once and doesn't move. */
    @view-transition {
        navigation: auto;
    }

    ::view-transition-old(root) {
        animation: page-out var(--duration-base) var(--ease-out) both;
    }

    ::view-transition-new(root) {
        animation: page-in var(--duration-slow) var(--ease-out) both;
    }

    ::view-transition-old(site-header) {
        display: none;
    }

    ::view-transition-new(site-header) {
        animation: none;
    }

    .beams::after {
        animation: glow-drift var(--duration-drift) var(--ease-in-out) infinite alternate;
    }

    .beams i {
        display: block;
        animation: beam-fall var(--duration-loop-slow) var(--ease-in-out) infinite;
    }

    /* Two speeds and staggered starts, so the beams never fall in step. */
    .beams i:nth-child(even) {
        animation-duration: var(--duration-demo);
    }

    .beams i:nth-child(2) { animation-delay: var(--duration-loop); }
    .beams i:nth-child(3) { animation-delay: var(--duration-slowest); }
    .beams i:nth-child(4) { animation-delay: calc(var(--duration-loop) + var(--duration-loop)); }
    .beams i:nth-child(5) { animation-delay: calc(var(--duration-loop) + var(--duration-loop-fast)); }
    .beams i:nth-child(6) { animation-delay: var(--duration-loop-fast); }
    .beams i:nth-child(7) { animation-delay: calc(var(--duration-loop) + var(--duration-loop) + var(--duration-loop-fast)); }
    .beams i:nth-child(8) { animation-delay: var(--duration-slower); }

    @supports (animation-timeline: view()) {
        .reveal {
            animation: reveal linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 55%;
        }
    }

    @supports (animation-timeline: scroll()) {
        .site-header::after {
            content: "";
            position: absolute;
            inset-inline: 0;
            inset-block-end: calc(var(--border-width) * -1);
            block-size: calc(var(--border-width) * 2);
            background: var(--primary);
            /* Empty until there's somewhere to scroll. */
            scale: 0 1;
            transform-origin: 0 50%;
            animation: scroll-progress linear both;
            animation-timeline: scroll(root);
        }

        .site-header:dir(rtl)::after {
            transform-origin: 100% 50%;
        }
    }
}
