/* arctic.css - the product run on the Defense page.

   Four sections: the system and what it does, the collection that feeds it, the
   platform it ships on, and what it is good at. Everything is scoped to .ax,
   .axflow, .axplat, .axdev and .axcap, so removing one <link> removes the whole
   run and the propaganda shell above and below it is untouched.

   IT BREAKS TWO OF DEFENSE.CSS'S RULES, DELIBERATELY.

   Rule 5, one ink, becomes three: white, black, and a deep blue. The blue is
   the only thing that separates a product section from the shell around it, and
   on a page that is otherwise white on black it does that without a single
   extra word.

   Rule 4, almost no drawn lines, cannot survive a diagram. Five sources feeding
   one system is a picture made of lines; the alternative is a list, and a list
   of five sources is what the page already says in prose. The lines live inside
   the diagram and nowhere else: there is still no rule between sections.

   Rules 1 and 2 hold. No type sits on a picture and nothing overlays anything.
   The screenshots are plates, and the words are beside them on their own ground.

   No em dashes and no middle dots in rendered text.

   AND EVERY DISPLAY RUN NAMES ITS OWN GLYPH SPANS. defense.js splits anything
   carrying data-dx-uncover into one span per character, and body.pg-def span is
   a tag qualified by a class, so it hits those spans directly and a colour set
   on their parent is never inherited. The word Arctic shipped near black on the
   navy panel for exactly that reason.

   NEVER REQUEST A VERSIONED ASSET URL BEFORE ITS DEPLOY HAS LANDED. /assets/* is
   served immutable for a year, so a 404 fetched from a versioned URL during the
   build is cached at the edge under that exact URL and every later visitor gets
   it. This file shipped as v=1, was polled a minute early, and v=1 is now a
   permanent 404; it is served at v=2 for that reason and nothing else. Poll the
   bare URL or a random query string, and bump the version if it happens. */

/* EVERY GROUND AND EVERY INK HERE IS NAMED THROUGH body.pg-def.

   defense.css sets body.pg-def section{background:#000} and paints every
   element that renders a word white through body.pg-def p, body.pg-def a and so
   on. Those are (0,1,2); a bare .ax--platform or .axcap p is (0,1,0), so the
   first pass of this file rendered a blue section black, a white section black,
   and a white button with white type on it. Two classes beats one class and two
   elements, so the prefix is not decoration, it is the only thing that makes
   these rules apply at all. */
body.pg-def{
  --axblue:#14305A;        /* the panel, and the platform ground */
  --axwire:#2F6BD8;        /* every line and mark in the diagram */
  --axgrat:#A8C2F2;        /* the graticule, one step back from the land */
  --axdot:#C9D6EE;         /* the dotted ground the sheet is drawn on */
  --axleg:#B9C3CF;         /* the legs out to the sources, the only grey */
  --axink:#0A0E14;
  --axpaper:#fff;
  --axease:cubic-bezier(.16,.84,.3,1);
}

body.pg-def .ax{background:#000;color:#fff}

/* ============================================================ THE SYSTEM
   The name and the statement sit in a blue plate on the left, the screenshot
   lands on white on the right. Two grounds meeting on one line is the whole
   device: nothing is written on the picture and nothing is laid over it. */
.ax--intro{display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  align-items:stretch;min-height:clamp(420px,62vh,760px)}
body.pg-def .ax__panel{background:var(--axblue);display:flex;flex-direction:column;
  justify-content:center;gap:clamp(20px,3vh,38px);
  padding:clamp(40px,6vw,104px) clamp(26px,4.4vw,82px)}
body.pg-def .ax__name,body.pg-def .ax__name span{color:#fff}
body.pg-def .ax__name{margin:0;font-family:var(--angular);font-weight:600;
  font-size:clamp(2.6rem,5.4vw,5.6rem);line-height:.96;letter-spacing:-.03em;color:#fff}
body.pg-def .ax__lede{margin:0;font-family:var(--angular);font-weight:500;
  font-size:clamp(1.05rem,1.3vw,1.3rem);line-height:1.5;color:#fff;max-width:46ch}

/* The ground behind the plate is paper with a drawn grid, which is what gives a
   dark screenshot an edge to sit against. The grid is the one exception to the
   no-lines rule outside the diagram, and it is a texture rather than a rule. */
body.pg-def .ax__shot{position:relative;background:var(--axpaper);display:grid;place-items:center;
  padding:clamp(26px,4vw,76px);overflow:hidden}
/* Contours, not graph paper. A square grid behind a product shot is the
   reference board's own device and copying the device is copying the board.
   This is a bathymetric sheet: a noise field run through marching squares at 26
   iso levels, chained into polylines and smoothed, which is the picture a chart
   of the sea floor makes and the one thing a company that reads water should
   have behind its console.

   Drawn once by scripts/contours.py and served as a file rather than inlined.
   It is 98KB of path, 36 of them over the wire, and it would be 98KB in the
   markup of the page on every visit if it were a data URI.

   /assets/* is immutable for a year, so regenerating it means a new filename,
   not a new file at the same one. */
.ax__shot::before{content:"";position:absolute;inset:0;
  background:url("../img/arctic/contours.svg") center/cover no-repeat}
.ax__shot img{position:relative;width:100%;max-width:1000px;height:auto;display:block;
  box-shadow:0 26px 60px rgba(8,18,34,.3);
  opacity:0;transform:translateY(26px);
  transition:opacity .9s var(--axease),transform .9s var(--axease)}
/* defense.js stamps is-on, once, on anything carrying data-dx-in */
.ax__shot.is-on img{opacity:1;transform:none}

/* ============================================================ THE COLLECTION
   Paper, not black. The section was the one dark field between a navy panel and
   a white one, which made the run read as a light page with a hole punched
   through the middle of it; and the picture it carries is a map, which wants a
   ground it can be drawn on rather than one it has to glow out of.

   Everything in it is one blue on paper: the land, the graticule, the tags, the
   pills and the boxes. The legs out to the sources are the only grey, because
   they are the one thing in the picture that is not the subject. */
body.pg-def .ax--flow{background:var(--axpaper);
  padding:clamp(60px,9vh,120px) var(--dxpad) clamp(56px,8vh,110px);
  background-image:radial-gradient(var(--axdot) 1.1px,transparent 1.1px);
  background-size:17px 17px}
body.pg-def .ax__h,body.pg-def .ax__h span{color:var(--axink)}
body.pg-def .ax__h{margin:0 auto clamp(30px,4.4vh,58px);max-width:22ch;text-align:center;
  font-family:var(--angular);font-weight:600;
  font-size:clamp(1.7rem,3.4vw,3.4rem);line-height:1.06;letter-spacing:-.024em}
.axflow{max-width:1320px;margin-inline:auto}
.axflow__svg{width:100%;height:auto;display:block;overflow:visible}

/* The land is an <image> pointing at assets/img/arctic/world.svg, so its blue
   is baked into that file and not driven from here. At the fidelity the
   coastline needs it is 152KB of path, and inline that is 152KB of markup on
   every visit; as an asset it is fetched once. If --axwire changes, the map
   has to change with it by hand. */
.axflow__grat path{stroke:var(--axgrat);stroke-width:1;fill:none}
.axflow__tag rect{fill:var(--axpaper);stroke:var(--axwire);stroke-width:1.7}
body.pg-def .axflow__tag text{fill:var(--axwire);font-family:var(--angular);
  font-weight:700;font-size:16px;letter-spacing:.06em}
.axflow__stalk{stroke:var(--axwire);stroke-width:1.5;fill:none}

.axflow__pill rect{fill:var(--axpaper);stroke:var(--axwire);stroke-width:1.9}
body.pg-def .axflow__pill text{fill:var(--axwire);font-family:var(--angular);
  font-weight:600;font-size:18px;letter-spacing:.17em}
.axflow__star path{stroke:var(--axwire);stroke-width:1.9;fill:none;
  transform-origin:0 0;animation:axspin 9s linear infinite}
@keyframes axspin{to{transform:rotate(360deg)}}
.axflow__spine{stroke:var(--axwire);stroke-width:1.7;fill:none}

.axflow__box rect{fill:var(--axpaper);stroke:var(--axwire);stroke-width:1.7}
body.pg-def .axflow__box text{fill:var(--axwire);font-family:var(--angular);
  font-weight:500;font-size:23px}
.axflow__legs path{stroke:var(--axleg);stroke-width:1.5;fill:none}

/* The dashes travel down the wire toward the first pill rather than sitting
   still: the picture is about collection arriving, not about it existing. */
.axflow__w{stroke:var(--axwire);stroke-width:1.7;fill:none;
  stroke-dasharray:7 11;animation:axwire 1.5s linear infinite;
  animation-delay:var(--d,0ms)}
@keyframes axwire{from{stroke-dashoffset:36} to{stroke-dashoffset:0}}

/* everything arrives in sequence behind the heading */
.axflow__box,.axflow__tag{opacity:0;transform:translateY(12px);
  transition:opacity .7s var(--axease),transform .7s var(--axease);
  transition-delay:var(--d,0ms)}
.axflow.is-on .axflow__box,.axflow.is-on .axflow__tag{opacity:1;transform:none}
.axflow__wires,.axflow__legs,.axflow__pill,.axflow__spine{
  opacity:0;transition:opacity 1s var(--axease) .35s}
.axflow.is-on .axflow__wires,.axflow.is-on .axflow__legs,
.axflow.is-on .axflow__pill,.axflow.is-on .axflow__spine{opacity:1}

/* ============================================================ THE PLATFORM */
body.pg-def .ax--platform{background:var(--axblue);display:grid;
  grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);align-items:center;
  gap:clamp(30px,4vw,70px);
  padding:clamp(60px,9vh,130px) 0 clamp(60px,9vh,130px) var(--dxpad);
  overflow:hidden}
.axplat__say{display:flex;flex-direction:column;align-items:flex-start;
  gap:clamp(26px,4vh,46px)}
body.pg-def .axplat__h,body.pg-def .axplat__h span{color:#fff}
body.pg-def .axplat__h{margin:0;font-family:var(--angular);font-weight:600;
  font-size:clamp(1.8rem,3.5vw,3.5rem);line-height:1.05;letter-spacing:-.026em;
  color:#fff;max-width:17ch}
body.pg-def .axplat__cta{font-family:var(--mono);font-weight:500;font-size:1rem;
  letter-spacing:.22em;text-transform:uppercase;
  background:#fff;color:var(--axblue);padding:20px 40px;display:inline-block;
  transition:background .3s var(--axease),color .3s var(--axease)}
body.pg-def .axplat__cta:hover{background:#000;color:#fff}

/* ---------- the device ----------
   Drawn, not photographed. A stock photograph of a rugged laptop is somebody
   else's hardware, and the screen in it is never the shape of the picture you
   want to put inside it. It runs off the right edge so it reads as a machine
   standing in the room rather than as a product shot on a plinth. */
.axplat__dev{position:relative;justify-self:end;width:100%;
  opacity:0;transform:translateX(40px);
  transition:opacity 1s var(--axease),transform 1s var(--axease)}
.axplat__dev.is-on{opacity:1;transform:none}
.axdev{position:relative;width:min(108%,1020px);margin-right:-5%}
.axdev__handle{display:block;height:16px;width:30%;margin:0 0 -4px 12%;
  background:#1C2026;border:2px solid #343B45;border-bottom:0;border-radius:9px 9px 0 0}
.axdev__body{position:relative;background:#14181D;border:2px solid #343B45;
  border-radius:12px;padding:clamp(14px,1.5vw,24px)}
.axdev__bolt{position:absolute;width:11px;height:11px;border-radius:50%;
  background:#0C0F13;border:1.5px solid #3C444F}
.axdev__bolt--tl{top:9px;left:9px} .axdev__bolt--tr{top:9px;right:9px}
.axdev__bolt--bl{bottom:9px;left:9px} .axdev__bolt--br{bottom:9px;right:9px}
.axdev__screen{background:#000;border:1px solid #000;overflow:hidden}
.axdev__screen img{width:100%;height:auto;display:block}
body.pg-def .axdev__strip{display:flex;align-items:center;gap:10px;padding-top:11px;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.24em;color:#6F7A88}
.axdev__strip em{width:7px;height:7px;border-radius:50%;background:#2B323B;font-style:normal}
.axdev__strip em:first-of-type{background:var(--axwire)}
.axdev__strip span{margin-right:auto}

/* ============================================================ CAPABILITIES
   Paper, three columns, a rule between them. The icons are drawn in the blue
   and nothing else on this ground is. */
/* Six, in two rows of three. The second row is the half of the system the
   first row does not describe: when it runs, what it scores, and who it is
   allowed to be handed to. */
body.pg-def .ax--caps{background:var(--axpaper);color:#000;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  row-gap:clamp(40px,6vh,86px);
  padding:clamp(56px,8vh,110px) var(--dxpad)}
body.pg-def .axcap:nth-child(3n+1){border-left:1px solid rgba(0,0,0,.26)}
body.pg-def .axcap:nth-child(3n){border-right:1px solid rgba(0,0,0,.26)}
.axcap{display:flex;flex-direction:column;
  padding:clamp(10px,2.4vw,46px) clamp(16px,2.6vw,50px);
  border-left:1px solid rgba(0,0,0,.26)}
body.pg-def .axcap h3{margin:0;font-family:var(--angular);font-weight:700;
  font-size:clamp(1.3rem,2vw,2rem);line-height:1.08;letter-spacing:-.02em;color:#000}
.axcap__i{display:block;width:clamp(96px,11vw,172px);height:auto;
  margin:clamp(36px,6vh,86px) auto clamp(36px,6vh,86px);color:var(--axwire)}
body.pg-def .axcap p{margin:auto 0 0;font-family:var(--angular);font-weight:500;
  font-size:clamp(.98rem,1.08vw,1.08rem);line-height:1.5;color:#000;text-align:justify}

/* The prefix carries into the media query for the same reason it carries
   outside it: a bare .ax--caps here is (0,1,0) and loses to the (0,2,1) rule
   above, so the columns stayed three wide on a phone. */
@media (max-width:1100px){
  body.pg-def .ax--intro,body.pg-def .ax--platform{grid-template-columns:minmax(0,1fr)}
  body.pg-def .ax--platform{padding-inline:var(--dxpad);gap:clamp(36px,6vh,60px)}
  body.pg-def .ax--intro{min-height:0}
  .axdev{width:100%;margin-right:0}
  .axdev__handle{width:30%;margin-left:14%}
  .axplat__dev{transform:none}
  body.pg-def .ax--caps{grid-template-columns:1fr;gap:clamp(30px,5vh,52px)}
  body.pg-def .axcap{border-left:0;border-top:1px solid rgba(0,0,0,.26);padding-inline:0}
  body.pg-def .axcap:last-child{border-right:0}
  body.pg-def .axcap p{text-align:left}
  body.pg-def .axcap__i{margin-block:clamp(26px,4vh,44px)}
}
@media (max-width:620px){
  .axflow{overflow-x:auto;overscroll-behavior-x:contain}
  .axflow__svg{min-width:720px}
}
@media (prefers-reduced-motion:reduce){
  .axflow__w{animation:none}
  .ax__shot img,.axplat__dev,.axflow__box,.axflow__mark,
  .axflow__wires,.axflow__heads,.axflow__frame{
    opacity:1;transform:none;transition:none}
}
