/* =====================================================================
   WMS - Network atmosphere, mobile app shell, landing page v2
   ---------------------------------------------------------------------
   Three things live here, and nothing else:

     1. The "this is an internet system" atmosphere - a slow dot field, a
        pair of drifting waves and a signal bloom, painted behind the page
        rather than on top of it. Motion is slow enough to read against.
     2. The mobile application shell - a fixed bottom tab bar and a fixed
        primary-action bar, so a phone gets thumb-reachable navigation
        instead of a scroll to the footer.
     3. The rebuilt public page: an asymmetric hero with a live network
        map, a ticker, a numbered rail and a bento grid - deliberately not
        the hero / three-cards / pricing / CTA stack every template uses.

   Everything obeys prefers-reduced-motion. Nothing here is decoration
   that carries meaning: if the animation never ran, the page still reads.
   ===================================================================== */

:root {
    --wms-tabbar-h:  60px;
    --wms-safe-b:    env(safe-area-inset-bottom, 0px);
    --wms-actionbar: 0px;

    --net-cyan:      #4ed7f1;
    --net-cyan-dim:  rgba(78, 215, 241, .16);
    --net-deep:      #06111a;
}

/* Anchor navigation glides rather than jumps. This is the whole of the
   smooth-scrolling implementation: the browser's own, on the document.
   Nothing here hijacks the wheel or drives scrolling from JavaScript -
   that costs the reader their momentum, their scrollbar and their
   accessibility settings, and it always feels wrong on a trackpad. */
html { scroll-behavior: smooth; }

/* The header floats over the page, so a section scrolled to the very top
   would begin underneath it. Every anchor target keeps the header's height
   clear above itself. */
:target { scroll-margin-top: 5.25rem; }
body.wms-public section[id] { scroll-margin-top: 5.25rem; }

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
}

/* The backdrop lives in a fixed layer behind the page. A body with its own
   opaque background would paint straight over it, so the base colour moves
   up to the root element and every shell keeps a transparent body. */
html { background: var(--wms-canvas); }
body.wms-admin,
body.wms-public,
body.wms-portal,
body.wms-auth { background: transparent; }

/* =====================================================================
   1. ATMOSPHERE
   ===================================================================== */

/* The backdrop sits behind everything in its own layer.
   z-index:-1 puts it under the page's content but still over the canvas
   colour, which is why the base colour lives on <html> and every body is
   transparent. Lifting the content instead - body > * { z-index: 1 } - was
   tried first and quietly broke position:fixed on the bottom bars, because
   that selector also matched them and forced position:relative. */
.net-bg {
    position: fixed;
    inset: 0;
    z-index: -1;
    overflow: hidden;
    pointer-events: none;
    contain: strict;
}

/* A backdrop scoped to one band of the page rather than the whole viewport,
   so a dark hero keeps its own atmosphere while the page around it stays
   light. It sits inside that band's own stacking context, so it paints over
   the band's background and under its content. Size containment is dropped:
   this one is sized by its parent. */
.net-bg--inline { position: absolute; z-index: 0; contain: layout paint; }

.net-bg__layer { position: absolute; inset: -10%; }

/* --- the dot field: a network of nodes, drifting very slowly ---------- */
.net-bg__dots {
    background-image: radial-gradient(circle at center, rgba(10, 110, 133, .16) 1.1px, transparent 1.2px);
    background-size: 26px 26px;
    animation: net-drift 60s linear infinite;
    opacity: .85;
}
.net-bg__dots--fine {
    background-image: radial-gradient(circle at center, rgba(10, 110, 133, .10) 1px, transparent 1.1px);
    background-size: 9px 9px;
    animation: net-drift 90s linear infinite reverse;
    opacity: .5;
}
@keyframes net-drift {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-26px, -26px, 0); }
}

/* --- the signal bloom: two soft radial sources, breathing ------------- */
.net-bg__bloom {
    background:
        radial-gradient(38rem 26rem at 12% -6%, rgba(78, 215, 241, .20), transparent 62%),
        radial-gradient(32rem 24rem at 92% 8%,  rgba(10, 110, 133, .14), transparent 60%);
    animation: net-breathe 18s ease-in-out infinite;
}
@keyframes net-breathe {
    0%, 100% { opacity: .85; transform: scale(1); }
    50%      { opacity: 1;   transform: scale(1.06); }
}

/* --- the waves: three bands sliding at different speeds --------------- */
.net-bg__waves {
    position: absolute;
    left: -50%;
    right: -50%;
    bottom: 0;
    height: 46vh;
    min-height: 260px;
}
.net-bg__wave {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 200%;
    height: 100%;
    background-repeat: repeat-x;
    background-position: 0 bottom;
    background-size: 50% 100%;
    will-change: transform;
}
.net-bg__wave--1 {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 220' preserveAspectRatio='none'%3E%3Cpath d='M0 120c120-52 240-52 360 0s240 52 360 0 240-52 360 0 240 52 360 0v100H0z' fill='%234ed7f1' fill-opacity='.10'/%3E%3C/svg%3E");
    animation: net-wave 26s linear infinite;
}
.net-bg__wave--2 {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 220' preserveAspectRatio='none'%3E%3Cpath d='M0 150c150-60 300 40 450 0s300-70 450-10 250 40 300 20v60H0z' fill='%230a6e85' fill-opacity='.08'/%3E%3C/svg%3E");
    animation: net-wave 40s linear infinite reverse;
    opacity: .9;
}
.net-bg__wave--3 {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 220' preserveAspectRatio='none'%3E%3Cpath d='M0 178c200-46 400 34 600 6s400-52 600-6v42H0z' fill='%234ed7f1' fill-opacity='.14'/%3E%3C/svg%3E");
    animation: net-wave 58s linear infinite;
}
@keyframes net-wave {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}

/* Dark rooms (hero, ink sections, portal night) get the same system in
   the inverse key, so the atmosphere is continuous across the page. */
.net-bg--ink .net-bg__dots { background-image: radial-gradient(circle at center, rgba(78, 215, 241, .22) 1.1px, transparent 1.2px); }
.net-bg--ink .net-bg__dots--fine { background-image: radial-gradient(circle at center, rgba(255, 255, 255, .07) 1px, transparent 1.1px); }
.net-bg--ink .net-bg__bloom {
    background:
        radial-gradient(40rem 26rem at 15% -10%, rgba(78, 215, 241, .22), transparent 60%),
        radial-gradient(34rem 22rem at 88% 0%,  rgba(45, 122, 148, .26), transparent 62%);
}

/* A scanning sweep - the "something is live in here" cue. Very low
   contrast on purpose; it should be felt, not watched. */
.net-bg__scan {
    position: absolute;
    inset: 0;
    background: linear-gradient(115deg, transparent 42%, rgba(78, 215, 241, .07) 50%, transparent 58%);
    background-size: 260% 100%;
    animation: net-scan 11s ease-in-out infinite;
}
@keyframes net-scan {
    0%   { background-position: 130% 0; }
    100% { background-position: -30% 0; }
}

/* --- a wave that separates two sections ------------------------------- */
.wave-sep {
    display: block;
    width: 100%;
    height: 58px;
    margin: 0;
    line-height: 0;
    color: var(--wms-canvas);
}
.wave-sep svg { display: block; width: 100%; height: 100%; }
.wave-sep--flip svg { transform: scaleY(-1); }

/* --- reusable signal marks -------------------------------------------- */

/* Concentric rings radiating from a point, like coverage from an AP. */
.signal-rings { position: absolute; inset: 0; pointer-events: none; }
.signal-rings i {
    position: absolute;
    top: 50%; left: 50%;
    width: 40px; height: 40px;
    margin: -20px 0 0 -20px;
    border: 1px solid rgba(78, 215, 241, .55);
    border-radius: 50%;
    opacity: 0;
    animation: net-ring 3.6s cubic-bezier(.2, .6, .3, 1) infinite;
}
.signal-rings i:nth-child(2) { animation-delay: 1.2s; }
.signal-rings i:nth-child(3) { animation-delay: 2.4s; }
@keyframes net-ring {
    0%   { transform: scale(.35); opacity: .85; }
    75%  { opacity: .12; }
    100% { transform: scale(4.6);  opacity: 0; }
}

/* A live dot: the universal "connected" tell. */
.live-dot {
    position: relative;
    display: inline-block;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: #35d39a;
    flex: none;
}
.live-dot::after {
    content: "";
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 1px solid currentColor;
    color: #35d39a;
    animation: net-ping 2s ease-out infinite;
}
.live-dot--cyan { background: var(--net-cyan); }
.live-dot--cyan::after { color: var(--net-cyan); }
@keyframes net-ping {
    0%   { transform: scale(.6); opacity: .9; }
    100% { transform: scale(1.9); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .net-bg__dots, .net-bg__dots--fine, .net-bg__bloom, .net-bg__wave,
    .net-bg__scan, .signal-rings i, .live-dot::after,
    .netmap__packet, .ticker__track, .rail__pulse {
        animation: none !important;
    }
    .net-bg__scan { opacity: 0; }
}

/* =====================================================================
   2. MOBILE APPLICATION SHELL
   ---------------------------------------------------------------------
   On a phone the system stops behaving like a website: navigation moves
   to a fixed bottom bar within thumb reach, and the page's primary action
   is pinned above it instead of living at the end of a scroll.
   ===================================================================== */

.app-tabbar {
    display: none;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    /* Under the admin drawer's backdrop (890) so an open drawer dims the bar
       too, and under modals (1100) and toasts (1200). */
    z-index: 880;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    align-items: stretch;
    padding: .3rem .25rem calc(.3rem + var(--wms-safe-b));
    background: rgba(255, 255, 255, .94);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-top: 1px solid var(--wms-border);
    box-shadow: 0 -8px 28px -18px rgba(10, 30, 40, .55);
}

.app-tab {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .18rem;
    min-height: 52px;
    padding: .35rem .2rem;
    font-size: .625rem;
    font-weight: 650;
    letter-spacing: .01em;
    color: var(--wms-text-muted);
    background: none;
    border: 0;
    border-radius: var(--wms-radius);
    font-family: inherit;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: color .14s ease, background-color .14s ease;
}
.app-tab:hover, .app-tab:focus-visible { text-decoration: none; color: var(--wms-text); }
.app-tab .ico { width: 1.25rem; height: 1.25rem; }
.app-tab__label { display: block; line-height: 1.1; }

.app-tab.is-active { color: var(--wms-primary); }
.app-tab.is-active .ico { color: var(--wms-primary); }
.app-tab.is-active .app-tab__label { font-weight: 750; }

/* The active tab is marked by a signal bar above it, not by a filled pill:
   it reads as a level meter, which is the language of this product. */
.app-tab.is-active::before {
    content: "";
    position: absolute;
    top: 0;
    width: 26px;
    height: 3px;
    border-radius: 0 0 3px 3px;
    background: var(--wms-brand);
    box-shadow: 0 0 10px rgba(78, 215, 241, .9);
}
.app-tab { position: relative; }

/* Centre action tab - the raised "buy / connect" button. */
.app-tab--action { color: var(--wms-primary); }
.app-tab--action .app-tab__mark {
    display: grid;
    place-items: center;
    width: 42px; height: 42px;
    margin-top: -18px;
    margin-bottom: .1rem;
    color: var(--wms-ink);
    background: var(--wms-brand);
    border: 3px solid var(--wms-surface);
    border-radius: 50%;
    box-shadow: 0 6px 18px -6px rgba(78, 215, 241, .95);
}
.app-tab--action.is-active::before { display: none; }

.app-tab__dot {
    position: absolute;
    top: .3rem;
    left: 50%;
    margin-left: .35rem;
    min-width: 15px;
    padding: 0 .2rem;
    font-size: .5625rem;
    font-weight: 800;
    line-height: 15px;
    text-align: center;
    color: #fff;
    background: var(--wms-danger);
    border-radius: 999px;
}

/* The pinned primary action. Pages put their main button in here; on a
   large screen it un-pins and behaves like an ordinary block button. */
.app-actionbar {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    padding: .75rem 0 .25rem;
}
.app-actionbar > * { flex: 1 1 auto; }
.app-actionbar__hint {
    flex: 1 1 100%;
    margin: 0 0 .1rem;
    font-size: .6875rem;
    color: var(--wms-text-muted);
    text-align: center;
}

@media (max-width: 860px) {
    .app-tabbar { display: grid; }

    /* Only reserve the space where the bar is actually on screen. */
    body.has-tabbar { padding-bottom: calc(var(--wms-tabbar-h) + var(--wms-safe-b)); }

    /* Pinned to the viewport on a phone, floating clear of the tab bar. */
    .app-actionbar {
        position: fixed;
        left: 0; right: 0;
        bottom: calc(var(--wms-tabbar-h) + var(--wms-safe-b));
        z-index: 870;
        padding: .6rem .9rem calc(.6rem);
        background: rgba(255, 255, 255, .96);
        backdrop-filter: saturate(180%) blur(12px);
        -webkit-backdrop-filter: saturate(180%) blur(12px);
        border-top: 1px solid var(--wms-border);
        flex-wrap: wrap;
    }
    body.has-actionbar { padding-bottom: calc(var(--wms-tabbar-h) + var(--wms-safe-b) + 74px); }

    /* Nothing may hide behind the bars. */
    .portal, .page { padding-bottom: 1.25rem; }
}

/* A phone-shaped page header that scrolls away like an app's. */
.app-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    min-height: 44px;
}
.app-head__back {
    display: none;
    place-items: center;
    width: 36px; height: 36px;
    flex: none;
    color: var(--wms-text-muted);
    background: var(--wms-surface);
    border: 1px solid var(--wms-border);
    border-radius: 50%;
}
.app-head__back:hover { color: var(--wms-text); text-decoration: none; border-color: var(--wms-border-strong); }
.app-head__back .ico { transform: rotate(180deg); }
@media (max-width: 860px) { .app-head__back { display: grid; } }

/* =====================================================================
   3. PUBLIC PAGE, REBUILT
   ===================================================================== */

/* --- top bar ---------------------------------------------------------- */

.site-header { background: rgba(255, 255, 255, .82); }
/* The toggle is an .icon-btn, whose display:grid would otherwise win here. */
.site-nav__toggle { display: none; }
.site-header--ink {
    background: rgba(7, 17, 25, .72);
    border-bottom-color: rgba(255, 255, 255, .08);
}
.site-header--ink .site-brand,
.site-header--ink .site-brand .brand-text b { color: #fff; }
.site-header--ink .site-nav a { color: #9fb0bd; }
.site-header--ink .site-nav a:hover { color: var(--net-cyan); }
.site-header--ink .site-nav__toggle { color: #cfe2ea; }
.site-header--ink .btn--ghost { color: #d6e5ec; border-color: rgba(255, 255, 255, .24); }
.site-header--ink .btn--ghost:hover { background: rgba(255, 255, 255, .1); color: #fff; border-color: rgba(255, 255, 255, .4); }

/* A live status chip instead of a marketing badge: what this product is
   for is visible in the first 200 milliseconds. */
.net-chip {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .3rem .65rem;
    font-size: .6875rem;
    font-weight: 700;
    letter-spacing: .04em;
    color: #b9e9f5;
    background: rgba(78, 215, 241, .10);
    border: 1px solid rgba(78, 215, 241, .30);
    border-radius: 999px;
    white-space: nowrap;
}
.net-chip--light { color: var(--wms-primary); background: var(--wms-brand-tint); border-color: var(--wms-brand-pale); }

/* --- hero ------------------------------------------------------------- */

.nhero {
    position: relative;
    isolation: isolate;
    color: #fff;
    background: linear-gradient(168deg, #08131c 0%, #0d1a20 46%, #0a2029 100%);
    overflow: hidden;
}
.nhero__fx { position: absolute; inset: 0; pointer-events: none; }

.nhero__inner {
    position: relative;
    z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, .98fr);
    gap: 3.5rem;
    align-items: center;
    /* Keep .site-wrap's gutters - a shorthand here would zero them. */
    padding: 3.75rem 1.25rem 3.25rem;
}

.nhero__kicker {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    margin-bottom: 1.15rem;
    font-family: var(--wms-mono);
    font-size: .6875rem;
    font-weight: 600;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--net-cyan);
}
.nhero__kicker::after {
    content: "";
    width: 3.5rem;
    height: 1px;
    background: linear-gradient(90deg, var(--net-cyan), transparent);
}

.nhero h1 {
    font-size: clamp(2.05rem, 5.2vw, 3.35rem);
    line-height: 1.04;
    letter-spacing: -.035em;
    color: #fff;
    margin: 0 0 1.05rem;
}
/* The word that carries the promise gets the signal colour and a live
   underline that redraws itself, like a link coming up. */
.nhero h1 em {
    position: relative;
    font-style: normal;
    color: var(--net-cyan);
    white-space: nowrap;
}
.nhero h1 em::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -.06em;
    height: 3px;
    border-radius: 2px;
    background: linear-gradient(90deg, var(--net-cyan), rgba(78, 215, 241, 0));
    transform-origin: left;
    animation: net-underline 4.5s ease-in-out infinite;
}
@keyframes net-underline {
    0%, 12%   { transform: scaleX(0); opacity: .3; }
    45%, 75%  { transform: scaleX(1); opacity: 1; }
    100%      { transform: scaleX(1); opacity: .5; }
}

.nhero__lead {
    max-width: 33rem;
    font-size: 1.02rem;
    line-height: 1.7;
    color: #a7bac6;
    margin: 0 0 1.7rem;
}

/* The map-only hero: one centred column, the diagram carrying the message
   and the two doors under it. No two-column split to balance, so the grid
   collapses and everything centres on the map. */
.nhero__inner--map {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 1.9rem;
    padding-top: 2.6rem;
    padding-bottom: 2.6rem;
}
.nhero__inner--map .netmap { max-width: 400px; }

/* The headline sits above the diagram, so it is centred and kept to a
   readable measure rather than running the width of the page. */
.nhero__head { max-width: 46rem; text-align: center; }
.nhero__head .nhero__kicker { justify-content: center; margin-bottom: .85rem; }
/* The rule that trails the kicker is an off-centre flourish; drop it here. */
.nhero__head .nhero__kicker::after { display: none; }
.nhero__head h1 {
    font-size: clamp(1.7rem, 4vw, 2.55rem);
    margin-bottom: .8rem;
    /* Even out the line lengths where the browser can; ignored elsewhere. */
    text-wrap: balance;
}
.nhero__head .nhero__lead {
    max-width: 36rem;
    margin: 0 auto;
    font-size: .95rem;
    text-wrap: pretty;
}

.nhero__cta { display: flex; flex-wrap: wrap; gap: .6rem; }
.nhero__inner--map .nhero__cta { justify-content: center; }
.nhero__cta .btn--ghost { color: #d6e5ec; border-color: rgba(255, 255, 255, .24); }
.nhero__cta .btn--ghost:hover { background: rgba(255, 255, 255, .09); color: #fff; border-color: rgba(255, 255, 255, .4); }

.nhero__note {
    margin: 1.15rem 0 0;
    font-size: .75rem;
    color: #6d8290;
}
.nhero__note b { color: #9fb8c4; font-weight: 600; }

/* --- the live network map (replaces the fake console screenshot) ------- */

.netmap {
    position: relative;
    aspect-ratio: 1 / .88;
    width: 100%;
    max-width: 480px;
    margin-inline: auto;
}
.netmap__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }

.netmap__link {
    fill: none;
    stroke: rgba(120, 175, 195, .35);
    stroke-width: 1.25;
}
.netmap__flow {
    fill: none;
    stroke: var(--net-cyan);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-dasharray: 5 92;
    filter: drop-shadow(0 0 4px rgba(78, 215, 241, .8));
    animation: net-flow 3.2s linear infinite;
}
.netmap__flow--b { animation-delay: .9s; }
.netmap__flow--c { animation-delay: 1.8s; }
.netmap__flow--d { animation-delay: 2.5s; }
@keyframes net-flow {
    from { stroke-dashoffset: 97; }
    to   { stroke-dashoffset: 0; }
}

.netmap__hub, .netmap__node {
    fill: #0e1d27;
    stroke: rgba(78, 215, 241, .5);
    stroke-width: 1.25;
}
.netmap__hub { fill: #10242e; stroke: var(--net-cyan); }
.netmap__halo {
    fill: none;
    stroke: rgba(78, 215, 241, .5);
    transform-origin: center;
    animation: net-halo 3.8s ease-out infinite;
}
.netmap__halo--b { animation-delay: 1.3s; }
.netmap__halo--c { animation-delay: 2.6s; }
@keyframes net-halo {
    0%   { r: 30px;  opacity: .7; }
    100% { r: 118px; opacity: 0; }
}
.netmap__label {
    fill: #8fa6b3;
    font-family: var(--wms-mono);
    font-size: 9px;
    letter-spacing: .06em;
    text-transform: uppercase;
}
.netmap__value { fill: var(--net-cyan); font-size: 10.5px; font-weight: 700; font-family: var(--wms-mono); }
.netmap__glyph { fill: none; stroke: var(--net-cyan); stroke-width: 1.4; stroke-linecap: round; }
.netmap__glyph--dim { stroke: #7f97a4; }

/* Floating read-outs pinned to the map - real labels for the diagram. */
.netmap__tag {
    position: absolute;
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .32rem .55rem;
    font-size: .6875rem;
    font-weight: 650;
    color: #cfe3ec;
    background: rgba(9, 22, 31, .88);
    border: 1px solid rgba(120, 175, 195, .28);
    border-radius: 999px;
    backdrop-filter: blur(6px);
    white-space: nowrap;
    animation: net-float 6s ease-in-out infinite;
}
.netmap__tag b { color: #fff; font-weight: 700; font-variant-numeric: tabular-nums; }
.netmap__tag--1 { top: 4%;  left: -2%; }
.netmap__tag--2 { top: 44%; right: -4%; animation-delay: 1.6s; }
/* The third tag labels the device row, so it is centred under it rather
   than floated at an edge where it would sit on top of a device. */
.netmap__tag--3 {
    bottom: 1%;
    left: 0; right: 0;
    width: max-content;
    margin: 0 auto;
    animation-delay: 3.1s;
}
@keyframes net-float {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-6px); }
}

.netmap__caption {
    position: absolute;
    left: 0; right: 0;
    bottom: -1.9rem;
    text-align: center;
    font-size: .65rem;
    letter-spacing: .04em;
    color: #5d7280;
}

/* --- the ticker: figures that scroll, like a NOC wallboard ------------- */

.ticker {
    position: relative;
    overflow: hidden;
    background: rgba(7, 17, 25, .92);
    border-top: 1px solid rgba(255, 255, 255, .07);
    border-bottom: 1px solid rgba(255, 255, 255, .07);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.ticker__track {
    display: flex;
    width: max-content;
    animation: net-ticker 42s linear infinite;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
@keyframes net-ticker {
    from { transform: translate3d(0, 0, 0); }
    to   { transform: translate3d(-50%, 0, 0); }
}
.ticker__item {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .7rem 1.4rem;
    font-size: .75rem;
    color: #8ea3b0;
    white-space: nowrap;
    border-right: 1px solid rgba(255, 255, 255, .06);
}
.ticker__item b { color: #fff; font-weight: 700; font-variant-numeric: tabular-nums; }
.ticker__item .ico { color: var(--net-cyan); }

/* --- the rail: how it works, as a signal path -------------------------- */

.rail { position: relative; display: grid; gap: 0; }
.rail::before {
    content: "";
    position: absolute;
    left: 21px;
    top: 1.6rem; bottom: 1.6rem;
    width: 2px;
    background: linear-gradient(180deg, var(--wms-brand-pale), var(--wms-border) 70%);
}
.rail__pulse {
    position: absolute;
    left: 17px;
    width: 10px; height: 10px;
    border-radius: 50%;
    background: var(--wms-brand);
    box-shadow: 0 0 12px 2px rgba(78, 215, 241, .8);
    animation: net-rail 6s cubic-bezier(.6, 0, .4, 1) infinite;
}
@keyframes net-rail {
    0%   { top: 1.4rem;  opacity: 0; }
    8%   { opacity: 1; }
    92%  { opacity: 1; }
    100% { top: calc(100% - 2rem); opacity: 0; }
}

.rail__step {
    position: relative;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    gap: 1.1rem;
    padding: .9rem 0;
}
.rail__num {
    display: grid;
    place-items: center;
    width: 44px; height: 44px;
    font-family: var(--wms-mono);
    font-size: .8125rem;
    font-weight: 700;
    color: var(--wms-primary);
    background: var(--wms-surface);
    border: 1px solid var(--wms-brand-pale);
    border-radius: 50%;
    z-index: 1;
}
.rail__step--accent .rail__num { color: var(--wms-ink); background: var(--wms-brand); border-color: var(--wms-brand); }
.rail__body h3 { font-size: .98rem; margin: .4rem 0 .25rem; }
.rail__body p { font-size: .8375rem; color: var(--wms-text-muted); margin: 0; }
.rail__meta {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    margin-top: .45rem;
    font-family: var(--wms-mono);
    font-size: .6875rem;
    letter-spacing: .04em;
    color: var(--wms-text-faint);
}

/* A flow diagram turned vertical. Without this the nodes keep their
   flex-grow and stretch to whatever height the tallest neighbour has. */
.flow--stack { flex-direction: column; align-items: stretch; gap: .4rem; }
.flow--stack .flow__node { flex: 0 0 auto; }

/* --- bento: modules at the size they deserve, not nine equal boxes ----- */

.bento {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 1rem;
}
.bento__cell {
    position: relative;
    grid-column: span 2;
    display: flex;
    flex-direction: column;
    padding: 1.35rem;
    background: var(--wms-surface);
    border: 1px solid var(--wms-border);
    border-radius: var(--wms-radius-lg);
    overflow: hidden;
    transition: border-color .16s ease, transform .16s ease, box-shadow .16s ease;
}
.bento__cell:hover {
    border-color: var(--wms-brand-pale);
    transform: translateY(-3px);
    box-shadow: 0 18px 34px -22px rgba(10, 40, 55, .55);
}
.bento__cell--wide { grid-column: span 3; }
.bento__cell--tall { grid-column: span 3; }
.bento__cell--full { grid-column: span 6; }
.bento__cell--ink {
    color: #cfdde5;
    background: linear-gradient(155deg, #0d1a20, #0b2029);
    border-color: rgba(255, 255, 255, .09);
}
.bento__cell--ink h3 { color: #fff; }
.bento__cell--ink p { color: #93a8b5; }

.bento__icon {
    display: grid;
    place-items: center;
    width: 38px; height: 38px;
    margin-bottom: .9rem;
    color: var(--wms-primary);
    background: var(--wms-brand-tint);
    border: 1px solid var(--wms-brand-pale);
    border-radius: 11px;
}
.bento__cell--ink .bento__icon {
    color: var(--net-cyan);
    background: rgba(78, 215, 241, .12);
    border-color: rgba(78, 215, 241, .3);
}
.bento__cell h3 { font-size: .98rem; margin: 0 0 .3rem; }
.bento__cell p { font-size: .8125rem; color: var(--wms-text-muted); margin: 0; }
.bento__list {
    list-style: none;
    margin: .9rem 0 0;
    padding: 0;
    display: grid;
    gap: .35rem;
    font-size: .78rem;
    color: var(--wms-text-muted);
}
.bento__list li { display: flex; align-items: flex-start; gap: .45rem; }
.bento__list .ico { color: var(--wms-primary); margin-top: 3px; flex: none; }
.bento__cell--ink .bento__list { color: #93a8b5; }
.bento__cell--ink .bento__list .ico { color: var(--net-cyan); }

/* A faint signal-bar motif in the corner of the wide cells. */
.bento__bars {
    position: absolute;
    right: 1rem; bottom: 1rem;
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 26px;
    opacity: .5;
    pointer-events: none;
}
.bento__bars i {
    display: block;
    width: 4px;
    background: var(--wms-brand-pale);
    border-radius: 2px;
    animation: net-bars 1.9s ease-in-out infinite;
}
.bento__bars i:nth-child(1) { height: 30%; animation-delay: 0s; }
.bento__bars i:nth-child(2) { height: 55%; animation-delay: .18s; }
.bento__bars i:nth-child(3) { height: 80%; animation-delay: .36s; }
.bento__bars i:nth-child(4) { height: 100%; animation-delay: .54s; }
@keyframes net-bars {
    0%, 100% { transform: scaleY(.55); opacity: .5; }
    50%      { transform: scaleY(1);   opacity: 1; }
}
.bento__cell--ink .bento__bars i { background: rgba(78, 215, 241, .7); }
@media (prefers-reduced-motion: reduce) { .bento__bars i { animation: none; } }

/* --- tariff board ------------------------------------------------------ */

.tariff {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
}
.tariff__card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 1.35rem 1.2rem;
    background: var(--wms-surface);
    border: 1px solid var(--wms-border);
    border-radius: var(--wms-radius-lg);
    transition: border-color .16s ease, transform .16s ease;
}
.tariff__card:hover { border-color: var(--wms-brand-pale); transform: translateY(-3px); }
.tariff__card--featured {
    border-color: var(--wms-primary);
    box-shadow: 0 0 0 3px var(--wms-brand-tint), 0 20px 40px -26px rgba(10, 110, 133, .6);
}
.tariff__flag {
    position: absolute;
    top: -.6rem; left: 1.2rem;
    padding: .15rem .5rem;
    font-size: .625rem;
    font-weight: 800;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--wms-ink);
    background: var(--wms-brand);
    border-radius: 999px;
}
.tariff__name { font-size: .8125rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--wms-text-muted); }
.tariff__price {
    margin: .35rem 0 .1rem;
    font-size: 1.75rem;
    font-weight: 750;
    letter-spacing: -.03em;
    color: var(--wms-text);
    font-variant-numeric: tabular-nums;
}
.tariff__for { font-size: .75rem; color: var(--wms-text-faint); margin-bottom: .9rem; }
.tariff__specs { list-style: none; margin: 0 0 1.1rem; padding: 0; display: grid; gap: .4rem; font-size: .8125rem; color: var(--wms-text-muted); }
.tariff__specs li { display: flex; align-items: center; gap: .5rem; }
.tariff__specs .ico { color: var(--wms-primary); flex: none; }
.tariff__card .btn { margin-top: auto; }

/* --- closing band ----------------------------------------------------- */

.band {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: 3.25rem 0;
    color: #fff;
    background: linear-gradient(150deg, #0a1b23, #0d2833 60%, #0a1b23);
}
.band__fx { position: absolute; inset: 0; pointer-events: none; }
.band__inner {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    flex-wrap: wrap;
}
.band h2 { color: #fff; font-size: clamp(1.35rem, 3vw, 1.9rem); letter-spacing: -.025em; margin-bottom: .35rem; }
.band p { color: #94aab7; margin: 0; max-width: 34rem; }

/* --- section rhythm on the public page -------------------------------- */

body.wms-public .section { background: transparent; border-bottom: 0; padding: 3.5rem 0; }
body.wms-public .section--alt { background: rgba(243, 247, 249, .72); backdrop-filter: blur(2px); }
/* The dark band keeps its ink - the transparent rule above outranks the
   .section--ink one in style.css, so it has to be restated here. */
body.wms-public .section--ink { background: var(--wms-ink); }

/* Check lists inherit dark ink for their bold labels, which disappears on a
   dark band. Repaint the whole list for the inverse ground. */
.section--ink .check-list li { color: #a9b5c3; border-bottom-color: rgba(255, 255, 255, .08); }
.section--ink .check-list li b { color: #fff; }
.section--ink .check-list .ico { color: var(--wms-brand); }
body.wms-public .section--tight { padding: 2.5rem 0; }

.eyebrow-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-bottom: 1.75rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--wms-border);
}
.eyebrow-row__title { max-width: 40rem; }
.eyebrow-row__title h2 {
    font-size: clamp(1.35rem, 2.9vw, 1.95rem);
    letter-spacing: -.028em;
    margin: .5rem 0 .4rem;
}
.eyebrow-row__title p { font-size: .9rem; color: var(--wms-text-muted); margin: 0; }
.eyebrow-row__aside { font-family: var(--wms-mono); font-size: .6875rem; letter-spacing: .1em; text-transform: uppercase; color: var(--wms-text-faint); }

/* --- footer ------------------------------------------------------------ */

.site-footer { position: relative; background: linear-gradient(180deg, #0b1820, #071119); }

/* --- staff sign in ------------------------------------------------------ */

.auth-aside { isolation: isolate; background: linear-gradient(168deg, #08131c, #0d1a20 50%, #0a2029); }
.auth-aside__fx { position: absolute; inset: 0; pointer-events: none; }
.auth-aside > .site-brand,
.auth-aside__content { position: relative; z-index: 1; }
/* The static grid it used to carry is now the dot field's job. */
.auth-aside::before { display: none; }

/* =====================================================================
   4. PORTAL, AS AN APPLICATION
   ===================================================================== */

/* The portal keeps a transparent body (declared with the other shells at the
   top of this file) so the wave backdrop is visible behind the card stack. */

/* The portal's top bar follows the page down, like an app's. It is the only
   place the brand, the way home and the account live. */
.portal__top {
    position: sticky;
    top: 0;
    z-index: 60;
    margin: 0 -1rem;
    padding: .7rem 1rem;
    background: rgba(243, 247, 249, .88);
    backdrop-filter: saturate(180%) blur(10px);
    -webkit-backdrop-filter: saturate(180%) blur(10px);
    border-bottom: 1px solid transparent;
    transition: border-color .15s ease;
}
/* A hairline appears only once the bar is actually lifted off the top. */
.portal__top.is-stuck { border-bottom-color: var(--wms-border); }

/* Which network is serving this visitor, and the way to change it. */
.portal-net {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    margin-bottom: .85rem;
    padding: .45rem .7rem;
    font-size: .75rem;
    color: var(--wms-text-muted);
    background: var(--wms-surface);
    border: 1px solid var(--wms-border);
    border-radius: 999px;
}
.portal-net__text { display: inline-flex; align-items: center; gap: .4rem; min-width: 0; }
.portal-net__text b { color: var(--wms-text); font-weight: 650; }
.portal-net .ico { color: var(--wms-primary); flex: none; }

/* A button that reads as a link: a state change, so it must be a button. */
.link-btn {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    padding: .15rem .1rem;
    flex: none;
    font: inherit;
    font-weight: 650;
    color: var(--wms-primary);
    background: none;
    border: 0;
    cursor: pointer;
    white-space: nowrap;
}
.link-btn:hover { color: var(--wms-primary-strong); text-decoration: underline; }

/* Round icon button used for home / back in the portal chrome. */
.round-btn {
    display: grid;
    place-items: center;
    width: 36px; height: 36px;
    flex: none;
    color: var(--wms-text-muted);
    background: var(--wms-surface);
    border: 1px solid var(--wms-border);
    border-radius: 50%;
    cursor: pointer;
}
.round-btn:hover { color: var(--wms-primary); border-color: var(--wms-brand-pale); text-decoration: none; }
.round-btn--back .ico { transform: rotate(180deg); }

/* No backdrop-filter here. The card is already opaque, so it bought nothing
   visually - and any filter makes the element a containing block for
   position:fixed descendants, which silently unpinned the action bar that
   pages render inside these cards. */

/* The hero card of the portal: a signal panel the customer reads first. */
.portal-hero {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: 1.4rem 1.15rem;
    margin-bottom: 1rem;
    color: #fff;
    background: linear-gradient(155deg, #0d1a20, #0b2530);
    border-radius: var(--wms-radius-lg);
}
.portal-hero__fx { position: absolute; inset: 0; pointer-events: none; }
.portal-hero__body { position: relative; z-index: 1; display: flex; align-items: center; gap: .9rem; }
.portal-hero__mark {
    position: relative;
    display: grid;
    place-items: center;
    width: 52px; height: 52px;
    flex: none;
    color: var(--net-cyan);
    background: rgba(78, 215, 241, .12);
    border: 1px solid rgba(78, 215, 241, .3);
    border-radius: 50%;
}
.portal-hero__text b { display: block; font-size: 1.02rem; font-weight: 700; }
.portal-hero__text span { font-size: .8125rem; color: #93a8b5; }
.portal-hero--online .portal-hero__mark { color: #35d39a; background: rgba(53, 211, 154, .12); border-color: rgba(53, 211, 154, .34); }

/* The exit from the payment wait, set apart from the steps above it. */
.pay-wait__out {
    margin-top: 1.1rem;
    padding-top: .9rem;
    border-top: 1px solid var(--wms-border);
    text-align: left;
}

/* The portal's own tab strip duplicates the bottom bar on a phone, so it
   stands down where the bottom bar is showing. */
@media (max-width: 860px) {
    .portal-tabs { display: none; }
}

/* =====================================================================
   5. ADMIN TOUCH-UPS
   ===================================================================== */

body.wms-admin .page { position: relative; }

/* A quiet atmosphere in the control centre: present, never distracting. */
.net-bg--quiet .net-bg__dots { opacity: .35; }
.net-bg--quiet .net-bg__dots--fine { display: none; }
.net-bg--quiet .net-bg__bloom { opacity: .5; }
.net-bg--quiet .net-bg__waves { opacity: .55; height: 34vh; }
.net-bg--quiet .net-bg__scan { display: none; }

/* =====================================================================
   6. RESPONSIVE
   ===================================================================== */

@media (max-width: 1080px) {
    .nhero__inner { gap: 2.5rem; }
    .netmap__tag--2 { right: 0; }
    .bento { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .bento__cell--wide, .bento__cell--tall { grid-column: span 2; }
    .bento__cell--full { grid-column: span 4; }
}

@media (max-width: 900px) {
    .nhero__inner {
        grid-template-columns: minmax(0, 1fr);
        gap: 2.5rem;
        padding: 2.75rem 1.25rem 2.5rem;
    }
    .nhero__inner--map { gap: 2rem; }
    .netmap { max-width: 380px; }
    .netmap__tag--1 { left: 0; }
    .netmap__tag--2 { right: 0; }
}

@media (max-width: 860px) {
    .site-header__actions { display: none; }
    .site-nav {
        display: none;
        position: absolute;
        top: 100%; left: 0; right: 0;
        flex-direction: column;
        gap: 0;
        padding: .5rem .9rem 1rem;
        background: var(--wms-surface);
        border-bottom: 1px solid var(--wms-border);
        box-shadow: var(--wms-shadow);
    }
    .site-header--ink .site-nav { background: #0b1820; border-bottom-color: rgba(255,255,255,.1); }
    .site-nav.is-open { display: flex; }
    .site-nav a { padding: .7rem .25rem; border-bottom: 1px solid var(--wms-border); font-size: .875rem; }
    .site-header--ink .site-nav a { border-bottom-color: rgba(255, 255, 255, .07); }
    .site-nav a:last-child { border-bottom: 0; }
    .site-nav__toggle { display: inline-grid; margin-left: auto; }
    .site-header__inner { position: relative; gap: .75rem; }
}

@media (max-width: 640px) {
    .nhero h1 em { white-space: normal; }
    .nhero h1 em::after { display: none; }
    .bento { grid-template-columns: minmax(0, 1fr); }
    .bento__cell, .bento__cell--wide, .bento__cell--tall, .bento__cell--full { grid-column: span 1; }
    .band { padding: 2.5rem 0; }
    .band__inner { flex-direction: column; align-items: flex-start; }
    .band__inner .flex { width: 100%; }
    .band__inner .btn { flex: 1 1 auto; }
    .rail__step { grid-template-columns: 36px minmax(0, 1fr); gap: .85rem; }
    .rail__num { width: 36px; height: 36px; font-size: .75rem; }
    .rail::before { left: 17px; }
    .rail__pulse { left: 13px; }
    .site-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
    .site-footer__grid > :first-child { grid-column: 1 / -1; }
    .ticker__item { padding: .6rem 1rem; font-size: .7rem; }
    .netmap__caption { position: static; margin-top: 1.6rem; }
}

@media (max-width: 420px) {
    .nhero__inner { padding: 2.25rem 1.25rem 2rem; }
    .nhero__inner--map { gap: 1.5rem; }
    .nhero__inner--map .nhero__cta { width: 100%; }
    .nhero__inner--map .nhero__cta .btn { flex: 1 1 100%; }
    .netmap { max-width: 300px; }
    .netmap__tag { font-size: .625rem; padding: .25rem .45rem; }
    .app-tab { font-size: .5625rem; }
    .app-tab .ico { width: 1.15rem; height: 1.15rem; }
}

/* =====================================================================
   7. MENUS AND MOTION
   ===================================================================== */

/* --- row menus ---------------------------------------------------------
   Positioned by JS against the viewport rather than by CSS against the
   trigger: these menus sit inside .table-wrap, and a scrolling ancestor
   clips whatever is absolutely positioned inside it. On a phone the menu
   was clipped away entirely, so the button did nothing. */

.dropdown__menu {
    position: fixed;
    right: auto;
    top: auto;
    z-index: 1050;
    max-height: min(70vh, 420px);
    overflow-y: auto;
    overscroll-behavior: contain;
    display: none;
}

/* The entrance is an animation, not a transition. A transition needs a
   rendered "before" state to interpolate from, which a menu that was
   display:none has never had; an animation simply runs when the element
   appears. It is the same pattern the modal already uses. */
.dropdown__menu.is-open {
    display: block;
    transform-origin: top right;
    animation: wms-drop-in .14s ease-out;
}
.dropdown__menu.is-open.drops-up { transform-origin: bottom right; }

@keyframes wms-drop-in {
    from { opacity: 0; transform: translateY(-6px) scale(.98); }
}

/* On a phone the same menu becomes a bottom sheet - a list pinned under a
   30px icon is not a target anyone can hit reliably. */
@media (max-width: 640px) {
    .dropdown__menu.is-sheet.is-open {
        top: auto;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
        min-width: 0;
        max-height: 74vh;
        padding: .4rem .6rem calc(.6rem + var(--wms-safe-b));
        border-width: 1px 0 0;
        border-radius: var(--wms-radius-lg) var(--wms-radius-lg) 0 0;
        box-shadow: 0 -12px 40px -12px rgba(10, 30, 40, .45);
        transform-origin: bottom center;
        animation: wms-sheet-up .24s cubic-bezier(.2, .8, .3, 1);
    }

    @keyframes wms-sheet-up {
        from { transform: translateY(100%); }
    }

    /* A grab handle, so it reads as something you can dismiss. */
    .dropdown__menu.is-sheet.is-open::before {
        content: "";
        display: block;
        width: 34px; height: 4px;
        margin: .3rem auto .5rem;
        border-radius: 2px;
        background: var(--wms-border-strong);
    }
    .dropdown__menu.is-sheet .dropdown__item { padding: .7rem .6rem; font-size: .875rem; }
    .dropdown__menu.is-sheet .dropdown__label { padding-bottom: .35rem; }

    /* The scrim behind the sheet. */
    body.has-sheet::after {
        content: "";
        position: fixed;
        inset: 0;
        z-index: 1040;
        background: rgba(9, 22, 31, .38);
        animation: net-fade .18s ease-out;
    }
}
@keyframes net-fade { from { opacity: 0; } }

/* --- the header's mobile menu -----------------------------------------
   display:none cannot be transitioned, so the sheet is always laid out and
   simply collapsed - it now slides rather than appearing in one frame. */

@media (max-width: 860px) {
    .site-nav {
        display: flex;
        max-height: 0;
        opacity: 0;
        visibility: hidden;
        overflow: hidden;
        transform: translateY(-6px);
        transition: max-height .26s cubic-bezier(.2, .8, .3, 1),
                    opacity .18s ease,
                    transform .22s cubic-bezier(.2, .8, .3, 1),
                    visibility 0s linear .26s;
    }
    .site-nav.is-open {
        max-height: 22rem;
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        transition-delay: 0s;
    }
}

/* --- scroll reveal -----------------------------------------------------
   Sections resolve as they arrive: a short lift out of a soft blur, so the
   page feels like it is coming into focus rather than snapping into place.

   Two deliberate choices, both about failing safe. The effect is a nicety;
   the content is not, and no arrangement here may be able to withhold it.

   1. The hidden state is applied only once JS has confirmed it can reveal
      things again (the wms-reveal class on <html>). Without that, a failed
      script would leave the whole page invisible.

   2. The hidden state applies only while a block is still waiting - the
      :not(.is-in) - so the resting style is the element's own: opaque,
      unblurred, unmoved. The transition animates the journey to it.

      The other way round is the trap. Declaring the visible values on
      .is-in and letting a transition or an animation carry the element to
      them means anything that interrupts the motion leaves the block
      stranded at opacity 0 behind a 7px blur: unreadable content, not a
      missing flourish. Written this way, an interrupted reveal simply
      means the block appears at once. */

.wms-reveal [data-reveal]:not(.is-in) {
    opacity: 0;
    filter: blur(7px);
    transform: translateY(18px);
}
.wms-reveal [data-reveal].is-in {
    transition: opacity .55s ease,
                filter .55s ease,
                transform .55s cubic-bezier(.2, .7, .3, 1);
}

/* Blurring a section-sized box is the expensive half of this effect, and a
   phone pays for it in dropped frames on the very scroll it is meant to
   decorate. Small screens get the lift and the fade only, which the
   compositor handles without touching the pixels. */
@media (max-width: 640px) {
    .wms-reveal [data-reveal]:not(.is-in) { filter: none; transform: translateY(14px); }
    .wms-reveal [data-reveal].is-in {
        transition: opacity .45s ease, transform .45s cubic-bezier(.2, .7, .3, 1);
    }
}

/* The stagger is timed in JS, by holding back when `is-in` is added, so no
   element ever waits on a delay to become visible. */

@media (prefers-reduced-motion: reduce) {
    .wms-reveal [data-reveal],
    .wms-reveal [data-reveal]:not(.is-in) { opacity: 1; filter: none; transform: none; }
    .wms-reveal [data-reveal].is-in { transition: none; }
    .dropdown__menu.is-open,
    .dropdown__menu.is-sheet.is-open,
    body.has-sheet::after { animation: none !important; }
    .site-nav { transition: none !important; }
}
