/* Loop tiles. One animated 1:1 tile per page, authored separately and dropped in
   on 12-08-2026 at Eduard's request.

   The fonts came from Google and the map libraries from a CDN. Both are gone: the
   site makes no external request, and the faces are already self-hosted for the
   rest of the page. Everything now comes from assets/vendor and assets/tiles.

   These loop. Brand manual 09 says a scene builds once and stops, which is what
   core.js does everywhere else on the site. This file is the exception, and it is
   a deliberate one - see PROJECT-STATUS.md. */

:root{--cyc:12s;--acc:#E4441F;--ink:#E7EAEB;--hair:rgba(233,238,239,.14);--ez:cubic-bezier(.2,0,0,1)}
.mono{font-family:var(--font-mono)}
.eb{font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase}
.tile{position:relative;width:100%;max-width:720px;aspect-ratio:1/1;background:#06090A;overflow:hidden;border:1px solid var(--hair);color:var(--ink)}
.map{position:absolute;inset:0}
/* The source loops were authored on a light demo page, where brightness(.72) on
   an OpenStreetMap tile reads fine. Inside a basalt tile it is a bright grey
   block against the darkest surface the brand has. Same grade, taken down to
   where the map sits under the scrim instead of fighting it. */
.map .leaflet-tile-pane{filter:grayscale(1) contrast(1.12) brightness(.34)}
.map.leaflet-container{background:#06090A;font-family:var(--font-mono)}
.leaflet-control-attribution{background:rgba(6,9,10,.72)!important;color:#5A656C!important;font-size:9px!important;font-family:var(--font-mono)!important;border:0!important}
.leaflet-control-attribution a{color:#808B92!important}
.grat{position:absolute;inset:0;background-image:linear-gradient(rgba(233,238,239,.07) 1px,transparent 1px),linear-gradient(90deg,rgba(233,238,239,.07) 1px,transparent 1px);background-size:48px 48px;pointer-events:none}
.pad{position:absolute;inset:0;padding:26px;display:flex;flex-direction:column;justify-content:space-between;pointer-events:none}
.hdr{display:flex;justify-content:space-between;align-items:flex-start;color:#808B92}
.scrim{position:absolute;left:0;right:0;bottom:0;height:56%;background:linear-gradient(to top,rgba(6,9,10,.96) 0%,rgba(6,9,10,.82) 42%,rgba(6,9,10,0) 100%);pointer-events:none}
.stmt{font-size:34px;font-weight:600;letter-spacing:-.022em;line-height:1.06;text-wrap:pretty}
.ttl{font-size:25px;font-weight:600;letter-spacing:-.014em;line-height:1.2;text-wrap:pretty}
.num{font-size:27px;font-weight:600;letter-spacing:-.022em}
.mini{font-family:var(--font-mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:#5A656C}
.slot{position:absolute;left:26px;right:26px;bottom:26px;display:flex;flex-direction:column;gap:8px}
.dot{width:9px;height:9px;border-radius:50%;background:var(--acc)}
.ring{position:absolute;left:50%;top:50%;width:74px;height:74px;margin:-37px 0 0 -37px;border:1px solid var(--acc);border-radius:50%}
.buoy{position:relative;width:12px;height:12px;margin:-6px 0 0 -6px}
.buoy i{position:absolute;inset:0;border:1.5px solid var(--acc);border-radius:50%}
.buoy b{position:absolute;left:50%;top:50%;width:3px;height:3px;margin:-1.5px 0 0 -1.5px;background:var(--acc);border-radius:50%}
.veh{position:relative;width:10px;height:10px;margin:-5px 0 0 -5px;border:1px solid rgba(233,238,239,.75);background:rgba(6,9,10,.6)}
.veh.low{border-color:var(--acc);background:var(--acc)}
.sweepline{position:absolute;top:0;bottom:0;width:1px;background:var(--acc);box-shadow:0 0 22px 2px rgba(228,68,31,.35);animation:sweepX var(--cyc) linear infinite;pointer-events:none}
@keyframes cue4{0%{opacity:0;transform:translateY(10px)}3%{opacity:1;transform:none}20%{opacity:1;transform:none}24%,100%{opacity:0;transform:translateY(-6px)}}
@keyframes cue2{0%{opacity:0;transform:translateY(8px)}4%{opacity:1;transform:none}44%{opacity:1;transform:none}49%,100%{opacity:0;transform:translateY(-5px)}}
@keyframes pulse{0%,100%{opacity:.25}50%{opacity:1}}
@keyframes sweepX{0%{left:-2%;opacity:0}5%{opacity:1}95%{opacity:1}100%{left:102%;opacity:0}}
@keyframes ringOut{0%{transform:scale(.15);opacity:.85}100%{transform:scale(1);opacity:0}}
@keyframes markOn{0%,4%{opacity:0}8%{opacity:1}23%{opacity:1}27%,100%{opacity:0}}
@keyframes cellOn{0%{opacity:0}4%{opacity:1}90%{opacity:1}100%{opacity:0}}
@keyframes layerConv{0%,26%{transform:translate(0,0)}44%,62%{transform:translate(var(--tx,0),var(--ty,0))}80%,100%{transform:translate(0,0)}}
@keyframes compOn{0%,34%{opacity:0}44%,62%{opacity:1}72%,100%{opacity:0}}
@keyframes fillBar{0%{transform:scaleX(0);opacity:0}2%{opacity:1}16%{transform:scaleX(1)}92%{transform:scaleX(1);opacity:1}100%{transform:scaleX(1);opacity:0}}
.c4{animation:cue4 var(--cyc) var(--ez) infinite both}
.c2{animation:cue2 var(--cyc) var(--ez) infinite both}
.d25{animation-delay:calc(var(--cyc)*.25)}.d50{animation-delay:calc(var(--cyc)*.5)}.d75{animation-delay:calc(var(--cyc)*.75)}
@media (prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;animation-iteration-count:1!important}}

/* The map is a fixed view over locally served tiles. A tile that is missing at the
   edge of the downloaded window reads as basalt rather than as a white hole. */
.tile .leaflet-container,
.tile .leaflet-tile-container{background:#06090A}
.tile .leaflet-tile{image-rendering:auto}
