/* WiFiDrive — wifidrive.app
   Tokens and components. Values are the device firmware's, and docs_check.py
   fails on a token that differs; the system that governs them is
   ../brand/system.md. Light is the default; dark follows prefers-color-scheme.

   Three things to know before editing:
   — Two border weights. --line separates surfaces and rows, and edges a
     chip; --edge outlines a field. A button has a fill, not an outline: a
     line edge is a chip's. Never swap them.
   — A button's fill and its states are a layer of the ink, --hov, laid over
     what is under it, never a color of its own: an opaque fill matches some
     ground and vanishes on it.
   — Disabled is stated in ink and edge, never in opacity: fading a control
     fades the label that explains why it is off. Off states live in one
     block at the end of this file so they outrank every variant. */

:root{
  --bg:#eaecf2; --card:#ffffff; --fg:#14161a; --dim:#5a6069;
  --line:#ced3de; --edge:#7f8797;
  --a:var(--fg); --as:var(--fg);
  --hov:#080a0e1a;
  --usb:#008c3f;    --usbs:#007131;    --usbt:#e0f1e8;
  --wifi:#0062d4;   --wifis:#0057bf;   --wifit:#e0ecfa;
  --setup:#7d1bd9;  --setups:#6c34c1;  --setupt:#efe4fa;
  --switch:#7d5200; --switcht:#fcf1de;
  --fail:#b3181b;   --failt:#fdeaea;
  --r-ctl:10px; --r-card:14px;
  --sh:0 1px 2px #080a0e0f,0 10px 24px #080a0e21;
  --ff:-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif;
  --fm:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --measure:660px;
}
@media(prefers-color-scheme:dark){
  :root{
    --bg:#0f1115; --card:#171a21; --fg:#e9ebf0; --dim:#98a0ae;
    --line:#262b35; --edge:#5e697e;
    --hov:#e9ebf01a;
    --usb:#3ddc84;    --usbs:#3ddc84;    --usbt:#10231a;
    --wifi:#77b3ff;   --wifis:#77b3ff;   --wifit:#101c2e;
    --setup:#b39bff;  --setups:#b39bff;  --setupt:#1b1630;
    --switch:#ffc470; --switcht:#2a2011;
    --fail:#ff8080;   --failt:#2a1414;
    --sh:none;
  }
}

/* --- base --- */
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--fg);font:16px/1.6 var(--ff);
  -webkit-text-size-adjust:100%}
h1,h2,h3{margin:0;letter-spacing:-.01em;font-weight:600}
/* The scale's two weights: the browser draws b and strong at 700. */
b,strong{font-weight:600}
h1{font-size:36px;line-height:1.1;letter-spacing:-.015em}
h2{font-size:30px;line-height:1.2}
h3{font-size:20px;line-height:1.3}
p{margin:0;max-width:var(--measure);text-wrap:pretty}
/* What a script hides stays hidden whatever display its class gives it. */
[hidden]{display:none!important}
.dim{color:var(--dim);font-size:14px;line-height:1.5}
/* A link in text: the sentence's ink over a 1 px --edge rule that takes the
   ink on hover. The rule is the only mark, and --edge holds 3:1 on the page
   and a card in both schemes (system.md §copy-rules-the-components-assume).
   Longhands only: Safari reads the shorthand's color and thickness from 26.2. */
a,.lnk{text-decoration-line:underline;text-decoration-thickness:1px;
  text-underline-offset:.25em;text-decoration-color:var(--edge)}
a{color:inherit}
a:hover,.lnk:hover{color:var(--fg);text-decoration-color:currentColor}
/* On a tint --edge falls under 3:1: a notice's link is underlined in its ink. */
.al a{text-decoration-color:currentColor}
code{font:.9em/1.5 var(--fm);background:var(--bg);border:1px solid var(--line);
  border-radius:var(--r-ctl);padding:1px 6px}
pre{margin:0;font:14px/1.5 var(--fm);background:var(--bg);
  border:1px solid var(--line);border-radius:var(--r-ctl);padding:9px 11px;
  overflow-x:auto}
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;
    animation-iteration-count:1!important;transition-duration:.01ms!important}
}
@media(max-width:760px){h1{font-size:30px;line-height:1.15}h2{font-size:24px}}

/* --- layout --- */
.wrap{max-width:1120px;margin:0 auto;padding:0 16px}
.sec{padding:48px 0;display:flex;flex-direction:column;gap:24px}
.c{background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-card);padding:24px}
.row{display:flex;gap:16px;flex-wrap:wrap}
.row>*{flex:1;min-width:300px}   /* cards only — never buttons */
.btns{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.stack{display:flex;flex-direction:column;gap:12px;max-width:340px}

/* --- the lockup, brand.md §lockup --- */
/* Mark box 1.47 x the wordmark's font size, gap 0.24 x it, at 23 px: 34 px,
   the full form's floor, and 5.5 px. The wordmark's own height IS its cap
   height, because brand/logo/wordmark.svg is cut to its ink, so 0.688 x 23 is
   15.8 and the width follows at 7.02 x that. One ink through currentColor — the word is
   never two hues — while the mark keeps its pair and swaps drawing with the
   theme. */
.hd{display:flex;align-items:center;gap:16px;padding:16px 0}
.lk{display:inline-flex;align-items:center;gap:5.5px;color:var(--fg);
  text-decoration:none}
.lk>picture>img{width:34px;height:34px;display:block}
.lk>svg{height:15.8px;width:auto;display:block}

/* --- buttons --- */
/* The secondary is tonal: --hov for its fill and no border, so it has a
   surface of its own on the grey page and in a white card alike, and never
   reads as the chip's line edge. Hover lays the layer twice, pressed three
   times. */
.b{font:600 14px/1.2 var(--ff);padding:11px 14px;border-radius:var(--r-ctl);
  border:1px solid transparent;background:var(--hov);color:var(--fg);
  cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;
  gap:8px;transition:background-color .12s;text-decoration:none}
.b:hover{background-image:linear-gradient(var(--hov),var(--hov))}
.b:active{background-image:linear-gradient(var(--hov),var(--hov)),linear-gradient(var(--hov),var(--hov))}
.b:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
/* A link, a question's summary and a snippet that scrolls, which takes the
   keyboard's focus, take the same ring as a button: every focusable thing
   shows one (system.md §the-floors). */
a:focus-visible,summary:focus-visible,pre:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
/* The primary is the accent's solid partner and its ink, and the ink is the
   theme's: white in light, --bg in dark (system.md §who-carries-what). The
   site's accent is --fg; the installer's card sets USB's. */
/* background-color, not the shorthand, which would clear the hover's and
   the press's layers that .b lays over it. */
.b.pri{background-color:var(--as);border-color:var(--as);color:#fff}
@media(prefers-color-scheme:dark){.b.pri{color:var(--bg)}}
.b.big{padding:13px 18px}
.b.sm{padding:8px 12px}
.b svg{width:18px;height:18px;flex:none}
/* The destructive button is the device's own: --fail ink and border, never a
   red fill. */
.b.dg,.b.dg:hover{color:var(--fail);border-color:var(--fail)}
/* The destructive one keeps its --fail outline and no fill: never red, never
   the tone of a choice that is safe to make. */
.b.dg{background-color:transparent}
/* An action inside a sentence: a button with a link's declarations, the
   underline from the link's rule. */
.lnk{background:none;border:0;padding:0;font:inherit;color:inherit;cursor:pointer}
.lnk:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
/* The icon button, 40 px with no border; a menu's summary is one. */
.ib{width:40px;height:40px;display:grid;place-items:center;border-radius:var(--r-ctl);
  border:1px solid transparent;background:none;color:var(--dim);cursor:pointer}
.ib:hover{background:var(--hov);color:var(--fg)}
.ib:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
.ib svg{width:18px;height:18px}

/* --- fields --- */
/* --edge and the control radius, like anything else you click into. The label
   sits above the field and not beside it: a name and a field on one line is
   the layout that breaks first at 390 px. */
label{display:flex;flex-direction:column;gap:6px;font:14px/1.5 var(--ff);
  color:var(--dim)}
input,select{font:16px/1.4 var(--ff);color:var(--fg);background:var(--card);
  border:1px solid var(--edge);border-radius:var(--r-ctl);padding:10px 12px}
/* Safari draws a select natively and drops its padding; a height reaches it. */
select{height:44px}
input:focus-visible,select:focus-visible{outline:2px solid var(--fg);
  outline-offset:2px}
/* A field that failed is its focus ring in the failure ink. The firmware's
   #pw.er is upstream for the ink and the weight and not for where the ring
   sits: its offset is -1 because its focus ring's is, and here both are 2, so
   a field being corrected never carries two rings at two distances
   (system.md §states). The sentence under it takes the same ink. */
input[aria-invalid="true"]{outline:2px solid var(--fail);outline-offset:2px}
.dim.er{color:var(--fail)}

/* --- status line: a dot and the state it names, never a message (that is a
   notice) and never color on the words --- */
/* two children only: the dot, and ONE element holding the name. Text nodes
   put straight into .st become flex items and split the line. */
.st{display:flex;gap:9px;align-items:flex-start}
.st>i{width:9px;height:9px;border-radius:999px;background:var(--dim);
  flex:none;margin-top:6px}
.st>p,.st>span{margin:0;min-width:0}
.st.usb>i{background:var(--usb)}
.st.wifi>i{background:var(--wifi)}
.st.setup>i{background:var(--setup)}
.st.warn>i{background:var(--switch)}
.st.fail>i{background:var(--fail)}
.st.wait>i{background:transparent;border:2px solid var(--edge)}
.st.wait{color:var(--dim)}

/* --- progress --- */
/* the track is --line, filled, not a --bg well with a border: on a white
   card a --bg track measures 1.18:1 and reads as nothing at 6px tall. */
.bar{height:6px;background:var(--line);border-radius:999px;
  overflow:hidden;flex:1}
.bar>i{display:block;height:100%;background:var(--a)}
.pct{font:600 14px/1 var(--fm);font-variant-numeric:tabular-nums;flex:none;
  min-width:auto}

/* --- notice: the device's strip, its status's ink on its tint
   (system.md §the-rules-the-color-carries). Amber for a change the visitor did not
   cause or a hint, green when done, red when they cannot go on. --- */
.al{display:flex;gap:12px;align-items:flex-start;background:var(--switcht);
  color:var(--switch);border:1px solid var(--line);border-radius:var(--r-card);
  padding:14px 16px}
.al.ok{background:var(--usbt);color:var(--usbs)}
.al.fail{background:var(--failt);color:var(--fail)}
.al.setup{background:var(--setupt);color:var(--setups)}
.al.sticky{position:sticky;top:0;z-index:20;box-shadow:var(--sh)}

/* --- table: rules between rows only --- */
.tbl{background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-card);overflow:hidden}
.tbl table{width:100%;border-collapse:collapse;font:16px/1.5 var(--ff)}
.tbl th{text-align:left;padding:11px 14px;font:600 14px/1.3 var(--ff);
  color:var(--dim);border-bottom:1px solid var(--line)}
.tbl td{padding:12px 14px;border-bottom:1px solid var(--line)}
.tbl tr:last-child td{border-bottom:none}
/* A column that sorts, and a second line under a cell's value. */
.tbl th button{font:inherit;color:inherit;background:none;border:0;padding:0;
  cursor:pointer;display:inline-flex;align-items:center;gap:5px}
.tbl th button:hover,.tbl th[aria-sort] button{color:var(--fg)}
.tbl th button i{font-style:normal;font-size:12px}
.tbl td .dim{display:block;margin-top:3px}
.tbl td.n a{font-weight:600}
.tbl td input{width:100%;max-width:340px}
/* A table carrying a menu lets it out. Nothing in a row has a fill, so the
   clip was drawing nothing at the corners, and it cut a row's popover off at
   the table's edge — not only the last row's: any row's with less than a
   popover's height of table under it. The tables with no menu keep it. */
.tbl:has(.menu){overflow:visible}
@media(max-width:520px){
  .tbl thead{display:none}
  .tbl tr{display:block;position:relative;border-bottom:1px solid var(--line);
    padding:6px 0}
  .tbl tr:last-child{border-bottom:none}
  /* A cell is its column's name at the left and its value at the right,
     the value's second line under it. */
  .tbl td{display:block;text-align:right;border:none;padding:6px 14px}
  .tbl td::before{content:attr(data-th);float:left;margin-right:16px;
    color:var(--dim);font-size:14px}
  .tbl td .st,.tbl td .btns{justify-content:flex-end}
  /* A size keeps its note on its own line. */
  .tbl td>.pct+.dim{display:inline;margin:0 0 0 8px}
  .tbl td:first-child{text-align:left;font-weight:600;padding-top:10px}
  .tbl td:first-child::before{content:none}
  /* A row's menu sits at its top right, beside the name. */
  .tbl td:has(>.menu){position:absolute;top:6px;right:0;padding:4px 6px}
  .tbl tr:has(.menu)>td:first-child{padding-right:56px}
}

/* --- menus: a row's actions, and the account --- */
/* A <details> and what it opens: one to open, the right weight for an action
   nobody takes twice a week. The account control is the same menu worn as the
   company's name at the right of the header. */
.menu{position:relative}
.menu>summary{list-style:none;width:40px;height:40px;display:grid;
  place-items:center;border-radius:var(--r-ctl);border:1px solid transparent;
  color:var(--dim);cursor:pointer;margin-left:auto}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary:hover,.menu[open]>summary{background:var(--hov);color:var(--fg)}
.menu>summary:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
.menu svg{width:18px;height:18px}
.pop{position:absolute;right:0;top:44px;z-index:5;min-width:170px;
  background:var(--card);border:1px solid var(--line);
  border-radius:var(--r-ctl);box-shadow:var(--sh);padding:6px;display:flex;
  flex-direction:column}
.pop form{display:contents}
.mi{font:16px/1.4 var(--ff);text-align:left;background:none;border:0;
  color:var(--fg);padding:9px 10px;border-radius:var(--r-ctl);cursor:pointer;
  text-decoration:none}
.mi:hover{background:var(--hov)}
.mi.dg{color:var(--fail)}
.menu.acct{margin-left:auto}
.menu.acct>summary{width:auto;height:auto;padding:8px 10px;gap:8px;
  display:inline-flex;align-items:center;font:600 14px/1.2 var(--ff);
  color:var(--fg)}
.menu.acct>summary svg{width:16px;height:16px;color:var(--dim)}
.menu.acct .pop{top:42px}

/* --- overlay: the firmware's #ov, a scrim and a card --- */
/* Its values are the device's. */
.ov{position:fixed;inset:0;background:#080a0e80;display:grid;
  place-items:center;padding:16px;z-index:9}
.ov>.c{max-width:420px;width:100%;box-shadow:var(--sh);display:flex;
  flex-direction:column;gap:16px}
/* A card longer than the window scrolls inside the scrim; dvh, where the
   browser has it, leaves out a phone's moving toolbar. */
.ov>.c{max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);overflow:auto}

/* --- media --- */
/* A photo or a video in a frame; its aspect is set where it is used. A photo
   on white stays white in both schemes (.fit), shown whole; a frame inside
   a card takes the control's radius. Every video that plays on its own
   carries its play and pause, and under reduced motion waits on its poster
   with the play showing. */
.frame{position:relative;display:block;margin:0;aspect-ratio:16/9;
  border-radius:var(--r-card);overflow:hidden;border:1px solid var(--line);
  background:var(--bg)}
.frame>img,.frame>picture>img,.frame>video{width:100%;height:100%;display:block;object-fit:cover}
/* An animated image is a <picture> whose still is its source under reduced
   motion; the picture itself takes no box. */
.frame>picture{display:contents}
.frame.fit{background:#fff}
.frame.fit>img,.frame.fit>picture>img{object-fit:contain}
.c .frame{border-radius:var(--r-ctl)}
.frame>button{position:absolute;right:12px;bottom:12px;width:40px;height:40px;
  border-radius:999px;border:0;background:#080a0ec7;color:#fff;display:grid;
  place-items:center;cursor:pointer}
.frame>button:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
.frame>button svg{width:18px;height:18px;display:block}
/* A video pressed to play (data-press) shows its play at 96 px in the
   middle until it plays, then the corner's pause like every other video;
   site.js marks the frame data-playing while it plays. On the phone it is
   64 px, the icon half the button as on the desktop: 96 covered a third of
   a 390 px video, and the desktop's proportion would fall under a
   finger's 44 px. */
.frame:not([data-playing])>video[data-press]+button{left:calc(50% - 48px);
  top:calc(50% - 48px);right:auto;bottom:auto;width:96px;height:96px}
.frame:not([data-playing])>video[data-press]+button svg{width:48px;height:48px}
@media(max-width:760px){
  .frame:not([data-playing])>video[data-press]+button{left:calc(50% - 32px);
    top:calc(50% - 32px);width:64px;height:64px}
  .frame:not([data-playing])>video[data-press]+button svg{width:32px;height:32px}
}

/* --- questions --- */
.questions{border-top:1px solid var(--line)}
.questions details{border-bottom:1px solid var(--line)}
.questions summary{padding:12px 0;font:600 16px/1.5 var(--ff);cursor:pointer;
  list-style:none;display:flex;justify-content:space-between;gap:16px}
.questions summary::-webkit-details-marker{display:none}
.questions summary::after{content:"+";color:var(--dim);font:400 20px/1 var(--ff)}
.questions details[open] summary::after{content:"\2212"}
.questions p{padding:0 0 12px;color:var(--dim)}

/* --- the header's links --- */
.hd>.nav{margin-left:auto;display:flex;align-items:center;gap:24px}
/* Navigation says what it is by where it stands: the header's links and the
   footer's columns have no underline until hover. */
.hd>.nav>a:not(.b),.ft nav a{text-decoration-line:none}
.hd>.nav>a:not(.b):hover,.ft nav a:hover{text-decoration-line:underline}

/* --- a label over a head: the caption size, set in capitals --- */
.kick{font:600 12px/1.5 var(--ff);letter-spacing:.06em;text-transform:uppercase;
  color:var(--dim)}
.head{display:flex;flex-direction:column;gap:12px;max-width:var(--measure)}

/* --- ticks: a list whose every line is a claim. The tick is --fg: green is
   USB mode, and a green tick would be the palette meaning something else. */
.ticks{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:12px}
.ticks li{display:flex;gap:12px;align-items:flex-start}
.ticks svg{width:18px;height:18px;flex:none;margin-top:4px;color:var(--fg)}
/* A line the board does not have: crossed out, in --dim. */
.ticks li.no,.ticks li.no svg{color:var(--dim)}

/* --- a row led by an icon --- */
.irow{display:flex;gap:12px;align-items:flex-start}
.irow>svg{width:24px;height:24px;flex:none;color:var(--dim)}
.irow>div{display:flex;flex-direction:column;gap:4px}

/* --- quotes: the problem in the words of the people who have it --- */
.quote{margin:0;display:flex;flex-direction:column;justify-content:space-between;
  gap:16px;padding:24px}
.quote blockquote{margin:0;font-size:20px;line-height:1.5}
.quote figcaption{font:14px/1.5 var(--ff);color:var(--dim)}

/* --- a price and what it covers --- */
/* Its caption wraps under the amount in a narrow card rather than out of it. */
.price{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;row-gap:2px}
.price>span{white-space:nowrap}
.price b{font:600 30px/1.2 var(--ff);letter-spacing:-.01em}

/* --- a fact, as a label and its value --- */
.tile{display:flex;flex-direction:column;gap:4px}
.tile b{font:600 20px/1.3 var(--ff)}

/* --- a chip: a word with a --line edge, never a status fill --- */
.chip{align-self:flex-start;display:inline-flex;align-items:center;
  font:600 14px/1.2 var(--ff);padding:4px 8px;border:1px solid var(--line);
  border-radius:var(--r-ctl);background:var(--card);color:var(--fg)}

/* --- a band: rules above and below, no fill --- */
.band{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:24px 0;display:flex;align-items:center;gap:32px}
.band ul{list-style:none;margin:0;padding:0;display:flex}

/* --- a head that keeps its level in the outline and takes the size of an
   h3, where the page wants a smaller head than its level draws --- */
.h3{font-size:20px;line-height:1.3}

/* --- words for a screen reader alone, as the struck price's "Was" --- */
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  white-space:nowrap}

/* --- the footer, in columns --- */
.ft{border-top:1px solid var(--line);padding:32px 0 48px;display:grid;
  grid-template-columns:minmax(0,2fr) repeat(3,minmax(0,1fr));gap:24px;
  font:14px/1.5 var(--ff);color:var(--dim)}
.ft nav{display:flex;flex-direction:column;gap:8px}
.ft nav>b{color:var(--fg);font-weight:600}

/* --- the contact form: fields inside a card, on the card's ground --- */
textarea{font:16px/1.4 var(--ff);color:var(--fg);background:var(--card);
  border:1px solid var(--edge);border-radius:var(--r-ctl);padding:10px 12px;
  resize:vertical;min-height:140px}
textarea:focus-visible{outline:2px solid var(--fg);outline-offset:2px}
.form{display:flex;flex-direction:column;gap:16px;padding:24px}
.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
@media(max-width:520px){.two{grid-template-columns:1fr}}
/* A field no person fills, and a bot that fills every field fills this one.
   Moved off the screen rather than hidden, which some bots skip. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* --- steps: the installer's rail. A badge per step on a line that runs to
   the next; the step being done in --fg, a done one in the accent's solid
   partner and its line in the accent, the steps ahead in --dim. --- */
.steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.steps>li{display:grid;grid-template-columns:30px minmax(0,1fr);column-gap:16px;flex:1 1 0}
.steps>li:last-child{flex:0 0 auto}
.steps .mark{display:flex;flex-direction:column;align-items:center}
.steps .mark>b{width:30px;height:30px;border-radius:999px;border:1px solid var(--line);
  background:var(--card);display:grid;place-items:center;flex:none;font:600 14px/1 var(--ff)}
.steps .mark>b svg{width:16px;height:16px}
.steps .mark>i{flex:1;width:2px;min-height:24px;margin:6px 0;border-radius:999px;background:var(--line)}
.steps>li:last-child .mark>i{display:none}
/* The title's first line centers on its badge. */
.steps .txt{display:flex;flex-direction:column;gap:5px;padding:1px 0 24px}
.steps>li:last-child .txt{padding-bottom:0}
.steps>.on .mark>b{background:var(--fg);border-color:var(--fg);color:var(--bg)}
.steps>.ok .mark>b{background:var(--as);border-color:var(--as);color:#fff}
@media(prefers-color-scheme:dark){.steps>.ok .mark>b{color:var(--bg)}}
.steps>.ok .mark>i{background:var(--a)}
.steps>.off h3{color:var(--dim)}

/* --- pick: one choice of several, the picked one with a second border
   drawn inside --- */
.pick{display:flex;gap:8px;flex-wrap:wrap}
.pick .b[aria-pressed="true"]{border-color:var(--fg);box-shadow:inset 0 0 0 1px var(--fg)}

/* --- swipe: a row that scrolls sideways on a phone, the next card showing
   at the edge; its columns are set where it is used --- */
.swipe{overflow-x:auto;scroll-snap-type:x mandatory;margin:0 -16px;padding:0 16px 4px;
  scroll-padding:0 16px;scrollbar-width:none}
.swipe::-webkit-scrollbar{display:none}
.swipe>*{scroll-snap-align:start}
.swipe:focus-visible{outline:2px solid var(--fg);outline-offset:2px}

/* --- rows: a list ruled between its rows, and around them on the page;
   inside a card, the card is the edge --- */
.rows{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.rows>*{padding:12px 0;border-bottom:1px solid var(--line)}
.c.rows{border-top:0}
.c.rows>:last-child{border-bottom:0}

/* --- the site's header: the lockup, Distributors, Buy it and Remote. On a
   phone it stays on screen with Buy it and a menu for the rest, and an
   anchor lands under it rather than behind it. On the remote's panel
   (.panel) the company's menu stands where Remote does, and on a phone it
   is all the header keeps beside the lockup. --- */
.top .menu:not(.acct){display:none}
/* A long company name is cut short on one line before it pushes the lockup
   off it or folds the menu in two. */
.top .lk{flex:none}
.top .nav,.top .menu.acct{min-width:0}
.top .menu.acct>summary{max-width:100%}
.top .menu.acct>summary>span{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.top .menu.acct>summary>svg{flex:none}
@media(max-width:760px){
  .top{position:sticky;top:0;z-index:8;background:var(--bg);
    border-bottom:1px solid var(--line)}
  .top .hd{padding:12px 0}
  .top .nav{gap:8px}
  .top .nav>a,.top .nav .b:not(.pri){display:none}
  .top .menu:not(.acct){display:block}
  .top.panel .nav .b{display:none}
  main [id]{scroll-margin-top:72px}
  .ft{grid-template-columns:repeat(2,minmax(0,1fr));gap:24px 16px;font-size:16px}
  .ft>div:first-child{grid-column:1/-1}
  .ft nav{gap:12px}
}

/* --- the price struck, for the launch tier (commerce.md §prices): Free's
   size, quieter in weight and ink, its "Was" said through .vh --- */
.was{color:var(--dim);font-weight:400}
.price .was{font:400 30px/1.2 var(--ff)}
.nw{white-space:nowrap}

/* --- the band's logos, without end: two copies of the list side by side,
   the track moving by one copy's width, the second aria-hidden. A click, a
   tap, Enter or Space pauses it and another sets it going, and it stops
   under the pointer, because moving content over 5 s wants a pause a
   keyboard and a touch can reach (WCAG 2.2.2). Under reduced motion it
   stands still and scrolls by hand. Each logo is a mask in the quiet ink,
   never the brand's colors. --- */
.band>.kick{flex:none}
.mq{flex:1;min-width:0;overflow:hidden;cursor:pointer;
  -webkit-mask-image:linear-gradient(90deg,#0000,#000 48px,#000 calc(100% - 48px),#0000)}
/* The mask clips the band's own outline, so its ring is drawn on the band. */
.band:has(.mq:focus-visible){outline:2px solid var(--fg);outline-offset:2px}
.mq-t{display:flex;width:max-content;animation:mq 72s linear infinite}
.mq[aria-pressed="true"] .mq-t{animation-play-state:paused}
/* Only a pointer that hovers: on a phone a tap leaves :hover stuck, and the
   second tap would never set the band going. */
@media(hover:hover){.mq:hover .mq-t{animation-play-state:paused}}
.band .mq ul{flex-wrap:nowrap;align-items:center;gap:48px;padding-right:48px}
.band li{display:flex;align-items:center;color:var(--dim)}
/* -webkit-mask alone: Chrome 109 draws no other, and every browser since
   reads it (system.md §the-floors). */
.lgo{display:block;background:currentColor;-webkit-mask-size:contain;
  -webkit-mask-repeat:no-repeat;-webkit-mask-position:center}
@keyframes mq{to{transform:translateX(-50%)}}
@media(prefers-reduced-motion:reduce){.mq{overflow-x:auto;cursor:auto}
  .mq-t{animation:none}.mq ul[aria-hidden]{display:none}}
@media(max-width:760px){.band{flex-direction:column;align-items:flex-start;gap:12px}
  .band>.mq{width:100%}}

/* --- chat: a conversation in bubbles, the other side's in the --fg fill
   and ours on the card. A bubble points at its sender from its bottom
   corner, which it leaves square, as a chat app draws it; the line around
   ours is a triangle in --line under one in --card, a pixel in. --- */
.chat{list-style:none;margin:0;padding:0 8px;display:flex;flex-direction:column;gap:16px}
.chat li{display:flex;flex-direction:column;gap:6px;max-width:440px}
.chat li.you{align-self:flex-end;align-items:flex-end}
.chat li>p{position:relative;font-size:16px;line-height:1.5;padding:12px 16px;
  border-radius:var(--r-ctl);border:1px solid var(--line);background:var(--card)}
.chat li.you>p{background:var(--fg);border-color:var(--fg);color:var(--bg);
  border-bottom-right-radius:0}
.chat li.us>p{border-bottom-left-radius:0}
.chat li>p::before,.chat li.us>p::after{content:"";position:absolute;bottom:-1px;
  width:9px;height:13px}
.chat li.you>p::before{right:-9px;background:var(--fg);clip-path:polygon(0 0,100% 100%,0 100%)}
.chat li.us>p::before{left:-9px;background:var(--line);clip-path:polygon(100% 0,100% 100%,0 100%)}
.chat li.us>p::after{left:-8px;bottom:0;height:11px;background:var(--card);
  clip-path:polygon(100% 0,100% 100%,0 100%)}
@media(max-width:760px){.chat li{max-width:88%}}

/* --- off states, last in the file and on purpose --- */
/* Every variant above states its own ink — .b.pri, .b.dg — so the disabled
   state has to be declared after all of them to win. Anything added later
   goes here too, not next to its variant. --dim label at 6.34:1, --line edge,
   no fill: plainly inactive, still readable. */
.b[disabled],.b.pri[disabled],.b.dg[disabled]{
  color:var(--dim);border-color:var(--line);background:none;
  cursor:not-allowed}
.b[disabled]:hover{border-color:var(--line)}
.mi:disabled{color:var(--dim);background:none;cursor:not-allowed}
