/*
    RFBZ — the design system. One stylesheet, every page.

    This file is the whole visual language of the site, in the order a page uses
    it, and every page that is not the storefront loads it:

        tokens  →  the room  →  the navbar  →  buttons  →  section furniture
        →  components  →  the footer  →  motion

    WHAT BELONGS HERE. Anything more than one page draws: the palette, the room
    behind everything, the capsule navbar, buttons, section heads, the dotted
    rule, the card and panel shells, the table, the form field, the message, the
    status pill, the footer. A page's own <style> block is for what only that
    page is: the storefront's hero and product tiles, the account page's two
    columns and key rows, the download page's build box, the console's layout.

    WHAT MUST NOT HAPPEN HERE, each of which has shipped at least once:

      * the mark is a transparent PNG. Screen-blending it to hide a dark panel,
        or cropping it into a circle so the wordmark loses its ends, is the bug
        coming back — see the .brand rules below.
      * `.wrap` sets its sides with LONGHANDS. The shorthand also zeroes the top
        padding, and because a class beats the element selector it silently
        cancelled `main`'s offset on every page that is <main class="wrap">, so
        the first panel started at y=0 and slid under the fixed navbar.
      * one accent for the whole suite. Products are told apart by their artwork
        and their key prefix, never by a different colour card.
      * no cyan ambient light. The palette is black and violet, and the third
        orb used to be #67e8f9.

    Every animation here is decoration and all of it is switched off wholesale
    by the prefers-reduced-motion rule at the end of the file.

    test_shop_page.py reads this file — the wrapper's longhands, `main`'s
    offset, the nav height and the absence of a cyan orb are all asserted, and
    the palette tokens are checked to reach every page through it.
*/

/* ── tokens: the same black + violet the whole suite uses ──────────── */

/* <<rfbz:web>> */
:root{
  /* the palette. Every surface in the suite reads these names; none of them may
     declare a colour of its own. Generated from theme/rfbz_theme.cs. */
  --bg:#050508; --bg2:#09090f; --bg3:#10101c;
  --card:#0b0b14; --card-hi:#15152a;
  --accent:#8b5cf6; --accent2:#c4b5fd; --accent3:#6d28d9;
  --green:#25d0a0; --green2:#7cf5cd; --orange:#ffb454; --red:#ff5f6d; --red2:#ffc9cd;
  --txt:#f5f3ff; --txt2:#a5a2c0; --txt3:#6d6a89;
  --line:#1b1a2c; --line2:#2e2c47;
  /* the same four colours as bare channels, for the glows and washes a hex value
     cannot be fed to rgba(). One form of each colour, not two shades of it. */
  --violet:139,92,246; --green-rgb:37,208,160; --red-rgb:255,95,109; --amber:255,180,84;
  --mono:'JetBrains Mono',ui-monospace,SFMono-Regular,Consolas,monospace;
  /* glass: the frosted recipe and the hairline that edges it. A surface that
     invents its own alpha is a second frosted recipe, not a new one. */
  --glass-bar:rgba(5,5,8,.72); --glass-panel:rgba(11,11,20,.72); --glass-vessel:rgba(11,11,20,.42); --hair:rgba(255,255,255,.06);
  --blur-bar:8px; --blur-rail:10px; --blur-head:8px; --saturate:1.15;
  --artwork:radial-gradient(58% 62% at 18% -8%, rgba(139,92,246,.24), transparent 64%), radial-gradient(50% 56% at 97% 106%, rgba(37,208,160,.10), transparent 62%), linear-gradient(160deg,#0a0614 0%,#050509 50%,#04040a 100%);
  --art-plate:#030307;
  /* geometry: one radius scale, one type step, one entrance. Ask for the step by
     name - a number typed into a corner is how the client and the panel end up
     disagreeing about what a card is. */
  --vessel-r:30px; --pill-r:21px; --panel-r:20px; --card-r:18px; --field-r:14px;
  --chip-r:9px; --btn-r:12px; --sheet-r:22px; --sticker-r:16px;
  --type-page:20px;
  --enter-ms:220ms; --enter-x:-7px;
}
/* <</rfbz:web>> */
:root{
  /* The palette, the glass and the radius steps are the generated rfbz:web block above -
     the same bytes every surface carries. What is left here is what only the site has: one
     ink of its own, its own scale for a page's big panels, and the layout numbers the
     shell's rules read. Its pale red used to be declared here too; the windows were typing
     two shades of their own for it, so it is --red2 in the generated block now. */
  --cyan:#67e8f9;
  --radius:var(--panel-r); --radius-sm:var(--btn-r); --radius-lg:26px;
  --nav-h:64px;
  --pad:22px;
  --wrap:1200px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--txt);
  font:16px/1.65 'Inter',system-ui,-apple-system,'Segoe UI',sans-serif;
  -webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{display:block;max-width:100%}
::selection{background:rgba(var(--violet),.4)}
:focus-visible{outline:2px solid var(--accent2);outline-offset:3px;border-radius:8px}
/* Sides only, as longhands. See the file header: the shorthand cancels the top
   padding and a class beats the element selector below, so the pages that are
   <main class="wrap"> lost their offset under the fixed navbar. */
.wrap{max-width:var(--wrap);margin:0 auto;padding-left:22px;padding-right:22px}
.hidden{display:none}

/* ── the room: slow violet light, masked grid, vignette ─────────────── */
.bg{position:fixed;inset:0;z-index:-1;pointer-events:none;overflow:hidden}
/* Static blobs: blur is pre-computed once, no per-frame animation, so low-end
   GPUs are not asked to re-blur a 62vw circle sixty times a second. */
.bg i{position:absolute;border-radius:50%;filter:blur(56px);opacity:.55;
  will-change:transform;transform:translateZ(0)}
.bg i:nth-child(1){width:62vw;height:62vw;left:-18vw;top:-24vw;
  background:rgba(var(--violet),.32)}
.bg i:nth-child(2){width:44vw;height:44vw;right:-14vw;top:6vh;
  background:rgba(var(--violet),.13)}
.bg i:nth-child(3){width:55vw;height:55vw;left:20vw;top:60vh;
  background:rgba(var(--violet),.16)}
.bg .grid{position:absolute;inset:0;opacity:.45;
  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:70px 70px;
  mask-image:radial-gradient(ellipse 80% 55% at 50% 0%,#000 18%,transparent 76%);
  -webkit-mask-image:radial-gradient(ellipse 80% 55% at 50% 0%,#000 18%,transparent 76%)}
.bg .vig{position:absolute;inset:0;
  background:radial-gradient(ellipse 120% 80% at 50% 0%,transparent 40%,rgba(0,0,0,.7))}
@keyframes drift{0%,100%{transform:translate3d(0,0,0) scale(1)}
  33%{transform:translate3d(4vw,3vh,0) scale(1.13)}
  66%{transform:translate3d(-3vw,-2vh,0) scale(.93)}}

/* ── the floating capsule navbar ────────────────────────────────────── */
.nav-shell{position:fixed;top:14px;left:0;right:0;z-index:60;
  display:flex;justify-content:center;padding:0 16px;pointer-events:none}
.nav{pointer-events:auto;width:100%;max-width:1160px;height:var(--nav-h);
  display:flex;align-items:center;gap:18px;padding:0 12px 0 16px;
  border:1px solid transparent;border-radius:999px;transition:all .3s cubic-bezier(.4,0,.2,1)}
.nav.solid{background:var(--glass-bar);backdrop-filter:blur(var(--blur-bar)) saturate(var(--saturate));
  border-color:var(--line);box-shadow:0 18px 50px -24px rgba(0,0,0,.95)}
.brand{display:flex;align-items:center;gap:10px;font-weight:900;letter-spacing:.16em;
  font-size:15px;white-space:nowrap}
/* A transparent PNG drawn as itself: no blend mode to hide a panel, and no
   circle crop taking the ends off the wordmark. */
.brand img{width:34px;height:34px;object-fit:contain}
.brand .dot{color:var(--accent)}
.nav nav{display:flex;gap:6px;margin-left:10px}
.nav nav a{font-size:13.5px;color:var(--txt2);padding:8px 13px;border-radius:999px;transition:all .2s}
.nav nav a:hover{color:var(--txt);background:rgba(255,255,255,.05)}
.nav nav a[aria-current="page"]{color:var(--txt);background:rgba(var(--violet),.14)}
.nav .spacer{flex:1}
.icon-btn{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;
  border:1px solid var(--line2);color:var(--txt2);background:none;cursor:pointer;transition:all .2s}
.icon-btn:hover{color:var(--accent2);border-color:var(--accent)}
.icon-btn svg{width:17px;height:17px;fill:currentColor}
.burger{display:none}

/* ── buttons ────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;border:0;cursor:pointer;
  font:600 14px 'Inter',sans-serif;padding:12px 22px;border-radius:999px;white-space:nowrap;
  background:linear-gradient(135deg,var(--accent),var(--accent3));color:#fff;
  box-shadow:0 12px 34px -14px rgba(var(--violet),.95);
  transition:transform .2s,box-shadow .2s,filter .2s}
.btn:hover{transform:translateY(-2px);filter:brightness(1.08);
  box-shadow:0 18px 44px -14px rgba(var(--violet),1)}
.btn.sm{padding:9px 18px;font-size:13px}
.btn.ghost{background:transparent;color:var(--txt);border:1px solid var(--line2);box-shadow:none}
.btn.ghost:hover{border-color:var(--accent);color:var(--accent2);background:rgba(var(--violet),.07)}
.btn.wide{width:100%;padding:14px 22px}
/* Delete is the only action in the suite that cannot be undone by pressing it
   again, so it is the only one that looks different. */
.btn.danger{background:transparent;color:var(--red2);border:1px solid rgba(var(--red-rgb),.4);box-shadow:none}
.btn.danger:hover{border-color:var(--red);color:#fff;background:rgba(var(--red-rgb),.14)}
.btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}
.btn[disabled]{opacity:.6;cursor:default;transform:none;filter:none}

/* ── section furniture ──────────────────────────────────────────────── */
main{padding-top:calc(var(--nav-h) + 118px)}
section{padding:34px 0}
.head{margin-bottom:40px}
.head .kicker{font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--accent);
  font-weight:700;margin-bottom:14px}
.head h2{font-size:clamp(2rem,5vw,3.2rem);font-weight:900;letter-spacing:-.035em;line-height:1.02}
.head h2 .thin{color:var(--txt3);font-weight:300}
.head p{color:var(--txt2);margin-top:14px;max-width:640px}
.head.center{text-align:center}
.head.center p{margin-left:auto;margin-right:auto}
/* The dotted rule between sections: one repeating gradient, faded at both ends
   so it reads as a seam rather than as a border. */
.dots{height:9px;margin:64px 0;
  background-image:radial-gradient(rgba(255,255,255,.14) 1.3px,transparent 1.4px);
  background-size:13px 9px;background-repeat:repeat-x;
  mask-image:linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 22%,#000 78%,transparent)}
.rv{opacity:0;transform:translateY(20px);transition:opacity .75s ease,transform .75s ease}
.rv.in{opacity:1;transform:none}

/* ── steps: the numbered/eyebrow cards a page explains itself with ──── */
.steps{display:grid;gap:22px;grid-template-columns:repeat(3,1fr)}
.step{background:var(--bg3);border:1px solid var(--line);border-radius:var(--radius);
  padding:24px 24px 26px}
.step .n{display:inline-flex;width:28px;height:28px;border-radius:var(--chip-r);align-items:center;
  justify-content:center;font:700 13px 'Inter',sans-serif;color:#fff;margin-bottom:14px;
  background:linear-gradient(135deg,var(--accent),var(--accent2))}
.step b{display:block;font-size:15px;margin-bottom:7px}
.step p{color:var(--txt2);font-size:13.5px}

/* ══ components ═══════════════════════════════════════════════════════
   The shared half of every page that is not the storefront. The console's
   own stylesheet layers its layout on top of these rather than inventing a
   second set of them. */

/* ── card and panel shells ──────────────────────────────────────────── */
.card{border:1px solid var(--line);border-radius:var(--radius-lg);padding:34px;
  background:linear-gradient(160deg,rgba(var(--violet),.06),transparent 55%),var(--card);
  box-shadow:0 30px 70px -40px rgba(0,0,0,.9)}
.card h1{font-size:clamp(1.5rem,3vw,2rem);font-weight:800;letter-spacing:-.03em}
.card h1 i{font-style:normal;background:linear-gradient(120deg,var(--accent2),var(--accent));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.card .sub{color:var(--txt2);font-size:14px;margin:10px 0 26px}
.panel{border:1px solid var(--line);border-radius:var(--sheet-r);overflow:hidden;background:var(--card)}
.panel>.head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:15px 18px;
  border-bottom:1px solid var(--line);margin:0}
.panel>.head h2{font-size:16px;font-weight:800;letter-spacing:-.02em}
.panel>.head .n{font-size:12px;color:var(--txt3)}
.empty{padding:34px 18px;text-align:center;font-size:13.5px;color:var(--txt2);
  border:1px dashed var(--line2);border-radius:var(--sticker-r)}
.panel .empty{border:0;border-radius:0}

/* ── a banner: one sentence the page wants read before anything else ── */
.banner{display:flex;gap:14px;border:1px solid var(--line2);border-radius:var(--card-r);
  padding:20px 22px;background:rgba(var(--violet),.05)}
.banner svg{width:20px;height:20px;flex:none;margin-top:3px;stroke:var(--accent2);fill:none;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.banner b{display:block;font-size:14.5px;margin-bottom:5px}
.banner p{color:var(--txt2);font-size:13.5px}
.banner.warn{background:rgba(var(--amber),.05)}
.banner.warn svg{stroke:var(--orange)}

/* ── tabs and chips: the same pill in two sizes ─────────────────────── */
.tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:13px 18px 0}
.tab{border:1px solid var(--line2);background:rgba(0,0,0,.28);color:var(--txt2);
  font:600 13px 'Inter',sans-serif;padding:9px 14px;border-radius:999px;cursor:pointer;
  display:inline-flex;align-items:center;gap:8px;transition:all .2s}
.tab:hover{color:var(--txt);border-color:var(--accent)}
.tab.on{color:#fff;border-color:transparent;
  background:linear-gradient(135deg,var(--accent),var(--accent3));
  box-shadow:0 12px 30px -16px rgba(var(--violet),1)}
.tab .n{font-size:11px;font-weight:700;color:inherit;opacity:.75;font-family:var(--mono)}
.chips{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--line2);
  border-radius:999px;padding:3px;background:rgba(0,0,0,.3)}
.chip{border:0;background:none;color:var(--txt2);font:600 12px 'Inter',sans-serif;
  padding:6px 12px;border-radius:999px;cursor:pointer;transition:all .18s;white-space:nowrap}
.chip:hover{color:var(--txt)}
.chip.on{color:#fff;background:linear-gradient(135deg,var(--accent),var(--accent3));
  box-shadow:0 10px 24px -14px rgba(var(--violet),1)}
.chip:disabled{opacity:.45;cursor:not-allowed}

/* ── fields: the shape every input in the suite wears ───────────────── */
.field{margin-bottom:16px}
.field label{display:block;font-size:12.5px;font-weight:600;color:var(--txt2);margin-bottom:7px}
.input{display:flex;align-items:center;gap:11px;border:1px solid var(--line2);
  border-radius:var(--field-r);padding:0 14px;background:rgba(0,0,0,.35);transition:border-color .2s}
.input:focus-within{border-color:var(--accent)}
.input svg{width:17px;height:17px;flex:none;stroke:var(--txt3);fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.input input,.input select{flex:1;min-width:0;background:none;border:0;outline:0;
  color:var(--txt);font:400 14.5px 'Inter',sans-serif;padding:14px 0}
.input select option{background:var(--bg3);color:var(--txt)}
.input input::placeholder{color:var(--txt3)}
.input input:disabled{opacity:.45}
.input .eye{background:none;border:0;color:var(--txt3);cursor:pointer;padding:6px}
.input .eye:hover{color:var(--accent2)}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:0 16px}
/* The class that actually hides. Declared with the weight to beat anything a
   later rule would bring back with it: it sat on a field with no rule behind
   it once, so signing in asked for the password twice. */
.hide{display:none!important}
.caps{font-size:12px;color:var(--red2);margin:-6px 0 14px}
.switch{margin-top:20px;font-size:13.5px;color:var(--txt2)}
.switch button{background:none;border:0;color:var(--accent2);cursor:pointer;
  font:inherit;font-weight:600;text-decoration:underline}
.tiny{font-size:12px;color:var(--txt3);margin-top:18px;line-height:1.6}

/* ── the search box: built in the markup, never rebuilt by script ───── */
.search{display:flex;align-items:center;gap:9px;border:1px solid var(--line2);
  border-radius:999px;padding:0 13px;background:rgba(0,0,0,.35);min-width:210px}
.search:focus-within{border-color:var(--accent)}
.search svg{width:15px;height:15px;flex:none;stroke:var(--txt3);fill:none;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.search input{flex:1;min-width:0;background:none;border:0;outline:0;color:var(--txt);
  font:400 13.5px 'Inter',sans-serif;padding:10px 0}
.search input::placeholder{color:var(--txt3)}
.search .clear{display:flex;cursor:pointer;color:var(--txt3)}
.search .clear:hover{color:var(--accent2)}
.search .clear svg{width:13px;height:13px;stroke:currentColor}

/* ── status pills, key badges, and one-off links ────────────────────── */
.pill{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;border-radius:999px;padding:4px 10px;border:1px solid}
.pill.ok{color:var(--green2);border-color:rgba(var(--green-rgb),.45);background:rgba(var(--green-rgb),.1)}
.pill.bad{color:var(--orange);border-color:rgba(var(--amber),.45);background:rgba(var(--amber),.1)}
.badge{display:inline-block;font-family:var(--mono);font-size:11.5px;border-radius:8px;
  padding:4px 9px;border:1px solid rgba(var(--violet),.45);background:rgba(var(--violet),.12);
  color:var(--accent2);white-space:nowrap}
.badge.pfx{font-weight:700}
.link{background:none;border:0;color:var(--accent2);font:600 12.5px 'Inter',sans-serif;
  cursor:pointer;text-decoration:underline;padding:0}
.link:hover{color:var(--txt)}
.avatar{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;flex:none;
  font-weight:800;font-size:14px;color:#fff;
  background:linear-gradient(135deg,var(--accent),var(--accent3))}

/* ── messages: the server's own answer, in the server's own words ───── */
.msg{margin-top:14px;font-size:13.5px;border-radius:var(--btn-r);padding:12px 14px;
  border:1px solid var(--line2);color:var(--txt2)}
.msg.bad{border-color:rgba(var(--red-rgb),.45);background:rgba(var(--red-rgb),.08);color:var(--red2)}
.msg.ok{border-color:rgba(var(--green-rgb),.4);background:rgba(var(--green-rgb),.08);color:var(--green2)}
.msg.hide{display:none}

/* ── tallies ────────────────────────────────────────────────────────── */
.stats{display:flex;flex-wrap:wrap;gap:9px}
.stat{display:inline-flex;align-items:baseline;gap:7px;font-size:12px;color:var(--txt2);
  border:1px solid var(--line2);border-radius:999px;padding:6px 12px;background:rgba(0,0,0,.25)}
.stat b{font-size:13px;font-weight:800;color:var(--txt)}
.stat.dim{opacity:.45}
.stat.ok b{color:var(--green2)}
.stat.warn b{color:var(--orange)}

/* ── labelled facts ─────────────────────────────────────────────────── */
.kv{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:10px 18px}
.kv div{font-size:11.5px;color:var(--txt3);letter-spacing:.06em;text-transform:uppercase;
  font-weight:700}
.kv b{display:block;font-size:13px;font-weight:500;color:var(--txt);
  letter-spacing:normal;text-transform:none;margin-top:3px;font-family:var(--mono);
  word-break:break-all}

/* ── the table ──────────────────────────────────────────────────────── */
.tablewrap{overflow-x:auto}
table{width:100%;border-collapse:collapse;font-size:13px;min-width:860px}
thead th{text-align:left;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--txt3);font-weight:700;padding:12px 14px;border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);white-space:nowrap}
tbody td{padding:11px 14px;border-bottom:1px solid var(--line);vertical-align:middle}
tbody tr:hover{background:rgba(var(--violet),.05)}
td.k{font-family:var(--mono);font-size:12.5px;color:var(--accent2);white-space:nowrap}
td.mono{font-family:var(--mono);font-size:12.5px}
td.dim,.dim{color:var(--txt3)}
td.note{max-width:190px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* One row of actions that never wraps: a wrapped action reads as part of the row
   above it, which is how the wrong key gets revoked. The table scrolls sideways
   instead. */
td.rowacts{white-space:nowrap}
td.rowacts .btns{display:flex;gap:7px;justify-content:flex-end}

/* ── a bar and what fills it ────────────────────────────────────────── */
.meters{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:9px 18px}
.meter{display:flex;align-items:center;gap:9px}
.meter label{font-size:10.5px;letter-spacing:.14em;color:var(--txt3);font-weight:700;width:46px}
.meter .bar{flex:1;height:6px;border-radius:999px;background:var(--bg3);overflow:hidden}
.meter .bar i{display:block;height:100%;width:0;border-radius:999px;
  background:linear-gradient(90deg,var(--accent),var(--accent2));transition:width .3s}
.meter em{font-style:normal;font-size:11.5px;color:var(--txt2);font-family:var(--mono);
  width:52px;text-align:right}
.spinner{display:inline-block;width:14px;height:14px;border-radius:50%;
  border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.busy{font-size:13px;color:var(--txt3);margin-top:12px}

/* ── footer ─────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--line);margin-top:56px;padding:52px 0 40px;color:var(--txt3);
  font-size:13.5px}
.foot{display:grid;gap:34px;grid-template-columns:1.3fr 1fr 1fr;align-items:start}
.foot h5{color:var(--txt);font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  margin-bottom:16px}
.foot a{display:block;margin-bottom:9px;transition:color .2s}
.foot a:hover{color:var(--accent2)}
.foot .brand{margin-bottom:14px}
.foot .brand img{width:30px;height:30px}
.legal{margin-top:40px;padding-top:22px;border-top:1px solid var(--line);
  display:flex;justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:12.5px}

@media (max-width:860px){
  .nav nav{display:none}
  .burger{display:grid}
  .foot{grid-template-columns:1fr}
  .steps{grid-template-columns:1fr}
  .card{padding:24px}
  main{padding-top:calc(var(--nav-h) + 92px)}
}
@media (max-width:660px){.grid2{grid-template-columns:1fr}}

/* One blanket for every animation in the suite. Each page's own block repeats
   this for its own keyframes; anything added here is covered by it. */
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  html{scroll-behavior:auto}
  .rv{opacity:1;transform:none}
}
