/* ============================================================
   initcap.pro — the studio, not the instrument.

   Initcap builds and licenses software. MERIDIAN SCP is the
   first of those; it will not be the last. So this stylesheet
   dresses the FIRM, and is deliberately not a copy of the
   product's own skin — a shop wearing one product's identity has
   nowhere to put the second product.

   ── The surface ────────────────────────────────────────────
   Warm paper, white plates, one hairline, and a lot of air. The
   plates lift a little under the pointer and settle back; that is
   the only motion on a page. Everything is built from four
   values — paper, plate, hairline, ink — and a page that needs a
   fifth usually needs less on it instead.

   ── The device ─────────────────────────────────────────────
   The company is called Initcap, so the initial capital is the
   mark: set in a square on the wordmark, and drawn from the name
   on each product's plate. A new product is listed properly on
   the day it exists and does not wait on artwork.

   ── Colour reports a fact ──────────────────────────────────
   Cobalt is the one voice allowed to interrupt: it marks the
   thing on a page you are meant to do next, and the figure you
   are meant to read. Everything saturated beyond that is a
   STATUS — in service, expired, failed. If green appears,
   something is true.

   ── Type ───────────────────────────────────────────────────
   Plus Jakarta Sans for everything a person reads, JetBrains
   Mono for machine text and for figures: keys, paths, SKUs,
   money, counts. Mono used to be the face of every label here,
   which made it mean nothing. Now it means "this is a value, and
   it will line up with the one above it".

   Both are served from /fonts on this origin. No font CDN: on a
   site whose whole claim is that your data does not travel to
   us, a third-party request to render that sentence would
   contradict the page it is rendering. See webapp/fonts/README.md.

   ── The instrument stays dark ──────────────────────────────
   body.app — app.initcap.pro — keeps the console palette at the
   bottom of this file, because the console it wraps is dark and
   a daylight frame around it would look like a mistake. The firm
   is daylight; the product is night. That split is on purpose.
   ============================================================ */

/* ── the faces ──────────────────────────────────────────────
   One file per family per subset. These are VARIABLE fonts, so
   the single file answers for every weight from 300 to 800 and
   the browser fetches one resource instead of six.

   font-display:swap — the page is readable in the fallback
   immediately and reflows once. The alternative is a column of
   invisible text on a slow connection, which is worse than a
   reflow on a page that is mostly prose. */
@font-face{
  font-family:'Plus Jakarta Sans';
  src:url(/fonts/PlusJakartaSans-latin.woff2) format('woff2');
  font-weight:200 800;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
    U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,
    U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Plus Jakarta Sans';
  src:url(/fonts/PlusJakartaSans-latin-ext.woff2) format('woff2');
  font-weight:200 800;font-style:normal;font-display:swap;
  /* Customers have names. A checkout that cannot set Łukasz in the
     typeface it set the price in looks broken where it must not. */
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,
    U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,
    U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,
    U+A720-A7FF;
}
@font-face{
  font-family:'JetBrains Mono';
  src:url(/fonts/JetBrainsMono-latin.woff2) format('woff2');
  font-weight:100 800;font-style:normal;font-display:swap;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,
    U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,
    U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';
  src:url(/fonts/JetBrainsMono-latin-ext.woff2) format('woff2');
  font-weight:100 800;font-style:normal;font-display:swap;
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,
    U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,
    U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,
    U+A720-A7FF;
}

:root{
  /* stock and plates */
  --paper:#fafaf8;       /* the page                        */
  --sheet:#ffffff;       /* raised plates                   */
  --wash:#f4f4f0;        /* quiet fill, inset rows          */
  --rule:#e8e8e2;        /* hairlines                       */
  --rule-soft:#f0f0ea;   /* a hairline inside a plate       */
  --rule-hot:#cbd5e1;    /* a hairline asking to be noticed */

  /* ink, in four ranks */
  --ink:#0f172a;         /* blue-black, not a grey          */
  --ink-soft:#475569;    /* secondary text                  */
  --ink-mid:#64748b;     /* third rank                      */
  --ink-faint:#94a3b8;   /* captions, placeholders          */

  /* the brand navy — the [I] mark's own colour, matching the favicons,
     the theme-colour and the brand kit. Deeper than the cobalt scale. */
  --brand:#024981;

  /* cobalt — the one voice allowed to interrupt */
  --c-50:#eef4ff;
  --c-100:#e0ebff;
  --c-500:#3b82f6;
  --c-600:#2563eb;
  --c-700:#1d4ed8;
  --c-800:#1e40af;
  --c-900:#172554;

  /* statuses. Saturated on purpose, and only here. */
  --stamp:#059669;       /* in service, paid, active        */
  --stamp-bg:#ecfdf5;
  --amber:#b45309;       /* attention                       */
  --amber-bg:#fffbeb;
  --star:#f59e0b;        /* a rating, and nothing else      */
  --red:#be123c;         /* refused, failed, revoked        */
  --red-bg:#fff1f2;

  --sans:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,ui-sans-serif,
         system-ui,'Segoe UI',Roboto,'Helvetica Neue',Arial,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,'Cascadia Mono',Consolas,'SF Mono',
         Menlo,monospace;
  /* Kept as an alias. The redesign has no serif, but the name is
     referenced from the app shell's overrides and from a handful of
     inline styles, and an undefined custom property there would
     silently fall back to Times. */
  --serif:var(--sans);

  --r-sm:8px;            /* chips, small controls           */
  --r:12px;              /* buttons, inputs                 */
  --r-lg:16px;           /* plates                          */
  --r-xl:24px;           /* the big ones: banners, modals   */

  /* A plate at rest, and a plate under the pointer. Two shadows
     each: a tight one that seats it on the paper and a wide soft
     one that gives it height. One shadow reads as a border. */
  --lift:0 1px 3px rgba(15,23,42,.03), 0 2px 8px rgba(15,23,42,.02);
  --lift-hi:0 12px 24px -6px rgba(15,23,42,.06),
            0 4px 8px -2px rgba(15,23,42,.03);
  --ease:cubic-bezier(.16,1,.3,1);

  --measure:70ch;        /* prose line length               */
}

*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;min-height:100vh;background:var(--paper);color:var(--ink);
  font:16px/1.65 var(--sans);font-weight:400;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  display:flex;flex-direction:column;
}
::selection{background:var(--c-100);color:var(--c-900)}
a{color:var(--c-700);text-decoration:none}
a:hover{color:var(--c-800);text-decoration:underline;
  text-decoration-thickness:1px;text-underline-offset:2px}
code{font-family:var(--mono);font-size:.875em;font-weight:500}
:focus-visible{outline:2px solid var(--c-600);outline-offset:2px;border-radius:4px}
img,svg{max-width:100%}

/* Said to a screen reader and to nobody else. Used where an icon and a
   figure carry the meaning visually — the bag's count, for instance,
   reads as "3" on screen and "3 licences in your bag" aloud.
   Not display:none, which would remove it from the accessibility tree
   along with everything else. */
.sr{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

/* Figures are mono and tabular, everywhere. A column of prices in a
   proportional face does not line up, and a total that moves sideways
   as it changes looks like a different total. */
.num,.money,.key,.sku,code,table.prices td,table.data td.num,
.price,.tile b{font-variant-numeric:tabular-nums}

/* The site's own scrollbar. Chromium only, and that is fine: where it
   is unsupported the platform's own is used and nothing is lost. */
::-webkit-scrollbar{width:7px;height:7px}
::-webkit-scrollbar-track{background:var(--paper)}
::-webkit-scrollbar-thumb{background:var(--rule-hot);border-radius:999px}
::-webkit-scrollbar-thumb:hover{background:var(--ink-faint)}

/* ── small utilities ────────────────────────────────────────
   These replace inline style="" attributes, which the strict public CSP
   (style-src 'self', no 'unsafe-inline') silently drops. Keeping them as
   classes means the spacing and measure actually apply. */
.mw66{max-width:66ch}.mw64{max-width:64ch}.mw62{max-width:62ch}
.mw60{max-width:60ch}.mw58{max-width:58ch}
.mt4{margin-top:4px}.mt8{margin-top:8px}.mt10{margin-top:10px}.mt12{margin-top:12px}.mt14{margin-top:14px}
.mt16{margin-top:16px}.mt18{margin-top:18px}.mt20{margin-top:20px}.mt22{margin-top:22px}
.mt24{margin-top:24px}.mt28{margin-top:28px}.mt34{margin-top:34px}.mt56{margin-top:56px}
.mb24{margin-bottom:24px}.mtop12{margin:12px 0 0}
.fs12{font-size:12px}.fs125{font-size:12.5px}
.taLeft{text-align:left}.posStatic{position:static}.preWrap{white-space:pre-wrap}
.ic-sub{font-size:11.5px;color:var(--ink-faint);font-weight:500;margin-top:2px}
.mediaThumb{width:160px;height:auto;border:1px solid var(--rule);border-radius:6px}

/* ── media library (WooCommerce-style) ── */
.mediaUpload{margin:18px 0 30px}
.mediaUpload h2{font-size:17px;margin:0 0 14px}
.mediaForm{display:flex;flex-wrap:wrap;gap:14px;align-items:end}
.mediaForm label{display:flex;flex-direction:column;gap:6px;font-size:12.5px;font-weight:600;flex:1 1 160px}
.mediaForm .opt{font-weight:400;color:var(--ink-faint)}
.mediaForm .mediaPosField{flex:0 0 90px}
.mediaForm input,.mediaForm select{padding:9px 11px;border:1px solid var(--rule);
  border-radius:var(--r);font:inherit;background:var(--paper)}
.mediaForm input[type=file]{padding:7px}
.mediaForm>.btn{flex:0 0 auto}
.mediaProduct{margin:0 0 30px}
.mediaHead{display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:0 0 14px;border-bottom:1px solid var(--rule);padding-bottom:8px}
.mediaHead h2{margin:0;font-size:16px}
.mediaGrid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(230px,1fr))}
.mediaCard{position:relative;border:1px solid var(--rule);border-radius:var(--r-lg);
  background:var(--sheet);overflow:hidden;display:flex;flex-direction:column}
.mcThumb{aspect-ratio:16/10;background:#0d1326;display:flex;align-items:center;justify-content:center;overflow:hidden}
.mcThumb img{width:100%;height:100%;object-fit:cover}
.mcVideo{color:#aeb9d6;font:12px/1.5 var(--mono,monospace);text-align:center;padding:10px}
.mcKind{position:absolute;top:8px;left:8px;font-size:10px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:#fff;background:rgba(13,19,38,.66);border-radius:999px;padding:3px 9px}
.mcEdit{display:flex;flex-direction:column;gap:9px;padding:12px}
.mcEdit>input{padding:8px 10px;border:1px solid var(--rule);border-radius:var(--r);font:inherit;font-size:12.5px}
.mcRow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.mcPos{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--ink-soft)}
.mcPos input{width:52px;padding:7px 8px;border:1px solid var(--rule);border-radius:var(--r);font:inherit}
.mcRow .btn.danger{margin-left:auto}
.mediaCard.isDefault{border-style:dashed;opacity:.92}
.mcCap{padding:10px 12px;margin:0;font-size:12px;color:var(--ink-soft);line-height:1.45}
.mb10{margin-bottom:10px}

/* ── Products list (WooCommerce products table) ───────────────── */
.wcProducts td{vertical-align:middle}
.wcProducts th.wcpThumb,.wcProducts td.wcpThumb{width:64px}
.wcpThumb img{width:52px;height:40px;object-fit:cover;border-radius:6px;
  border:1px solid var(--rule);display:block;background:var(--wash)}
.wcpNoImg{display:inline-flex;align-items:center;justify-content:center;
  width:52px;height:40px;border:1px dashed var(--rule);border-radius:6px;
  color:var(--ink-faint);font-size:18px}
.wcpTitle{font-weight:700;color:var(--ink);text-decoration:none}
.wcpTitle:hover{color:var(--c-700);text-decoration:underline}
.wcpSub{font-size:12px;color:var(--ink-soft);margin-top:1px}
.wcpRowActions{font-size:11.5px;margin-top:4px;color:var(--ink-faint)}
.wcpRowActions a{color:var(--c-600);text-decoration:none}
.wcpRowActions a:hover{text-decoration:underline}
.wcpSku{font-family:var(--mono);font-size:12px;color:var(--ink-soft)}
.wcpStars{white-space:nowrap;font-weight:600;color:var(--ink)}
.wcpBadge{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.02em;
  padding:3px 9px;border-radius:999px;background:var(--wash);color:var(--ink-soft);
  border:1px solid var(--rule)}
.wcpBadge.ok{background:var(--c-50,rgba(60,180,120,.12));color:var(--c-700);border-color:transparent}
.wcpBadge.warn{background:rgba(200,120,20,.12);color:#b4600f;border-color:transparent}

/* ── One product's editor (WooCommerce add-product layout) ────── */
.wcBack{margin:0 0 10px}
.wcBack a{color:var(--c-600);text-decoration:none;font-size:13px}
.wcBack a:hover{text-decoration:underline}
.wcHead{display:flex;align-items:flex-start;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin:0 0 18px}
.wcTitle{margin:0;font-size:22px}
.wcEyebrow{margin:2px 0 0;font-size:12px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-soft)}
.wcEdit{display:grid;gap:22px;align-items:start;
  grid-template-columns:minmax(0,1fr) minmax(240px,300px)}
.wcMain{min-width:0;display:flex;flex-direction:column;gap:22px}
.wcSide{display:flex;flex-direction:column;gap:22px}
.wcPanel{border:1px solid var(--rule);border-radius:var(--r-lg);
  background:var(--sheet);padding:16px 18px}
.wcPanelHead{display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin:0 0 14px}
.wcPanelH{margin:0;font-size:15px}
.wcPanelHead .wcPanelH{margin:0}
.wcType{font-size:11.5px;font-weight:700;color:var(--c-700);background:var(--wash);
  border-radius:999px;padding:3px 10px}
.wcData .adminTabs{margin-top:0}
/* Editable product fields (General tab). */
.wcForm{display:flex;flex-direction:column;gap:14px;max-width:560px}
.wcForm label{display:flex;flex-direction:column;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink)}
.wcForm .opt{font-weight:400;color:var(--ink-faint)}
.wcForm .help{display:block;margin:0;font-weight:400;font-size:11.5px;color:var(--ink-faint)}
.wcForm input,.wcForm textarea,.wcForm select{width:100%;box-sizing:border-box;padding:10px 12px;
  border:1px solid var(--rule);border-radius:var(--r);font:inherit;background:var(--paper);resize:vertical}
.wcForm input:focus,.wcForm textarea:focus,.wcForm select:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}
.wcForm .btn{align-self:flex-start}
.wcFormWide{max-width:none}
/* Sale + price editor (Pricing tab). */
.saleBox{border:1px solid var(--rule);border-radius:var(--r-lg);padding:14px 16px;margin:0 0 4px;
  display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center}
.wcForm .saleBox label{flex-direction:row;align-items:center;gap:8px;font-size:13px}
.saleBox .saleToggle input{width:auto}
.saleBox .pctWrap{display:inline-flex;align-items:center;gap:6px}
.saleBox .pctWrap input{width:68px}
.saleBox .pctSign{color:var(--ink-soft);font-weight:600}
.saleBox .saleNote{flex:1 1 100%;margin:0}
.wcPrices td{vertical-align:middle}
.wcPrices .priceInput{display:inline-flex;align-items:center;gap:4px}
.wcPrices .priceInput input{width:92px;padding:7px 9px;border:1px solid var(--rule);
  border-radius:var(--r);font:inherit;background:var(--paper)}
.wcPrices .priceInput input:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}
.wcPrices .curSign{color:var(--ink-faint)}
/* Struck-through "was" price + red sale badge, on cards and the product page. */
.wasPrice{text-decoration:line-through;color:var(--ink-faint);font-weight:500;font-size:.85em}
.nowPrice{color:#d5341f}
.saleTag{display:inline-block;background:#d5341f;color:#fff;font-size:11px;font-weight:700;
  border-radius:5px;padding:1px 7px;letter-spacing:.02em;vertical-align:middle}
.stamp.sale,.coverStamp.sale{background:#d5341f;color:#fff;border-color:transparent}
/* The buy box forces its spans to display:block for the price/caption
   stack, so the was-price and the sale tag must opt back to inline to sit
   on the price line rather than becoming full-width bars. */
.buyPrice .wasPrice,.buyPrice .saleTag{display:inline-block;width:auto;vertical-align:middle}
.buyPrice .wasPrice{font-size:18px}
.wcDl{margin:0;display:grid;gap:0}
.wcDl>div{display:grid;grid-template-columns:150px 1fr;gap:12px;padding:9px 0;
  border-top:1px solid var(--rule)}
.wcDl>div:first-child{border-top:0}
.wcDl dt{margin:0;font-size:12.5px;font-weight:600;color:var(--ink-soft)}
.wcDl dd{margin:0;font-size:13px;color:var(--ink)}
.wcCap{text-transform:capitalize}
.wcFacts{list-style:none;margin:0 0 14px;padding:0}
.wcFacts li{display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;padding:8px 0;border-top:1px solid var(--rule);font-size:13px}
.wcFacts li:first-child{border-top:0}
.wcFacts li span{color:var(--ink-soft)}
.wcLive{color:var(--c-700)}
.wcFull{display:block;text-align:center;width:100%}
.wcFeatured{border:1px solid var(--rule);border-radius:var(--r);overflow:hidden;
  background:var(--wash);aspect-ratio:16/10;display:flex;align-items:center;
  justify-content:center;padding:8px;text-align:center}
.wcFeatured img{max-width:100%;max-height:100%;object-fit:contain;display:block}
@media(max-width:820px){.wcEdit{grid-template-columns:1fr}}

/* ── Product workbench: images + installer per product, one card ── */
.pwProduct{margin:0 0 30px;padding:0 0 10px;border:1px solid var(--rule);
  border-radius:var(--r-lg);background:var(--sheet);overflow:hidden}
.pwProduct>.mediaHead{margin:0;padding:14px 18px;background:var(--wash);
  border-bottom:1px solid var(--rule)}
.pwBlock{padding:16px 18px;border-bottom:1px solid var(--rule)}
.pwProduct>.pwBlock:last-child{border-bottom:0}
.pwLabel{margin:0 0 12px;font-size:12px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ink-soft)}
/* The per-product "add image" form reuses the .dlFields grid. */
.pwAdd{margin-top:16px;padding-top:16px;border-top:1px dashed var(--rule)}
.pwAdd .dlFields{margin-bottom:14px}
/* Replace-in-place control inside a media card. */
.mcReplace{display:flex;flex-direction:column;gap:7px;padding:0 12px 12px;
  border-top:1px dashed var(--rule);margin-top:2px;padding-top:10px}
.mcReplaceLbl{display:flex;flex-direction:column;gap:5px;font-size:11.5px;
  font-weight:600;color:var(--ink-soft)}
.mcReplace input[type=file]{font-size:11.5px}
.mcReplace .btn{align-self:flex-start}

/* ── Downloads: the installer each product hands to licence holders ── */
.dlProduct{margin:0 0 30px;padding:0 0 22px;border-bottom:1px solid var(--rule)}
.dlProduct:last-child{border-bottom:0}
.dlNow{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin:0 0 14px;
  padding:10px 14px;border:1px solid var(--rule);border-radius:var(--r-lg);background:var(--wash)}
.dlNow .dlIcon{color:var(--c-600)}
.dlNow .meta{color:var(--ink-soft);font-size:12.5px}
.dlImport{justify-content:space-between}
.dlImport .meta{flex:1 1 240px;min-width:0}
.dlImport .inline{margin:0;flex:none}
.dlForm{margin:0}
/* The add-image / new-version fields: equal columns, labels top-aligned,
   and every control — text box, select and the file picker — the same
   height and full width so they line up across the row. */
.dlFields{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  margin-bottom:16px;align-items:start}
.dlFields label{display:flex;flex-direction:column;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink)}
.dlFields .opt{font-weight:400;color:var(--ink-faint)}
.dlFields .dfWide{grid-column:1/-1}
.dlFields input,.dlFields select,.dlFields textarea{width:100%;box-sizing:border-box;
  padding:10px 12px;border:1px solid var(--rule);border-radius:var(--r);
  font:inherit;background:var(--paper);resize:vertical}
/* The file input renders a Browse button + filename; give it the same
   frame and a touch less vertical padding so its button sits centred and
   it lines up with the text box and select beside it. */
.dlFields input[type=file]{padding:7px 10px;background:var(--wash);cursor:pointer;font-size:12px}
.dlFields input:focus,.dlFields select:focus,.dlFields textarea:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}
/* Publish / replace and remove sit on one row, aligned. */
.dlBtns{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:4px}
.dlBtns .inline{margin:0}
.dlRemove{margin-top:12px}
.dlHistory{margin-top:16px;font-size:13px}
.dlHistory summary{cursor:pointer;font-weight:600;color:var(--ink-soft)}
.dlRel{padding:10px 0;border-top:1px solid var(--rule)}
.dlRel:first-of-type{border-top:0}
.dlRel .meta{margin-left:8px;color:var(--ink-faint);font-size:12px}
.dlRel p{margin:4px 0 0;color:var(--ink-soft);font-size:12.5px;line-height:1.5}

/* A heading row with a count on the right. */
.secHead{display:flex;align-items:baseline;justify-content:space-between;gap:14px;
  flex-wrap:wrap;margin:28px 0 14px}
.secHead h2{margin:0}
.mb0{margin-bottom:0}

/* Make-a-code form: horizontal fields in a card, like the others. */
.discNew{margin:18px 0 10px}
.discNew h2{font-size:17px;margin:0 0 14px}
.discForm{margin-top:4px}
.discFields{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));margin-bottom:18px}
.discFields label{display:flex;flex-direction:column;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink)}
.discFields .opt{font-weight:400;color:var(--ink-faint)}
.discFields .dfWide{grid-column:1/-1}
.discFields input,.discFields select{padding:10px 12px;border:1px solid var(--rule);
  border-radius:var(--r);font:inherit;background:var(--paper)}
.discFields input:focus,.discFields select:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}

/* Orders: keep money, status and the key from wrapping awkwardly. */
.ordersTable td.num{white-space:nowrap}
.ordersTable .status{white-space:nowrap}
.ordersTable td:last-child{white-space:nowrap}
.tag2.staffTag{background:rgba(177,140,255,.14);color:#b18cff;
  border-color:rgba(177,140,255,.35)}

/* ── the initial capital ────────────────────────────────────
   The company's own name used as a drawn letter: set in a square on
   the wordmark, and as a true drop cap on a page of prose. */
.initial{
  float:left;font-family:var(--sans);font-weight:800;font-size:68px;
  line-height:.8;padding:8px 14px 0 0;color:var(--ink);
  letter-spacing:-.04em;
}
/* The [I] mark itself — no tile, no fill behind it, no hover. The drawn
   brackets ARE the logo, in the brand navy; a box around them was a
   placeholder standing in for a logo we now have. */
.mark{flex:none;display:inline-flex;align-items:center;color:var(--brand)}
.mark .markLogo{width:40px;height:40px;fill:currentColor}
.mark.sm .markLogo{width:30px;height:30px}

/* ── the announcement rail ──────────────────────────────────
   One line, above everything, for the one thing a visitor should know
   before they start reading: a release, or a service interruption.
   It is rendered only when there is something to say — an empty
   announcement bar is a strip of furniture that teaches people to
   ignore the place real news appears. */
.announce{
  background:var(--wash);border-bottom:1px solid var(--rule);
  padding:8px 16px;font-size:12px;font-weight:500;color:var(--ink-soft);
  text-align:center;
}
.announce > div{
  max-width:none;margin:0;display:flex;align-items:center;
  justify-content:center;gap:10px;flex-wrap:wrap;
}
.announce a{color:var(--c-700);font-weight:600}
.announce .sep{color:var(--ink-faint)}
.announce .code{
  font-family:var(--mono);font-size:11px;font-weight:600;color:var(--c-700);
  background:var(--c-50);border:1px solid var(--c-100);border-radius:6px;
  padding:2px 8px;
}

/* A live dot. Two rules, one shape: something is running. */
.dot{width:6px;height:6px;border-radius:999px;background:var(--stamp);flex:none}
.dot.cobalt{background:var(--c-600)}
.dot.red{background:var(--red)}

/* ── chrome ─────────────────────────────────────────────────
   The header sticks. On a long catalogue the way back to the bag and
   the way back to the top are the two things a visitor reaches for
   most, and a header that has scrolled away makes both a journey. */
.top{
  position:sticky;top:0;z-index:40;
  background:rgba(255,255,255,.95);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--rule);
}
.topIn{
  max-width:none;margin:0;padding:12px clamp(16px,3vw,48px);
  display:flex;align-items:center;gap:20px;
}
.brand{display:flex;align-items:center;gap:11px;text-decoration:none;flex:none}
.brand:hover{text-decoration:none}
/* No tagline here — the hero says it. The wordmark is sized to stand at
   the header's height beside the mark. */
.brandName{
  display:flex;align-items:center;line-height:1;
  font-size:30px;font-weight:800;letter-spacing:-.02em;color:var(--ink);
}
.brandName .cap{font-size:1em;font-family:var(--mono)}

.top nav{
  margin-left:auto;display:flex;align-items:center;gap:26px;
  font-size:13.5px;font-weight:500;
}
.top nav a{color:var(--ink-soft);text-decoration:none}
.top nav a:hover{color:var(--ink);text-decoration:none}
.top nav a[aria-current=page]{color:var(--ink);font-weight:600}
/* Register is the one call to action in the bar — a filled pill so a new
   visitor sees the way in, not just another link. */
.top nav a.navCta{color:#fff;background:var(--accent,var(--c-700));padding:6px 14px;border-radius:999px;font-weight:600}
.top nav a.navCta:hover{color:#fff;filter:brightness(1.07)}
.top nav a.navCta[aria-current=page]{color:#fff}
/* The burger shows only on narrow screens (see the media query); on
   desktop the nav is always open and this is hidden. */
.navBurger{display:none;flex-direction:column;justify-content:center;gap:5px;
  width:40px;height:40px;padding:9px;margin-left:auto;cursor:pointer;
  border:1px solid var(--rule);border-radius:10px;background:var(--sheet)}
.navBurger span{display:block;height:2px;border-radius:2px;background:var(--ink);
  transition:transform .2s var(--ease),opacity .2s var(--ease)}
.topTools{display:flex;align-items:center;gap:10px;flex:none}
.top nav + .topTools{margin-left:0}
.topTools:first-of-type{margin-left:auto}

/* The currency indicator. It is not a control: this shop prices in one
   currency, and saying so plainly is better than a picker with one
   entry in it. */
/* Sign out — a quiet outline button, so it reads as an action like
   Register without competing with it for attention. */
.navBtn{
  display:inline-flex;align-items:center;font:600 13px/1 var(--sans);cursor:pointer;
  padding:7px 14px;border-radius:999px;text-decoration:none;
  transition:background .18s var(--ease),border-color .18s var(--ease),color .18s var(--ease);
}
.navBtn.ghost{background:transparent;border:1px solid var(--rule-hot);color:var(--ink-soft)}
.navBtn.ghost:hover{background:var(--wash);border-color:var(--ink);color:var(--ink);text-decoration:none}

/* The bag. Ink, with white icon and label and the count in a bright pill —
   the count is the thing that changes, so it reads first. */
.bagBtn{
  display:flex;align-items:center;gap:9px;padding:9px 16px;
  background:var(--ink);color:#fff;border:1px solid var(--ink);
  border-radius:999px;font:700 13.5px/1 var(--sans);cursor:pointer;
  text-decoration:none;box-shadow:var(--lift);letter-spacing:.01em;
  transition:background .18s var(--ease);
}
.bagBtn,.bagBtn .bagLabel{color:#fff}
.bagBtn:hover{background:var(--c-600);border-color:var(--c-600);
  color:#fff;text-decoration:none}
.bagBtn:active{transform:scale(.97)}
.bagBtn svg{width:17px;height:17px;flex:none;stroke:#fff;color:#fff}
.bagCount{
  font-family:var(--mono);font-size:11.5px;font-weight:700;background:#fff;
  color:var(--ink);border-radius:999px;min-width:21px;padding:1px 6px;
  text-align:center;
}
.bagCount.zero{background:rgba(255,255,255,.28);color:#fff}

/* ── the page runs the full width of the window ──────────────
   No centred column. The gutter grows with the viewport — clamp()
   rather than a fixed padding — so the content keeps breathing room on
   a wide monitor without ever being capped at some chosen pixel width.

   PROSE is the exception, and it has to be: a paragraph 200 characters
   wide is a paragraph the eye loses its place in halfway along, and no
   amount of full-bleed layout makes that read better. So running text
   still honours --measure, while the things that genuinely want the
   room — the card grid, tables, the catalogue — take all of it. */
main{max-width:none;margin:0;padding:48px clamp(16px,3vw,48px) 88px;width:100%;flex:1}
main.wide{max-width:none}
main > p,main > .lead,main > ul,main > ol{max-width:var(--measure)}

/* ── type ───────────────────────────────────────────────────
   One scale, tight tracking, heavy where it must carry. A headline at
   800 and body at 400 is the whole hierarchy; weights in between are
   for interface furniture. */
h1{
  font-size:40px;line-height:1.12;font-weight:800;letter-spacing:-.035em;
  margin:0 0 18px;max-width:22ch;
}
h2{
  font-size:25px;line-height:1.25;font-weight:700;letter-spacing:-.025em;
  margin:52px 0 16px;
}
h3{
  font-size:15px;line-height:1.4;font-weight:700;letter-spacing:-.01em;
  margin:0 0 9px;color:var(--ink);
}
h4{font-size:13px;font-weight:700;letter-spacing:-.005em;margin:0 0 8px}
p{margin:0 0 16px}
.lead{font-size:17.5px;line-height:1.6;color:var(--ink-soft);margin:0 0 26px;
      max-width:var(--measure);font-weight:400}
.meta{font-size:13px;color:var(--ink-soft)}
.fine{font-size:13px;line-height:1.7;color:var(--ink-soft)}
.opt{font-size:12px;color:var(--ink-faint);font-weight:500}
.dim{color:var(--ink-soft)}
.mono{font-family:var(--mono)}
/* A small capital label above a heading: the section's own name. */
.eyebrow{
  display:block;font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--c-700);margin:0 0 6px;
}
.eyebrow.quiet{color:var(--ink-faint)}

/* ── the badge ──────────────────────────────────────────────
   A pill above a headline, saying what kind of thing this page is. */
.badge{
  display:inline-flex;align-items:center;gap:8px;padding:6px 14px;
  background:var(--sheet);border:1px solid var(--rule);border-radius:999px;
  font-size:12px;font-weight:500;color:var(--ink-soft);box-shadow:var(--lift);
  margin:0 0 22px;
}

/* ── the opening statement ──────────────────────────────────
   The front page opens with a sentence, not a slogan. This company's
   product is careful work explained plainly, and the fastest way to
   show that is to do it. */
.hero{
  border-bottom:1px solid var(--rule);
  /* Three layers, front to back: a centre-weighted veil that keeps the
     headline legible, the brand hero backdrop (app-window tiles drawn to
     the copy), and the original gradient as the ground. The veil is
     strongest behind the text and fades to nothing at the edges, so the
     artwork reads at the margins without ever fighting the words. */
  background:
    radial-gradient(120% 86% at 50% 42%,
      rgba(255,255,255,.80) 0%, rgba(255,255,255,.42) 34%, rgba(255,255,255,0) 66%),
    url(/brand/hero-bg.svg) center center / cover no-repeat,
    linear-gradient(180deg,var(--sheet) 0%,var(--paper) 55%);
  margin:-48px calc(-1 * clamp(16px,3vw,48px)) 0;
  padding:56px clamp(16px,3vw,48px) 60px;
  /* The backdrop is a 1600×760 (≈2.1:1) image. Give the hero a height
     that tracks that ratio so the whole artwork fills the band without
     the next section cropping its lower tiles — capped so it never
     becomes a full-screen banner on a very wide monitor, and floored so
     a phone still has room for the words. The copy sits centred in it. */
  min-height:clamp(460px,47.5vw,780px);
  display:flex;flex-direction:column;justify-content:center;
}
/* The hero's text stays a readable column even though its background
   is full-bleed: a centred headline spanning 2000px reads as a banner,
   not as a sentence. The band behind it is the full width. */
.heroIn{max-width:min(960px,100%);margin:0 auto;text-align:center}
.heroIn h1{margin-left:auto;margin-right:auto;max-width:26ch;font-size:52px}
/* The one underline on the site. It marks the half of the sentence the
   rest of the page is about. */
.heroIn h1 .u{
  text-decoration:underline;text-decoration-color:var(--c-500);
  text-decoration-thickness:4px;text-underline-offset:5px;
}
.statement{
  font-size:17.5px;line-height:1.6;color:var(--ink-soft);
  max-width:62ch;margin:0 auto 32px;
}
.statement::after{content:'';display:block;clear:both}
.heroActions{display:flex;gap:12px;flex-wrap:wrap;align-items:center;
  justify-content:center}
/* A left-aligned hero, for a page that is not the front page. */
.hero.plain{background:none;border-bottom:1px solid var(--rule);
  margin:0;padding:0 0 36px}
.hero.plain .heroIn{text-align:left;max-width:none}
.hero.plain .heroIn h1{margin-left:0;font-size:40px}
.hero.plain .statement{margin-left:0}

/* ── the search bar ─────────────────────────────────────────
   A real form, submitting to the catalogue. It filters server-side, so
   it works with scripting off and the result has an address that can
   be sent to somebody. */
.searchBar{
  display:flex;align-items:center;gap:8px;max-width:620px;margin:0 auto;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  padding:8px;box-shadow:var(--lift);
}
.searchBar:focus-within{border-color:var(--c-600);
  box-shadow:0 0 0 3px var(--c-50),var(--lift)}
.searchBar svg{width:19px;height:19px;color:var(--ink-faint);
  margin-left:10px;flex:none}
.searchBar input{
  flex:1;min-width:0;border:0;background:none;outline:none;
  font:400 14px/1.5 var(--sans);color:var(--ink);padding:6px 2px;
}
.searchBar input::placeholder{color:var(--ink-faint)}
.searchBar .clearBtn{
  background:none;border:0;cursor:pointer;font:500 12px var(--sans);
  color:var(--ink-faint);padding:6px 10px;
}
.searchBar .clearBtn:hover{color:var(--ink)}


/* ── the hero's own controls ─────────────────────────────────
   The search box and the platform pills sit INSIDE the hero, because
   somebody landing on this page has a job in mind and the first thing
   they meet should ask what it is. Centred with the rest of the hero;
   the catalogue further down repeats the same controls for anyone who
   scrolled past. */
.heroSearch{margin:30px auto 0}
.heroPlats{justify-content:center;margin-top:18px}
.heroPlats .pillLabel{margin-right:4px}
/* A line break that only exists where there is room for it. On a phone
   the headline wraps wherever it needs to instead of breaking at a
   point chosen for a wide screen. */
.brOnly{display:none}
@media (min-width:720px){ .brOnly{display:inline} }

/* ── filters ────────────────────────────────────────────────
   Links, not buttons, and not script: each pill is a URL that renders
   the filtered catalogue. The active one is ink — the heaviest thing
   in the row, so the eye finds the current state without reading. */
.filters{
  display:flex;align-items:center;justify-content:space-between;gap:16px;
  flex-wrap:wrap;padding-bottom:22px;border-bottom:1px solid var(--rule);
}
.pills{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  font-size:12.5px;font-weight:600}
.pills.tight{gap:6px;font-size:11.5px}
.pillLabel{
  font-size:10.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink-faint);margin-right:2px;
}
.pill{
  display:inline-block;padding:8px 15px;border-radius:var(--r);
  border:1px solid var(--rule);background:var(--sheet);color:var(--ink-soft);
  text-decoration:none;cursor:pointer;
  transition:background .15s var(--ease),border-color .15s var(--ease);
}
.pill:hover{background:var(--wash);color:var(--ink);text-decoration:none}
.pill.on{background:var(--ink);border-color:var(--ink);color:#fff}
.pill.on:hover{background:var(--ink);color:#fff}
.pills.tight .pill{padding:5px 11px;border-radius:var(--r-sm)}

/* A select that matches the pills beside it. */
.sorter{display:flex;align-items:center;gap:10px;flex:none}
.sorter span{font-size:12px;color:var(--ink-faint);font-weight:500}
.sorter select{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  color:var(--ink);font:500 12.5px var(--sans);padding:8px 12px;cursor:pointer;
}
.sorter select:focus{outline:none;border-color:var(--c-600)}

/* The line between the filters and the grid: how many, and whether the
   shop is actually able to serve you right now. */
.resultLine{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;padding:16px 0;font-size:12px;font-weight:500;
  color:var(--ink-soft);
}
.resultLine .count{font-family:var(--mono);color:var(--ink)}
.resultLine .live{display:flex;align-items:center;gap:8px}

/* ── plates ─────────────────────────────────────────────────
   One treatment, named for what it is: a white plate on paper with a
   hairline. Everything that holds content on this site is one. */
.card,.plan,.summary,.strip,.settings,.keyBox,.form,.tile,.review,.item{
  background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-lg);box-shadow:var(--lift);
}
.card,.plan,.summary,.strip,.settings{padding:26px 28px}
.card h2{margin:0 0 8px;font-size:19px;font-weight:700}
.card p{max-width:none}
.card p:last-child,.plan p:last-child{margin-bottom:0}
.strip{margin-top:44px}
.strip h3{font-size:18px;font-weight:700;margin-bottom:14px}
/* The ask-us actions sit under the text, aligned with it — not centred,
   which left the button floating away from the left-aligned copy. */
.strip .heroActions{justify-content:flex-start;margin-top:18px}

/* A plate that reacts. Used where the whole plate is a link, so the
   lift is the affordance: it says "this is one thing, and it opens". */

.grid{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(270px,1fr))}
.split{display:grid;gap:30px;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));
       margin:30px 0}
.split p,.split ul{max-width:none}

/* ── the catalogue ──────────────────────────────────────────
   Cards, four across. The register of rows this replaced read well
   with one product in it and would have read as a rather empty ledger
   with nine; a card carries the plate, the price, the platforms and a
   way in without the eye having to track across a wide row. */
/* Product tiles flow on one line and share the space between the page
   gutters: each grows to fill, so three products sit as three equal
   tiles across the row rather than leaving a gap, and they wrap only
   when the row genuinely runs out of room. A max keeps a short
   catalogue from blowing each tile up on a very wide monitor. */
.cards{
  display:flex;flex-wrap:wrap;gap:22px;padding-top:8px;justify-content:start;
}

/* ── average-rating stars (listing cards and the product title) ── */
.starRate{display:inline-flex;align-items:center;gap:6px;text-decoration:none;
  font-size:13px;color:var(--ink-soft);line-height:1;white-space:nowrap}
a.starRate:hover .rNum{text-decoration:underline}
.rNum{font-weight:700;color:var(--ink)}
.rCount{color:var(--ink-faint)}
.cardRating{margin:1px 0 8px}
.pdpRating{margin:0 0 12px}
/* Half-aware star row: each star is full gold, half gold (a gold left
   half overlaid on a grey star), or grey. */
.starsRow{display:inline-flex;font-size:15px;line-height:1;letter-spacing:1px}
.starsRow .st{position:relative;color:var(--ink-faint);opacity:.45}
.starsRow .st.sFull{color:#f6a609;opacity:1}
.starsRow .st.sHalf::before{content:'★';position:absolute;left:0;top:0;
  width:.5em;overflow:hidden;color:#f6a609;opacity:1}
/* ── half-star rating PICKER (review form) ─────────────────────
   Ten half-width slices, row-reversed so 5 is on the right. A slice is a
   window over a star: '.full' shows its right half, '.half' its left.
   Checking (or hovering) a slice golds it and every slice after it in the
   DOM — which, in reverse, are the lower stars to its left. */
.starHalf{display:inline-flex;flex-direction:row-reverse;justify-content:flex-end;
  font-size:30px;line-height:1;margin:2px 0 14px}
.starHalf input{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.starHalf label{position:relative;width:.5em;height:1em;overflow:hidden;cursor:pointer;
  color:var(--ink-faint);opacity:.5}
.starHalf label::before{content:'★';position:absolute;top:0;left:0;width:1em;height:1em;line-height:1}
.starHalf label.full::before{left:-.5em}
.starHalf input:checked ~ label{color:#f6a609;opacity:1}
.starHalf:hover input ~ label{color:var(--ink-faint);opacity:.5}
.starHalf label:hover,.starHalf label:hover ~ label{color:#f6a609;opacity:1}
.starHalf input:focus-visible + label{outline:2px solid var(--c-600);outline-offset:2px}
/* Prose anywhere on a page keeps a readable line length, whatever the
   window is doing. Full-bleed layout is for the things that want the
   room; a sentence is not one of them. */
main p:not(.cardBlurb):not(.fine):not(.meta):not([class]),
main > p,.statement,.lead{max-width:var(--measure)}
/* A retail product card: a cover, then a body, then the price and a
   full-width call to action pinned to the bottom so the buy rails line up
   across the shelf. The whole card is one link to the product. */
.cardItem{
  flex:1 1 240px;max-width:420px;min-width:0;
  display:flex;flex-direction:column;background:var(--sheet);
  border:1px solid var(--rule);border-radius:var(--r-lg);padding:0;overflow:hidden;
  box-shadow:var(--lift);color:var(--ink);text-decoration:none;
  transition:transform .2s var(--ease),box-shadow .2s var(--ease),
             border-color .2s var(--ease);
}
.cardItem:hover{border-color:var(--rule-hot);transform:translateY(-3px);
  box-shadow:var(--lift-hi);text-decoration:none;color:var(--ink)}
/* The cover. A branded tile today — its own initial as a watermark on a
   product-coloured wash — built to be swapped for a real screenshot. */
.cardCover{
  position:relative;aspect-ratio:16/10;display:grid;place-items:center;overflow:hidden;
  background:linear-gradient(135deg,var(--c-700),var(--c-600));
  border-bottom:1px solid var(--rule);
}
.cardCover::after{content:"";position:absolute;inset:0;
  background:radial-gradient(120% 90% at 18% 10%,rgba(255,255,255,.22),transparent 60%);}
.cardCover img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block}
/* A real screenshot fills the cover; the gloss and gradient are for the
   drawn tiles, so drop them when there is a photo. */
.cardCover.hasShot{background:#0d1326}
.cardCover.hasShot::after{display:none}
.cover-soon{background:linear-gradient(135deg,#475569,#7c8ba3)}
.cover-free{background:linear-gradient(135deg,#0f766e,#15b8a6)}
.coverMark{position:relative;z-index:1;font:800 76px/1 var(--sans);
  letter-spacing:-.05em;color:rgba(255,255,255,.95);
  text-shadow:0 2px 18px rgba(0,0,0,.18)}
.cardItem:hover .coverMark{transform:scale(1.04);transition:transform .25s var(--ease)}
.coverStamp{position:absolute;top:12px;left:12px;z-index:2;
  background:rgba(255,255,255,.94);border-color:transparent}
.coverVer{position:absolute;top:12px;right:12px;z-index:2;
  font-family:var(--mono);font-size:10.5px;font-weight:600;color:#fff;
  background:rgba(0,0,0,.28);border-radius:999px;padding:3px 9px}
.cardBody{display:flex;flex-direction:column;flex:1;padding:18px}
.cardCat{font-size:10.5px;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--c-700)}
.cardName{font-size:17px;font-weight:700;letter-spacing:-.02em;margin:4px 0 0}
.cardItem:hover .cardName{color:var(--c-700)}
.cardBlurb{
  font-size:12.5px;line-height:1.6;color:var(--ink-soft);margin:8px 0 0;
  /* Two lines, so every card in a row is the same height and the price
     rails line up across the grid. */
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}
.cardRule{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:16px;padding-top:12px;border-top:1px solid var(--rule-soft);
  font-size:11px;
}
.cardRule .plats{color:var(--ink-faint);font-weight:500}
.cardRule .rate{display:flex;align-items:center;gap:4px;font-family:var(--mono);
  font-weight:600;color:var(--ink)}
.cardRule .rate .star{color:var(--star)}
/* Price + CTA, pinned to the bottom so every card's buy rail aligns. */
.cardBuy{margin-top:auto;padding-top:16px;border-top:1px solid var(--rule)}
.cardFoot{display:flex;align-items:flex-end;justify-content:space-between;gap:10px}
.cardFoot .priceCol{display:flex;flex-direction:column}
.cardFoot .was{font-family:var(--mono);font-size:11px;color:var(--ink-faint);
  text-decoration:line-through;margin-right:5px}
.cardFoot .now{font-family:var(--mono);font-size:20px;font-weight:700;color:var(--ink)}
.cardFoot .from{display:block;font-size:10.5px;color:var(--ink-faint);
  font-weight:500;margin-top:2px}
.btn.block{display:block;width:100%;text-align:center}
.cardCta{margin-top:12px}
.cardActs{display:flex;align-items:center;gap:7px;flex:none}

/* The account overview: two cards, details and security, side by side. */
.acctCards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));
  gap:18px;margin:22px 0 34px}
.acctCard h2{font-size:15px;margin:0 0 14px}
.acctDl{display:grid;grid-template-columns:auto 1fr;gap:10px 18px;margin:0}
.acctDl dt{color:var(--ink-faint);font-size:12.5px;font-weight:600}
.acctDl dd{margin:0;font-size:13.5px;color:var(--ink);word-break:break-word}
.acctDl dd code{font-family:var(--mono);font-size:12.5px}

/* ── chips and stamps ───────────────────────────────────────
   A chip is a fact about a thing. A stamp is its state. */
.tag2{
  font-size:11px;font-weight:500;line-height:1.5;color:var(--ink-soft);
  border:1px solid var(--rule);background:var(--sheet);padding:3px 9px;
  border-radius:999px;
}
.tag2.on{color:var(--stamp);border-color:var(--stamp);background:var(--stamp-bg)}
.tag2.soon{color:var(--amber);border-color:var(--amber);background:var(--amber-bg)}
.tag2.mono{font-family:var(--mono);font-size:10.5px}
.stamp{
  font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--stamp);background:var(--stamp-bg);border:1px solid var(--stamp);
  border-radius:999px;padding:4px 10px;display:inline-block;white-space:nowrap;
}
.stamp.soon{color:var(--amber);background:var(--amber-bg);border-color:var(--amber)}
.stamp.quiet{color:var(--ink-soft);background:var(--wash);border-color:var(--rule)}
.ver{font-family:var(--mono);font-size:10px;color:var(--ink-faint);font-weight:500}

/* ── the offer banner ───────────────────────────────────────
   One wide plate, a price card sitting inside it. Used where there is
   genuinely one thing to recommend; a page with three of these has
   none. */
.offer{
  background:linear-gradient(100deg,var(--sheet),var(--wash));
  border:1px solid var(--rule);border-radius:var(--r-xl);
  padding:32px;margin:12px 0;overflow:hidden;
}
.offerIn{display:flex;align-items:center;justify-content:space-between;
  gap:32px;flex-wrap:wrap}
.offerText{flex:1 1 380px;min-width:0}
.offerText h2{margin:0;font-size:26px;font-weight:800;letter-spacing:-.03em}
.offerText p{font-size:13.5px;line-height:1.65;color:var(--ink-soft);
  margin:10px 0 0;max-width:58ch}
.offerBadge{
  display:inline-flex;align-items:center;gap:6px;padding:5px 13px;
  border-radius:999px;background:var(--c-50);color:var(--c-700);
  border:1px solid var(--c-100);font-size:10.5px;font-weight:700;
  letter-spacing:.07em;text-transform:uppercase;margin-bottom:16px;
}
.offerFacts{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px;
  font-family:var(--mono);font-size:11.5px;color:var(--ink-soft)}
.offerFacts span{background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-sm);padding:5px 11px}
.offerCard{
  flex:0 0 300px;background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-lg);box-shadow:var(--lift);padding:24px;text-align:center;
}
.offerCard .cap2{font-size:10.5px;font-weight:700;letter-spacing:.07em;
  text-transform:uppercase;color:var(--ink-faint)}
.offerCard .figs{display:flex;align-items:baseline;justify-content:center;
  gap:9px;margin-top:10px}
.offerCard .was{font-family:var(--mono);font-size:15px;color:var(--ink-faint);
  text-decoration:line-through}
.offerCard .now{font-family:var(--mono);font-size:34px;font-weight:800;
  letter-spacing:-.03em;color:var(--ink)}
.offerCard .saved{font-size:12px;font-weight:600;color:var(--stamp);margin:6px 0 0}
.offerCard .btn{width:100%;margin-top:18px;justify-content:center}
.offerCard .after{font-size:11px;color:var(--ink-faint);margin:10px 0 0}

/* ── facts, numbered ────────────────────────────────────────
   Short columns, each with its own small heading. The numbers are
   labels, not steps: these are facts that hold at the same time, and
   numbering them 01-02-03 is how the sample's guarantee strip reads
   without implying an order. */
.facts{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));
       margin:26px 0 0}
.facts section{
  margin:0;background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-lg);padding:24px;box-shadow:var(--lift);
}
.facts h3{margin-bottom:8px}
.facts p{font-size:13px;line-height:1.65;color:var(--ink-soft);margin:0;max-width:44ch}
.facts .n{
  width:32px;height:32px;display:grid;place-items:center;border-radius:var(--r-sm);
  background:var(--wash);color:var(--ink);font-family:var(--mono);font-size:12px;
  font-weight:700;margin-bottom:14px;
}
/* The older bare-column variant, where the plates would be too much. */
.facts.bare section{background:none;border:0;border-radius:0;padding:0;
  box-shadow:none}
.facts.bare h3{border-top:2px solid var(--ink);padding-top:10px}

.ticks{list-style:none;padding:0;margin:0}
.ticks li{padding:7px 0 7px 24px;position:relative;font-size:15px;
          max-width:var(--measure)}
.ticks li::before{
  content:'';position:absolute;left:0;top:14px;width:9px;height:9px;
  border-left:1.5px solid var(--c-600);border-bottom:1.5px solid var(--c-600);
  transform:rotate(-45deg);
}
.ticks.small li{font-size:13.5px;padding-top:5px;padding-bottom:5px}

/* ── reviews ────────────────────────────────────────────────
   Real ones or none. The plates are here; what goes in them is
   whatever customers have actually written, and the section does not
   render at all until some of them have. A grid of invented
   testimonials on a page whose whole argument is that we tell you the
   truth about what we have built would undo the argument. */
.reviewHead{display:flex;align-items:flex-end;justify-content:space-between;
  gap:16px;flex-wrap:wrap;margin-bottom:24px}
.reviewHead h2{margin:0;font-size:25px}
.reviewScore{font-family:var(--mono);font-size:12.5px;color:var(--ink-soft)}
.reviewScore b{color:var(--ink);font-weight:700}
.reviews{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.review{padding:24px}
.review .stars{color:var(--star);font-size:12px;letter-spacing:.1em;
  margin-bottom:12px}
.review p{font-size:13px;line-height:1.7;color:var(--ink);margin:0}
.review footer{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:18px;padding-top:14px;border-top:1px solid var(--rule-soft);
  font-size:12px;background:none;border-left:0;border-right:0;border-bottom:0;
  padding-left:0;padding-right:0;padding-bottom:0;
}
.review footer b{font-weight:700;color:var(--ink)}
/* Follow-up comments on a review — the "repost", appended under it. */
.reviewComments{margin-top:14px;display:flex;flex-direction:column;gap:10px}
.reviewComment{border-left:2px solid var(--rule-hot);padding-left:12px}
.reviewComment .meta{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.reviewComment p{font-size:12.5px;line-height:1.6;margin:3px 0 0;color:var(--ink-soft)}

/* The buyer's review controls. */
.reviewGate{margin:14px 0 4px}
.reviewAdd{background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift);padding:20px;margin:16px 0 26px;display:flex;flex-direction:column;gap:12px}
.reviewNewHead,.reviewMineHead{margin:0;font-size:14px}
.reviewMine{margin:16px 0 26px}
.reviewAdd textarea{width:100%;padding:11px 13px;border:1px solid var(--rule);border-radius:var(--r);
  font:inherit;font-size:13.5px;resize:vertical;background:var(--paper)}
.reviewAdd textarea:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}
.reviewAdd .btn{align-self:flex-start}
/* Star picker: five single stars. DOM runs 5→1 and row-reverse flips it
   to 1→5 on screen, so :checked ~ label fills the star and all lower ones
   (which sit to its left) — the classic no-script rating. */
.starPick{display:inline-flex;flex-direction:row-reverse;justify-content:flex-end;gap:3px}
.starPick input{position:absolute;opacity:0;pointer-events:none}
.starPick label{cursor:pointer;color:var(--ink-faint);font-size:24px;line-height:1;
  transition:color .1s var(--ease)}
.starPick label:hover,.starPick label:hover~label,.starPick input:checked~label{color:var(--star)}
.review footer span{font-size:11px;color:var(--ink-faint)}

/* ── a product's own page ───────────────────────────────── */
.toolHead{border-bottom:1px solid var(--rule);padding-bottom:30px;margin-bottom:14px}
.toolHead h1{margin-bottom:12px}
.toolHead .lead{margin-bottom:16px}
.headMeta{display:flex;gap:9px;flex-wrap:wrap;align-items:center;margin-top:18px}

/* ── pricing ──────────────────────────────────────────────── */
.plans{display:grid;gap:20px;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));
       margin-top:18px}
.plan{padding:26px 28px;display:flex;flex-direction:column}
.plan h3{font-size:18px;font-weight:700;margin-bottom:6px}
/* The recommended one is marked by a cobalt rule across its top, not
   by being bigger or louder than the others. */
.plan.trial{border-color:var(--c-600);box-shadow:inset 0 3px 0 var(--c-600),var(--lift)}
.blurb{color:var(--ink-soft);font-size:13.5px;margin:0 0 18px;min-height:42px;
       line-height:1.6}
.price{font-family:var(--mono);font-size:30px;font-weight:800;margin:6px 0 16px;
       line-height:1.1;letter-spacing:-.03em}
.price span{display:block;font-family:var(--sans);font-size:12.5px;font-weight:500;
            color:var(--ink-soft);margin-top:8px;letter-spacing:0}
.plan .btn{margin-top:auto}
table.prices{width:100%;border-collapse:collapse;font-size:13.5px}
table.prices th{
  text-align:left;font-size:11px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-faint);
  padding:0 10px 10px 0;border-bottom:1px solid var(--rule);
}
table.prices td{padding:13px 10px 13px 0;border-bottom:1px solid var(--rule-soft);
                vertical-align:middle}
table.prices tr:last-child td{border-bottom:none}
/* Add to bag beside Buy now: side by side, and stacked on a narrow screen */
table.prices .acts{display:flex;gap:6px;justify-content:flex-end;flex-wrap:wrap}
table.prices .acts form{margin:0}
.num{text-align:right}
/* Keep the right-aligned Amount off the Status column beside it. */
table.data td.num,table.data th.num{padding-right:26px}
.save{
  display:inline-block;margin-left:7px;font-size:10.5px;font-weight:700;
  color:var(--stamp);background:var(--stamp-bg);border:1px solid var(--stamp);
  border-radius:999px;padding:2px 8px;
}

/* ── the bag ────────────────────────────────────────────────
   A page, not a drawer. A drawer is a nicer gesture and a worse
   receipt: the bag is where somebody checks what they are about to be
   charged for, and that deserves an address they can reload, send to
   whoever signs for it, and come back to tomorrow. */
.bag{display:grid;gap:24px;grid-template-columns:minmax(0,1.7fr) minmax(280px,1fr);
  align-items:start;margin-top:8px}
.bagItems{display:flex;flex-direction:column;gap:12px}
.item{display:flex;align-items:center;gap:16px;padding:16px}
.item .plate{width:44px;height:44px;font-size:19px;border-radius:var(--r-sm)}
.itemBody{flex:1;min-width:0}
.itemBody h3{margin:0 0 3px;font-size:14px}
.itemBody .meta{font-size:11.5px;color:var(--ink-faint)}
/* A SKU is machine text wherever it appears — on a price row, on a
   basket line, on an invoice. One rule, so they match. */
.sku{font-family:var(--mono);font-size:10.5px;color:var(--ink-faint);font-weight:500}
.itemPrice{font-family:var(--mono);font-size:14px;font-weight:700;
  color:var(--ink);white-space:nowrap}
/* Quantity. Two single-character buttons and a figure, in one inset
   group, because three separate controls in a row read as three
   separate decisions. */
.qty{display:flex;align-items:center;gap:2px;background:var(--wash);
  border:1px solid var(--rule);border-radius:var(--r-sm);padding:3px;flex:none}
.qty button{
  width:24px;height:24px;display:grid;place-items:center;cursor:pointer;
  background:var(--sheet);border:1px solid var(--rule);border-radius:5px;
  font:600 13px var(--sans);color:var(--ink-soft);padding:0;
}
.qty button:hover{color:var(--ink);border-color:var(--rule-hot)}
.qty button[disabled]{opacity:.4;pointer-events:none}
.qty .n{font-family:var(--mono);font-size:12px;font-weight:700;
  min-width:24px;text-align:center}
.rm{background:none;border:0;cursor:pointer;color:var(--ink-faint);padding:6px;
  line-height:0;border-radius:6px}
.rm:hover{color:var(--red);background:var(--red-bg)}
.rm svg{width:15px;height:15px}

.summary{padding:24px;position:sticky;top:86px}
.summary h3{font-size:12px;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;margin-bottom:16px}
.sums{display:flex;flex-direction:column;gap:9px;font-size:13px;
  color:var(--ink-soft)}
.sums > div{display:flex;justify-content:space-between;gap:12px}
.sums b{font-family:var(--mono);font-weight:600;color:var(--ink)}
.sums .off{color:var(--stamp)}
.sums .off b{color:var(--stamp)}
.sums .total{
  padding-top:12px;margin-top:4px;border-top:1px solid var(--rule);
  font-size:14px;font-weight:700;color:var(--ink);
}
.sums .total b{font-size:19px;color:var(--c-700);font-weight:800}
.summary .btn{width:100%;margin-top:20px;justify-content:center}
.summary .after{font-size:11px;color:var(--ink-faint);text-align:center;
  margin:10px 0 0}

/* The promo code row: a field and a button, sized so the button never
   wraps under it. */
.promo{display:flex;gap:8px;margin-bottom:18px}
.promo input{
  flex:1;min-width:0;background:var(--wash);border:1px solid var(--rule);
  border-radius:var(--r);padding:9px 12px;font:600 12px var(--mono);
  color:var(--ink);text-transform:uppercase;
}
.promo input::placeholder{font-family:var(--sans);font-weight:400;
  text-transform:none;color:var(--ink-faint)}
.promo input:focus{outline:none;border-color:var(--c-600);background:var(--sheet)}
/* width:auto beats the `.summary .btn{width:100%}` rule — without it the
   Apply button went full-width and crushed the code input to a sliver. */
.promo .btn{flex:none;width:auto;margin-top:0;padding:9px 14px;font-size:12px}
/* The applied code, shown as a removable chip rather than as text in
   the field — so it is obvious it is ON, and obvious how to take it
   off. */
.promoOn{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  background:var(--stamp-bg);border:1px solid var(--stamp);
  border-radius:var(--r);padding:9px 12px;margin-bottom:18px;
  font-size:12px;color:var(--stamp);font-weight:600;
}
/* "Signed in as …" banner on the checkout form, so a logged-in buyer is
   not asked for an email and name the account already holds. */
.coAccount{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;background:var(--wash);border:1px solid var(--rule);border-radius:var(--r);
  padding:12px 14px;margin:0 0 18px;font-size:13.5px;line-height:1.5}
.coAccount a{color:var(--c-700);text-decoration:none;white-space:nowrap}
.coAccount a:hover{text-decoration:underline}
.promoOn code{font-family:var(--mono);font-weight:700;color:var(--stamp)}
.promoOn button{background:none;border:0;cursor:pointer;color:var(--stamp);
  font:500 11px var(--sans);text-decoration:underline;padding:0}

/* The empty bag. A direction, not a mood. */
.empty{
  text-align:center;padding:56px 24px;background:var(--sheet);
  border:1px solid var(--rule);border-radius:var(--r-lg);box-shadow:var(--lift);
}
.empty .ring{
  width:48px;height:48px;display:grid;place-items:center;margin:0 auto 14px;
  border-radius:var(--r);background:var(--wash);color:var(--ink-soft);
}
.empty .ring svg{width:22px;height:22px}
.empty h3{font-size:15px;margin-bottom:4px}
.empty p{font-size:12.5px;color:var(--ink-soft);margin:0 0 18px}

/* ── forms ──────────────────────────────────────────────── */
.form{padding:28px}
.form.narrow{max-width:460px}
.form label{display:block;margin-bottom:20px;font-size:13px;font-weight:600;
            color:var(--ink)}
.form label.placeholder{border-left:2px solid var(--amber);padding-left:13px;
                        margin-left:-15px}
.tag{
  display:inline-block;font-size:10.5px;font-weight:700;color:var(--amber);
  background:var(--amber-bg);border:1px solid var(--amber);border-radius:999px;
  padding:2px 8px;margin-left:7px;
}
.form input[type=text],.form input[type=email],.form input[type=password],
.form input[type=tel],.form input[type=number],.form select,.form textarea{
  display:block;width:100%;margin-top:8px;padding:11px 13px;
  background:var(--wash);color:var(--ink);
  border:1px solid var(--rule);border-radius:var(--r);
  font:400 14px/1.5 var(--sans);
}
.form input:focus,.form select:focus,.form textarea:focus{
  outline:none;border-color:var(--c-600);background:var(--sheet);
  box-shadow:0 0 0 3px var(--c-50);
}
.form input.code{font-family:var(--mono);font-size:21px;font-weight:600;
                 letter-spacing:.4em;text-align:center}
.help{display:block;margin-top:7px;font-size:12px;font-weight:400;
      color:var(--ink-soft);line-height:1.6}
.clear{display:inline-block;margin-top:9px;font-size:12.5px;font-weight:400;
       color:var(--ink-soft)}
.clear input{width:auto;display:inline;margin-right:6px}

/* ── buttons ────────────────────────────────────────────────
   Ink by default, cobalt when the button IS the thing the page is for.
   One cobalt button per screen; a page with three has none. */
.btn{
  display:inline-flex;align-items:center;gap:8px;padding:11px 20px;cursor:pointer;
  font:600 13.5px/1.2 var(--sans);text-decoration:none;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  color:var(--ink);box-shadow:var(--lift);
  transition:background .16s var(--ease),border-color .16s var(--ease),
             color .16s var(--ease);
}
.btn:hover{background:var(--wash);border-color:var(--rule-hot);
  text-decoration:none;color:var(--ink)}
.btn:active{transform:scale(.98)}
.btn.primary{background:var(--ink);border-color:var(--ink);color:#fff}
.btn.primary:hover{background:var(--c-600);border-color:var(--c-600);color:#fff}
.btn.go{background:var(--c-600);border-color:var(--c-600);color:#fff}
.btn.go:hover{background:var(--c-700);border-color:var(--c-700);color:#fff}
.btn.danger{border-color:var(--red);color:var(--red);background:var(--sheet)}
.btn.danger:hover{background:var(--red-bg)}
.btn.sm{padding:7px 13px;font-size:12px;border-radius:var(--r-sm)}
.btn.icon{padding:8px;border-radius:var(--r-sm)}
.btn.icon svg{width:15px;height:15px}
.btn.wide{width:100%;justify-content:center}
.btn.up{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.btn[disabled],.btn.off{opacity:.45;pointer-events:none}
.inline{display:inline}
.linkish{
  background:none;border:none;padding:0;cursor:pointer;color:var(--ink-soft);
  font:500 13px var(--sans);text-decoration:none;
}
.linkish:hover{color:var(--ink);text-decoration:underline}

/* ── notices ────────────────────────────────────────────────
   An empty or failed state is a direction, not a mood: the rule on the
   left says which kind, the text says what to do next. */
.note{
  font-size:13.5px;line-height:1.65;padding:14px 18px;margin:18px 0;
  max-width:var(--measure);background:var(--sheet);
  border:1px solid var(--rule);border-left:3px solid var(--rule-hot);
  border-radius:var(--r);box-shadow:var(--lift);
}
.note.ok{border-left-color:var(--stamp)}
.note.warn{border-left-color:var(--amber)}
.note.bad{border-left-color:var(--red)}

.keyBox{margin:28px 0;padding:26px;text-align:center}
.key{
  font-family:var(--mono);font-size:18px;letter-spacing:.14em;font-weight:700;
  color:var(--ink);background:var(--wash);border:1px solid var(--rule);
  border-radius:var(--r);padding:14px;margin:12px 0 16px;word-break:break-all;
}

/* ── the flash ──────────────────────────────────────────────
   Confirmation of the thing that just happened: added to the basket,
   code applied, line removed.

   The sample this was drawn from floats these in the corner and fades
   them out on a timer. That needs script, and the public site runs
   none — see BASE_CSP in server.js, where having no script-src is a
   property worth keeping rather than a gap. So it keeps the look and
   loses the timer: the server renders it at the top of the page it
   redirected to, and it goes away when the next page loads.

   Which is arguably the better behaviour anyway. A confirmation that
   erases itself after three seconds is a confirmation somebody who
   looked away never received, and this one is also the only version
   that exists for a reader using a screen reader or a text browser. */
.flash{
  display:flex;align-items:center;gap:10px;align-self:flex-start;
  background:var(--ink);color:#fff;font:500 12.5px var(--sans);
  padding:12px 16px;margin:0 0 24px;border-radius:var(--r);
  box-shadow:0 10px 24px -8px rgba(15,23,42,.3);
}
.flash .dot{background:var(--c-500)}
.flash.bad{background:var(--red)}
.flash.bad .dot{background:#fff}
.flash a{color:#fff;text-decoration:underline;margin-left:4px}

/* ── tables ─────────────────────────────────────────────── */
table.data{width:100%;border-collapse:collapse;font-size:13.5px;margin-top:18px}
table.data th{
  text-align:left;font-size:11px;font-weight:700;letter-spacing:.05em;
  text-transform:uppercase;color:var(--ink-faint);
  padding:0 12px 10px 0;border-bottom:1px solid var(--rule-hot);
}
table.data td{padding:13px 12px 13px 0;border-bottom:1px solid var(--rule-soft);
              vertical-align:top}
table.data code{font-size:12.5px}
.status{
  display:inline-block;font-size:10.5px;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;padding:3px 9px;border:1px solid var(--rule);
  border-radius:999px;color:var(--ink-soft);background:var(--wash);
}
.status.fulfilled,.status.sent,.status.verified,.status.paid,.status.active{
  color:var(--stamp);border-color:var(--stamp);background:var(--stamp-bg)}
.status.pending{color:var(--amber);border-color:var(--amber);background:var(--amber-bg)}
.status.cancelled,.status.refused,.status.revoked{
  color:var(--red);border-color:var(--red);background:var(--red-bg)}
.warnText{color:var(--amber)}

/* ── admin console shell ────────────────────────────────────
   A fixed dark rail, a slim bar, the work in the middle — the AWS/
   Vercel console shape, in the site's own palette rather than a
   borrowed one. Only the body that adminShell() renders wears
   .adminApp, so none of this touches the public shop. */
body.adminApp{margin:0;min-height:100vh;background:var(--wash)}
.aShell{display:flex;min-height:100vh;align-items:stretch}
.aSide{
  position:sticky;top:0;align-self:flex-start;
  width:252px;flex:none;height:100vh;overflow-y:auto;
  background:var(--ink);color:#cbd5e1;
  display:flex;flex-direction:column;gap:4px;padding:14px 12px;
  --railHot:#60a5fa;
}
.aBrand{display:flex;align-items:center;gap:10px;padding:8px 8px 14px;
        color:#fff;text-decoration:none}
/* The brand is a link home, but it is a logo, not a menu item — it must
   not light up on hover. Without this, the base a:hover colour overrode
   the inherited white and turned "InitCap" blue. */
.aBrand:hover{text-decoration:none;color:#fff}
.aBrand .mark.sm{color:#fff}
.aBrand .mark.sm .markLogo{fill:#fff;width:34px;height:34px}
.aBrandText{display:flex;flex-direction:column;line-height:1.1;
  font-family:var(--mono);font-weight:800;font-size:15px;letter-spacing:-.01em}
.aBrandText small{font-family:var(--sans);font-weight:500;font-size:10.5px;
  letter-spacing:.08em;text-transform:uppercase;color:var(--ink-faint);margin-top:3px}
.aNav{display:flex;flex-direction:column;gap:2px;flex:1}
.aGrp{display:flex;flex-direction:column;gap:2px;padding:6px 0}
.aGroup{font-size:10.5px;font-weight:700;letter-spacing:.09em;text-transform:uppercase;
  color:#64748b;padding:6px 10px 4px}
.aLink{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:10px;
  color:#cbd5e1;font-size:13.5px;font-weight:500;text-decoration:none;
  transition:background .15s var(--ease),color .15s var(--ease)}
.aLink:hover{background:rgba(255,255,255,.06);color:#fff;text-decoration:none}
.aLink.on{background:var(--c-600);color:#fff}
.aLink.on:hover{background:var(--c-600)}
.aLink .aI{width:18px;height:18px;flex:none;opacity:.9}
.aBackToSite{display:flex;align-items:center;gap:10px;padding:10px 11px;margin-top:6px;
  border-top:1px solid rgba(255,255,255,.08);color:var(--ink-faint);
  font-size:12.5px;text-decoration:none}
.aBackToSite:hover{color:#fff;text-decoration:none}
.aBackToSite .aI{width:16px;height:16px;flex:none}
.aMain{flex:1;min-width:0;display:flex;flex-direction:column}
.aBar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:14px;
  height:62px;padding:0 24px;background:var(--sheet);
  border-bottom:1px solid var(--rule)}
.aMenuBtn{display:none;align-items:center;justify-content:center;width:38px;height:38px;
  margin-left:-8px;border-radius:10px;color:var(--ink-soft);cursor:pointer}
.aMenuBtn:hover{background:var(--wash)}
.aMenuBtn svg{width:22px;height:22px}
.aHeading{margin:0;font-family:var(--sans);font-weight:700;font-size:19px;
  letter-spacing:-.01em;color:var(--ink)}
.aBarTools{margin-left:auto;display:flex;align-items:center;gap:14px}
.aMail{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border-radius:999px;
  background:var(--c-50);border:1px solid var(--c-100);color:var(--c-700);
  font-size:12.5px;font-weight:600;text-decoration:none}
.aMail:hover{background:var(--c-100);text-decoration:none}
.aMail .aI{width:16px;height:16px}
.aWho{display:flex;flex-direction:column;align-items:flex-end;line-height:1.15}
.aWho b{font-size:13px;font-weight:600;color:var(--ink)}
.aWho small{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-mid)}
.aOut{padding:8px 15px;border-radius:999px;background:var(--ink);color:#fff;
  border:none;font:600 12.5px var(--sans);cursor:pointer;
  transition:background .15s var(--ease)}
.aOut:hover{background:var(--c-800)}
.aContent{flex:1;padding:28px 32px 64px;width:100%;min-width:0;margin:0}
/* Prose-heavy admin pages (settings help, policy text) read better in a
   column; data pages (tables) want the whole width. So the content is
   full-width by default and the few text-first blocks cap their own
   measure rather than the whole page capping everything. */
.aContent > h1 + p.lead,.aContent > p.lead{max-width:var(--measure)}
.aScrim{display:none}
.aDrawerBox{position:fixed;opacity:0;pointer-events:none}
@media(max-width:920px){
  .aSide{position:fixed;left:0;top:0;z-index:60;transform:translateX(-100%);
    transition:transform .22s var(--ease);box-shadow:var(--lift-hi)}
  .aMenuBtn{display:inline-flex}
  .aScrim{display:block;position:fixed;inset:0;z-index:50;background:rgba(15,23,42,.45);
    opacity:0;pointer-events:none;transition:opacity .22s var(--ease)}
  .aDrawerBox:checked ~ .aShell .aSide{transform:translateX(0)}
  .aDrawerBox:checked ~ .aShell .aScrim{opacity:1;pointer-events:auto}
  .aContent{padding:22px 16px 56px}
  .aBar{padding:0 16px}
  .aWho{display:none}
  .aMail span{display:none}
}

/* ── sign-in screens (console-login card) ───────────────────
   A centred card on a quiet ground — the shape a console login takes.
   Shared by the staff and the customer sign-in. */
body.authBody{min-height:100vh;display:grid;place-items:center;
  background:var(--wash);padding:40px 16px}
.authWrap{width:100%;max-width:480px;display:flex;flex-direction:column;
  align-items:center;gap:24px}
.authBrand{display:flex;align-items:center;gap:13px;text-decoration:none}
.authBrand:hover{text-decoration:none}
.authBrand .markLogo{width:46px;height:46px}
.authBrandName{font-family:var(--mono);font-weight:800;font-size:30px;
  letter-spacing:-.02em;color:var(--ink)}
.authCard{width:100%;box-sizing:border-box;background:var(--sheet);
  border:1px solid var(--rule);border-radius:var(--r-lg);box-shadow:var(--lift-hi);
  padding:34px 38px 36px}
.authH{font-size:25px;font-weight:800;letter-spacing:-.01em;margin:0 0 5px}
.authSub{font-size:14px;color:var(--ink-soft);margin:0 0 20px}
.authForm{display:flex;flex-direction:column;gap:15px}
.authForm label{display:flex;flex-direction:column;gap:6px;
  font-size:13.5px;font-weight:600;color:var(--ink)}
.authForm input{box-sizing:border-box;padding:13px 15px;border:1px solid var(--rule);
  border-radius:var(--r);background:var(--wash);font:400 16px var(--sans);color:var(--ink)}
.authForm input:focus{outline:2px solid var(--c-600);outline-offset:1px;background:var(--sheet)}
.authBtn{width:100%;margin-top:6px;padding:14px;font-size:16px;text-align:center}
.authOr{display:flex;align-items:center;gap:12px;margin:16px 0;
  font-size:12px;color:var(--ink-faint)}
.authOr::before,.authOr::after{content:"";height:1px;background:var(--rule);flex:1}
.authLinks{font-size:12.5px;color:var(--ink-mid);line-height:1.8;margin:16px 0 0;
  padding-top:14px;border-top:1px solid var(--rule-soft)}
.authLinks a{color:var(--c-700);font-weight:600}
.authFoot{font-size:12.5px;color:var(--ink-mid);text-align:center;margin:0}
.authFoot a{color:var(--c-700);font-weight:600}

/* ── brand hub ──────────────────────────────────────────── */
/* The prominent entry point to the kit + generator. */
.brKitCard{display:flex;gap:20px;align-items:center;margin:18px 0 26px;padding:20px 22px;
  text-decoration:none;color:inherit;background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-lg);box-shadow:var(--lift);
  transition:box-shadow .15s var(--ease),border-color .15s var(--ease)}
.brKitCard:hover{text-decoration:none;box-shadow:var(--lift-hi);border-color:var(--c-100)}
.brKitArt{flex:none;width:92px;height:92px;border-radius:var(--r);background:var(--wash);
  display:flex;align-items:center;justify-content:center}
.brKitArt img{width:72px;height:72px}
.brKitBody{display:flex;flex-direction:column;gap:5px;min-width:0}
.brKitBody b{font-size:16px}
.brKitBody span{font-size:13px;color:var(--ink-soft);line-height:1.5}
.brKitGo{color:var(--c-700);font-weight:600;font-size:13px}
@media(max-width:620px){ .brKitCard{flex-direction:column;align-items:flex-start;text-align:left} }

.brMarks{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));
  margin:16px 0 8px}
.brMark{margin:0;display:flex;flex-direction:column;align-items:center;gap:14px;
  padding:30px 20px 16px;border:1px solid var(--rule);border-radius:var(--r-lg);
  background:var(--sheet)}
.brMark .brMarkArt{display:flex;align-items:center;justify-content:center;height:96px}
.brMark .brMarkArt .markLogo{width:72px;height:72px}
.brMark .brMarkArt img{width:96px;height:96px;display:block}
.brWord{font-family:var(--mono);font-weight:800;font-size:22px;letter-spacing:-.01em}
.brMark figcaption{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-mid)}
.brDual{display:flex;gap:8px;margin-top:2px}
.brDual a{font-size:11px;font-weight:700;letter-spacing:.04em;padding:4px 10px;
  border-radius:999px;border:1px solid var(--rule);color:var(--c-700);
  background:var(--sheet);text-decoration:none}
.brDual a:hover{background:var(--c-50);text-decoration:none}
.brMark.dark .brDual a{border-color:rgba(255,255,255,.3);color:#fff;
  background:rgba(255,255,255,.08)}
.brMark.dark .brDual a:hover{background:rgba(255,255,255,.16)}
.brMark.light{color:var(--navy,#024981)}
.brMark.light .markLogo{fill:#024981}
.brMark.dark{background:#024981;border-color:#024981;color:#fafaf8}
.brMark.dark .markLogo{fill:#fafaf8}
.brMark.dark figcaption{color:rgba(250,250,248,.72)}
.brMark.mono{color:var(--ink)}
.brMark.mono .markLogo{fill:var(--ink)}
.brSwatches{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  margin:16px 0}
.brSwatch{display:flex;gap:14px;align-items:center;padding:14px;
  border:1px solid var(--rule);border-radius:var(--r);background:var(--sheet)}
.brChip{width:46px;height:46px;border-radius:10px;flex:none;overflow:hidden;
  box-shadow:inset 0 0 0 1px rgba(15,23,42,.08)}
.brChip svg{display:block;width:100%;height:100%}
.brSwatch b{display:block;font-size:13.5px}
.brSwatch code{display:block;font-size:12px;color:var(--c-700);margin:2px 0}
.brSwatch span{display:block;font-size:12px;color:var(--ink-mid);line-height:1.4}
.brFonts{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));
  margin:16px 0}
.brFont{border:1px solid var(--rule);border-radius:var(--r-lg);background:var(--sheet);
  overflow:hidden}
.brFontSpec{padding:26px 22px;background:var(--wash);border-bottom:1px solid var(--rule);
  display:flex;flex-direction:column;gap:8px}
.brFontSpec.mono{font-family:var(--mono)}
.brFontSpec.sans{font-family:var(--sans)}
.brFontBig{font-size:30px;font-weight:800;color:var(--ink);letter-spacing:-.01em}
.brFontSet{font-size:14px;color:var(--ink-soft)}
.brFontMeta{padding:16px 22px;display:flex;flex-direction:column;gap:6px;align-items:flex-start}
.brFontMeta b{font-size:14.5px}
.brFontMeta span{font-size:12.5px;color:var(--ink-mid)}
.brFontMeta .btn{margin-top:6px}
.brAssets{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));
  margin:16px 0}
.brAsset{border:1px solid var(--rule);border-radius:var(--r-lg);background:var(--sheet);
  padding:14px;display:flex;flex-direction:column;gap:10px}
.brAssetView{height:120px;border-radius:var(--r);background:var(--wash);
  background-image:linear-gradient(45deg,#ecece6 25%,transparent 25%,transparent 75%,#ecece6 75%),
    linear-gradient(45deg,#ecece6 25%,transparent 25%,transparent 75%,#ecece6 75%);
  background-size:16px 16px;background-position:0 0,8px 8px;
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.brAssetView img{max-width:88%;max-height:88%;object-fit:contain}
.brAssetMeta{flex:1}
.brAssetMeta b{display:block;font-size:13.5px}
.brAssetMeta span{display:block;font-size:12px;color:var(--ink-mid);line-height:1.4;margin:2px 0 4px}
.brAssetMeta code{font-size:11.5px;color:var(--ink-soft)}
.brAsset .btn{align-self:flex-start}

/* ── admin ──────────────────────────────────────────────── */
.tiles{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));
       margin:22px 0 10px}
/* Service health — one card per backend the console depends on. */
.svcGrid{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  margin:14px 0 10px}
.svc{display:flex;gap:12px;align-items:flex-start;padding:15px 16px;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift)}
.svc .svcDot{width:9px;height:9px;border-radius:999px;flex:none;margin-top:5px}
.svc.up .svcDot{background:var(--stamp);box-shadow:0 0 0 3px var(--stamp-bg)}
.svc.down{border-color:var(--red);border-left-width:3px}
.svc.down .svcDot{background:var(--red);box-shadow:0 0 0 3px var(--red-bg)}
.svcBody{display:flex;flex-direction:column;gap:2px;min-width:0}
.svcBody b{font-size:14px}
.svcState{font-size:12px;font-weight:600}
.svc.up .svcState{color:var(--stamp)}
.svc.down .svcState{color:var(--red)}
.svcMeta{font-size:12px;color:var(--ink-mid)}

.btn.ghost{background:transparent;border:1px solid var(--rule);color:var(--ink-soft);box-shadow:none}
.btn.ghost:hover{background:var(--wash);color:var(--ink)}
.tableWrap{overflow-x:auto}
td.emptyRow{text-align:center;padding:26px}
.emailField{padding:6px 9px;font:400 12.5px var(--sans);min-width:170px;
  border:1px solid var(--rule);border-radius:8px;background:var(--wash);color:var(--ink)}
.emailField:focus{outline:2px solid var(--c-600);outline-offset:1px;background:var(--sheet)}
/* Per-platform download buttons on the app launcher. */
.dlRow{display:flex;gap:10px;flex-wrap:wrap;margin:4px 0 2px}
.dlRow .btn{display:inline-flex;align-items:center;gap:8px}
.dlIcon{width:16px;height:16px;flex:none}

/* ── product page (Amazon-style) ─────────────────────────────
   Three columns across the top — gallery, detail, buy box — the way an
   Amazon product page reads. "What it does / what you are buying" is a
   full-width row under the two left columns (not under the buy box).
   Folds to two columns, then one, as the screen narrows. The buy box is
   a card that sticks while you read.

   Explicit placement so the source order (gallery, info, buy, split)
   lands where it should: row 1 is the three columns; the split takes
   columns 1–2 of row 2, leaving the buy box alone on the right. */
.pdp{display:grid;gap:34px 30px;align-items:start;margin:8px 0 40px;
  grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(290px,340px)}
.pdpGallery{grid-column:1;grid-row:1}
.pdpInfo{grid-column:2;grid-row:1}
.pdpBuy{grid-column:3;grid-row:1 / span 2}
.pdpSplit{grid-column:1 / 3;grid-row:2}
/* The gallery fills its own column and keeps a fixed 16/10 frame — the
   three-column grid is what holds it to a consistent size now, so it no
   longer needs a hard max-width. Shrinks to fit on a phone. */
.pdpGallery{min-width:0;width:100%;display:flex;flex-direction:column;gap:12px}
.galStage{margin:0;border:1px solid var(--rule);border-radius:var(--r-lg);
  background:var(--sheet);overflow:hidden;aspect-ratio:16/10;width:100%;
  display:flex;align-items:center;justify-content:center}
/* contain, never crop — a product screenshot must be shown in full, the
   same as Amazon never clips a product photo. Off-ratio shots letterbox
   inside the fixed frame rather than resizing it. */
.galStage img,.galStage video{width:100%;height:100%;object-fit:contain;display:block}
.galEmpty{flex-direction:column;gap:10px;color:var(--ink-faint)}
.galEmpty .markLogo{width:64px;height:64px;fill:var(--brand);opacity:.5}
.galEmpty span:last-child{font-family:var(--mono);font-weight:800;font-size:16px;color:var(--ink-faint)}
/* Thumb strip: a horizontal rail that scrolls when there are many. */
.galThumbs{display:flex;gap:10px;overflow-x:auto;scroll-snap-type:x proximity;
  padding-bottom:4px;scrollbar-width:thin}
.galThumb{width:76px;height:58px;flex:none;scroll-snap-align:start;
  border:2px solid var(--rule);border-radius:8px;overflow:hidden;
  background:var(--sheet);display:block;cursor:pointer;
  transition:border-color .12s var(--ease)}
.galThumb img{width:100%;height:100%;object-fit:cover}
.galThumb:hover{border-color:var(--c-600)}

/* ── no-script click-to-swap gallery ──
   A hidden radio per shot; the thumbnail and the ‹ › arrows are labels
   that check it; the matching slide shows. Rules for up to 8 shots. */
.galPick{position:absolute;width:0;height:0;opacity:0;pointer-events:none}
.galSwap{position:relative;display:block;padding:0}
.galSlide{display:none;margin:0;position:relative;width:100%;height:100%;
  aspect-ratio:16/10}
.galSlide img{width:100%;height:100%;object-fit:contain;display:block}
.galArrow{position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:38px;height:38px;display:flex;align-items:center;justify-content:center;
  font-size:26px;line-height:1;color:var(--ink);cursor:pointer;
  background:rgba(255,255,255,.86);border:1px solid var(--rule);border-radius:50%;
  box-shadow:var(--lift);user-select:none;transition:background .12s var(--ease)}
.galArrow:hover{background:#fff;border-color:var(--c-600)}
.galPrev{left:12px}.galNext{right:12px}
.galCount{position:absolute;top:12px;right:12px;z-index:2;font-family:var(--mono);
  font-size:11px;font-weight:600;color:#fff;background:rgba(13,19,38,.6);
  border-radius:999px;padding:3px 9px}
.galCap{position:absolute;left:12px;bottom:12px;z-index:2;font-size:11.5px;
  color:#fff;background:rgba(13,19,38,.6);border-radius:7px;padding:4px 10px;
  max-width:80%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
#pg-0:checked~.galSwap .galSlide:nth-child(1),
#pg-1:checked~.galSwap .galSlide:nth-child(2),
#pg-2:checked~.galSwap .galSlide:nth-child(3),
#pg-3:checked~.galSwap .galSlide:nth-child(4),
#pg-4:checked~.galSwap .galSlide:nth-child(5),
#pg-5:checked~.galSwap .galSlide:nth-child(6),
#pg-6:checked~.galSwap .galSlide:nth-child(7),
#pg-7:checked~.galSwap .galSlide:nth-child(8){display:block}
#pg-0:checked~.galThumbs .galThumb:nth-child(1),
#pg-1:checked~.galThumbs .galThumb:nth-child(2),
#pg-2:checked~.galThumbs .galThumb:nth-child(3),
#pg-3:checked~.galThumbs .galThumb:nth-child(4),
#pg-4:checked~.galThumbs .galThumb:nth-child(5),
#pg-5:checked~.galThumbs .galThumb:nth-child(6),
#pg-6:checked~.galThumbs .galThumb:nth-child(7),
#pg-7:checked~.galThumbs .galThumb:nth-child(8){border-color:var(--c-700)}

/* The "what it does / what you are buying" pair, now in the left column. */
.pdpSplit{display:grid;gap:26px;grid-template-columns:1fr 1fr;margin-top:4px}
.pdpSplit h3{font-size:15px;margin:0 0 10px}
@media(max-width:560px){.pdpSplit{grid-template-columns:1fr;gap:18px}}

.pdpInfo{min-width:0}
.pdpInfo h1{font-size:28px;margin:4px 0 6px;line-height:1.15}
.pdpTagline{font-size:16px;color:var(--ink-soft);margin:0 0 12px}
.pdpTags{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 14px;align-items:center}
.pdpBlurb{font-size:14.5px;line-height:1.65;color:var(--ink);max-width:60ch}
.pdpTicks{margin-top:14px}
.pdpTicks li{font-size:14px}

.pdpBuy{position:sticky;top:84px;background:var(--sheet);border:1px solid var(--rule);
  border-radius:var(--r-lg);box-shadow:var(--lift);padding:20px}
.buyPrice{font-family:var(--mono);font-weight:800;font-size:30px;letter-spacing:-.02em;
  color:var(--ink);margin:0 0 14px;line-height:1.1}
.buyPrice span{display:block;font-family:var(--sans);font-weight:500;font-size:12.5px;
  letter-spacing:0;color:var(--ink-mid);margin-top:4px}
.buyOwned{margin:0 0 10px;font-size:14px;color:var(--stamp)}
.variants{border:none;padding:0;margin:0 0 14px;display:flex;flex-direction:column;gap:8px}
.variants legend{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-mid);padding:0;margin-bottom:4px}
.variant{display:flex;align-items:center;gap:10px;padding:11px 13px;cursor:pointer;
  border:1px solid var(--rule);border-radius:var(--r);background:var(--paper);
  transition:border-color .12s var(--ease),background .12s var(--ease)}
.variant:hover{border-color:var(--rule-hot)}
.variant:has(input:checked){border-color:var(--c-600);background:var(--c-50);
  box-shadow:inset 0 0 0 1px var(--c-600)}
.variant input{margin:0;flex:none;accent-color:var(--c-600)}
.vText{display:flex;flex-direction:column;gap:2px;min-width:0;flex:1}
.vName{font-size:13.5px;font-weight:600;color:var(--ink)}
.vMeta{font-size:11px;color:var(--ink-mid);display:flex;gap:6px;align-items:center}
.vMeta .sku{font-family:var(--mono)}
.vPrice{font-family:var(--mono);font-weight:800;font-size:16px;color:var(--ink);
  flex:none;font-variant-numeric:tabular-nums}
.variant .save{color:var(--stamp);font-weight:700;background:var(--stamp-bg);
  border-radius:5px;padding:0 5px}
.buyActions{display:flex;flex-direction:column;gap:9px;margin-bottom:10px}
.buyBtn{width:100%;text-align:center;justify-content:center}
.btn.ghost{background:transparent;border:1px solid var(--rule);color:var(--ink-soft)}
.pdpAsk{display:inline-block;margin-top:8px;font-size:13px;color:var(--c-700);font-weight:600}
.planNotes{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));margin:12px 0}
.planNote{background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);padding:16px 18px}
.planNote b{display:block;font-size:14.5px;margin-bottom:4px}
.planNote span{font-size:13px;color:var(--ink-soft);line-height:1.5}

/* Tablet: two columns — gallery and details side by side, the buy box
   and the "what it does" row each full-width underneath. */
@media(max-width:1024px){
  .pdp{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .pdpGallery{grid-column:1;grid-row:1}
  .pdpInfo{grid-column:2;grid-row:1}
  .pdpBuy{grid-column:1 / -1;grid-row:2;position:static}
  .pdpSplit{grid-column:1 / -1;grid-row:3}
}
/* Phone: everything stacks in source order. */
@media(max-width:680px){
  .pdp{grid-template-columns:1fr;gap:22px}
  .pdpGallery,.pdpInfo,.pdpBuy,.pdpSplit{grid-column:1;grid-row:auto}
  .pdpBuy{position:static}
}
.funnelInline{width:15px;height:15px;vertical-align:-2px;color:var(--ink-mid)}
.linkish{background:none;border:none;padding:0;color:var(--c-700);font:inherit;
  cursor:pointer;text-decoration:underline}

/* ── spreadsheet-style column filters (admin.js) ─────────────
   A funnel button in each header opens a menu: sort, search, checklist
   of the distinct values. Only present when admin.js runs. */
.tableBar{font-size:12.5px;color:var(--ink-soft);margin:4px 0 10px}
.tableBar b{color:var(--ink);font-variant-numeric:tabular-nums}
th.colHead{position:relative;white-space:nowrap;padding-right:28px}
.colFilterBtn{position:absolute;right:6px;top:50%;transform:translateY(-50%);
  display:inline-flex;align-items:center;justify-content:center;width:22px;height:22px;
  border:none;background:transparent;color:var(--ink-faint);border-radius:6px;cursor:pointer}
.colFilterBtn svg{width:14px;height:14px}
.colFilterBtn:hover{background:var(--wash);color:var(--ink-soft)}
th.isFiltered .colFilterBtn{color:var(--c-600);background:var(--c-50)}
th.sortAsc .colFilterBtn::after,th.sortDesc .colFilterBtn::after{
  content:"";position:absolute;right:-1px;top:-1px;width:6px;height:6px;border-radius:999px;
  background:var(--c-600)}
.colFilter{position:absolute;z-index:80;width:246px;background:var(--sheet);
  border:1px solid var(--rule-hot);border-radius:var(--r);box-shadow:var(--lift-hi);
  padding:8px;display:flex;flex-direction:column;gap:7px}
.colFilter .cfSort{display:flex;gap:6px}
.colFilter .cfSort button{flex:1;font:600 12px var(--sans);padding:7px;border-radius:8px;
  border:1px solid var(--rule);background:var(--wash);color:var(--ink-soft);cursor:pointer}
.colFilter .cfSort button:hover{background:var(--c-50);color:var(--c-700);border-color:var(--c-100)}
.colFilter .cfSearch{width:100%;box-sizing:border-box;padding:7px 9px;font:400 13px var(--sans);
  border:1px solid var(--rule);border-radius:8px;background:var(--wash);color:var(--ink)}
.colFilter .cfSearch:focus{outline:2px solid var(--c-600);outline-offset:1px;background:var(--sheet)}
.colFilter .cfAll{border-bottom:1px solid var(--rule-soft);padding-bottom:6px}
.colFilter .cfAll label,.colFilter .cfItem{display:flex;align-items:center;gap:8px;
  font-size:13px;color:var(--ink);cursor:pointer;padding:3px 4px;border-radius:6px}
.colFilter .cfItem:hover{background:var(--wash)}
.colFilter .cfItem i{color:var(--ink-faint);font-style:italic}
.colFilter .cfList{max-height:210px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.colFilter .cfFoot{display:flex;gap:7px;justify-content:flex-end;border-top:1px solid var(--rule-soft);
  padding-top:7px}

/* Clickable table rows (enquiries list): the first cell holds a real
   link whose ::after stretches over the whole row. No script. */
table.data.rows tbody tr{position:relative;transition:background .12s var(--ease)}
table.data.rows tbody tr:hover{background:var(--wash);cursor:pointer}
.enqRow.isNew{box-shadow:inset 3px 0 0 var(--c-600)}
.enqFromCell .rowLink{font-weight:600;color:var(--ink);text-decoration:none}
.enqFromCell .rowLink::after{content:"";position:absolute;inset:0}
.enqFromCell .meta{display:block;font-size:12px}

/* ── enquiry thread (email view) ─────────────────────────── */
.emBar{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin:0 0 16px}
.emHead{background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift);padding:20px 22px;margin:0 0 18px}
.emHead h1{margin:0 0 12px;font-size:21px}
.emFacts{display:grid;gap:8px 28px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));margin:0}
.emFacts > div{display:flex;flex-direction:column;gap:1px}
.emFacts dt{font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--ink-mid)}
.emFacts dd{margin:0;font-size:14px;color:var(--ink)}
.emFacts .addr{font-family:var(--mono);font-size:13px}
.emThread{display:flex;flex-direction:column;gap:14px;margin:0 0 22px}
.emMsg{max-width:82%;border-radius:var(--r-lg);padding:14px 16px;box-shadow:var(--lift)}
.emMsg.in{align-self:flex-start;background:var(--sheet);border:1px solid var(--rule);
  border-top-left-radius:4px}
.emMsg.out{align-self:flex-end;background:var(--c-50);border:1px solid var(--c-100);
  border-top-right-radius:4px}
.emMeta{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.emMeta b{font-size:13.5px}
.emMeta .emWhen{margin-left:auto}
.emText{font-size:14.5px;line-height:1.6;color:var(--ink);white-space:pre-wrap;word-break:break-word}
.emNote{align-self:center;text-align:center;font-size:12px;padding:4px 10px}
.emComposer{background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift);padding:20px 22px;display:flex;flex-direction:column;gap:10px}
.emComposer label{font-size:13px;font-weight:600}
.emComposer textarea{width:100%;box-sizing:border-box;padding:12px 14px;
  font:400 14.5px/1.6 var(--sans);color:var(--ink);background:var(--wash);
  border:1px solid var(--rule);border-radius:var(--r);resize:vertical}
.emComposer textarea:focus{outline:2px solid var(--c-600);outline-offset:1px;background:var(--sheet)}
.emActions{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.emComposer .fine{margin:2px 0 0}
@media(max-width:620px){ .emMsg{max-width:94%} }
.emSync{margin:14px 0;color:var(--c-700);font-weight:600}
.tile{padding:18px 20px}
a.tile{text-decoration:none;color:inherit;display:block;
  transition:box-shadow .15s var(--ease),transform .15s var(--ease),border-color .15s var(--ease)}
a.tile:hover{text-decoration:none;box-shadow:var(--lift-hi);transform:translateY(-1px);
  border-color:var(--rule-hot)}
.tile.hot{border-color:var(--amber);border-left-width:3px}
.tile b{display:block;font-family:var(--mono);font-size:26px;font-weight:800;
        line-height:1.15;letter-spacing:-.03em}
.tile span{color:var(--ink-soft);font-size:12.5px}
.blockers{list-style:none;padding:0;margin:0;font-size:13.5px}
.blockers li{padding:13px 0;border-bottom:1px solid var(--rule-soft);
             display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}
.blockers li:last-child{border-bottom:none}
.settings{margin:24px 0}

/* ── admin tabs (no-script) ──
   A hidden radio per tab; the tab is its label; CSS shows the matching
   panel. Used by Settings. Rules cover up to 12 tabs. */
.adminTabs{margin-top:18px}
.tabRadio{position:absolute;width:0;height:0;opacity:0;pointer-events:none}
.tabBar{display:flex;gap:2px;overflow-x:auto;border-bottom:1px solid var(--rule);
  margin-bottom:22px;scrollbar-width:thin}
.tabBtn{flex:none;padding:11px 16px;cursor:pointer;font-size:13.5px;font-weight:600;
  color:var(--ink-soft);border-bottom:2px solid transparent;white-space:nowrap;
  transition:color .12s var(--ease),border-color .12s var(--ease)}
.tabBtn:hover{color:var(--ink)}
.tabPanel{display:none}
.tabPanel.settings{margin:0}
.setBlurb{margin:0 0 16px;max-width:60ch}
.setTest{margin-top:20px}
#st-0:checked~.tabPanels .tabPanel:nth-child(1),
#st-1:checked~.tabPanels .tabPanel:nth-child(2),
#st-2:checked~.tabPanels .tabPanel:nth-child(3),
#st-3:checked~.tabPanels .tabPanel:nth-child(4),
#st-4:checked~.tabPanels .tabPanel:nth-child(5),
#st-5:checked~.tabPanels .tabPanel:nth-child(6),
#st-6:checked~.tabPanels .tabPanel:nth-child(7),
#st-7:checked~.tabPanels .tabPanel:nth-child(8),
#st-8:checked~.tabPanels .tabPanel:nth-child(9),
#st-9:checked~.tabPanels .tabPanel:nth-child(10),
#st-10:checked~.tabPanels .tabPanel:nth-child(11),
#st-11:checked~.tabPanels .tabPanel:nth-child(12){display:block}
#st-0:checked~.tabBar .tabBtn:nth-child(1),
#st-1:checked~.tabBar .tabBtn:nth-child(2),
#st-2:checked~.tabBar .tabBtn:nth-child(3),
#st-3:checked~.tabBar .tabBtn:nth-child(4),
#st-4:checked~.tabBar .tabBtn:nth-child(5),
#st-5:checked~.tabBar .tabBtn:nth-child(6),
#st-6:checked~.tabBar .tabBtn:nth-child(7),
#st-7:checked~.tabBar .tabBtn:nth-child(8),
#st-8:checked~.tabBar .tabBtn:nth-child(9),
#st-9:checked~.tabBar .tabBtn:nth-child(10),
#st-10:checked~.tabBar .tabBtn:nth-child(11),
#st-11:checked~.tabBar .tabBtn:nth-child(12){color:var(--c-700);border-bottom-color:var(--c-700)}
/* The staff form is a column rather than the .form plate, so its
   controls need the same treatment given explicitly. */
/* ── add-a-team-member flow ── */
.staffNew{margin:18px 0 34px}
.staffNew h2{font-size:17px;margin:0 0 6px}
.staffForm{margin-top:16px}
.staffFields{display:grid;gap:14px;grid-template-columns:repeat(3,1fr);margin-bottom:20px}
.staffFields label{display:flex;flex-direction:column;gap:6px;font-size:12.5px;font-weight:600;color:var(--ink)}
.staffFields .opt{font-weight:400;color:var(--ink-faint)}
.staffFields input{padding:10px 12px;border:1px solid var(--rule);border-radius:var(--r);
  font:inherit;background:var(--paper)}
.staffFields input:focus{outline:none;border-color:var(--c-600);box-shadow:0 0 0 3px var(--c-50)}
.rolePick{border:none;padding:0;margin:0 0 20px;display:grid;gap:12px;
  grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.rolePick legend{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-mid);padding:0;margin-bottom:10px;float:left;width:100%}
.roleCard{display:flex;flex-direction:column;gap:5px;padding:14px;cursor:pointer;
  border:1.5px solid var(--rule);border-radius:var(--r);background:var(--paper);
  transition:border-color .12s var(--ease),background .12s var(--ease)}
.roleCard:hover{border-color:var(--rule-hot)}
.roleCard:has(input:checked){border-color:var(--c-600);background:var(--c-50);
  box-shadow:inset 0 0 0 1px var(--c-600)}
.roleCard input{position:absolute;opacity:0;pointer-events:none}
.rcHead{display:flex;align-items:center;gap:8px}
.rcName{font-size:14px;font-weight:700;color:var(--ink)}
.rcTag{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
  color:var(--c-700);background:var(--c-50);border:1px solid var(--c-600);border-radius:999px;padding:1px 7px}
.rcWhat{font-size:12px;line-height:1.5;color:var(--ink-soft)}
.roleBadge{font-size:11.5px;font-weight:700;border-radius:999px;padding:3px 10px;
  background:var(--wash);color:var(--ink-soft);border:1px solid var(--rule)}
.roleBadge.role-owner{color:var(--c-700);background:var(--c-50);border-color:var(--c-600)}
@media(max-width:620px){.staffFields{grid-template-columns:1fr}}

.stack{display:grid;gap:8px;max-width:460px;background:var(--sheet);
       border:1px solid var(--rule);border-radius:var(--r-lg);
       box-shadow:var(--lift);padding:24px;margin-top:8px}
.stack label{font-size:13px;font-weight:600;margin-top:10px}
.stack label:first-of-type{margin-top:0}
.stack input,.stack select{
  padding:11px 13px;background:var(--wash);color:var(--ink);
  border:1px solid var(--rule);border-radius:var(--r);font:400 14px/1.5 var(--sans);
}
.stack input:focus,.stack select:focus{
  outline:none;border-color:var(--c-600);background:var(--sheet);
  box-shadow:0 0 0 3px var(--c-50);
}
.stack button{margin-top:18px;justify-self:start}

/* ── enquiries ──────────────────────────────────────────────
   One card per person who wrote in. The address is set in the mono
   face at full contrast: it is the single thing on this page somebody
   needs to read character by character, and `overflow-wrap:anywhere`
   is what stops a long one pushing the card wider than the window
   instead of folding. */
.enqList{display:grid;gap:18px;margin:26px 0 0}
.enq{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift);padding:22px 24px;
}
.enq.isNew{border-left:3px solid var(--amber)}
.enqTop{display:flex;justify-content:space-between;align-items:flex-start;
        gap:16px;flex-wrap:wrap}
.enqWho{display:flex;align-items:center;gap:10px;flex-wrap:wrap;font-size:15px}
.enqWhen{text-align:right;font-size:12.5px;line-height:1.6;white-space:nowrap}
.enqFacts{
  display:grid;grid-template-columns:auto 1fr;gap:6px 18px;
  margin:16px 0 0;font-size:13.5px;align-items:baseline;
}
.enqFacts dt{
  font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;
  color:var(--ink-faint);
}
.enqFacts dd{margin:0;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.enqFacts .addr{
  font-family:var(--mono);font-size:13px;color:var(--ink);
  user-select:all;overflow-wrap:anywhere;
}
.enqBody{
  margin:18px 0 0;padding:14px 16px;background:var(--wash);
  border-left:2px solid var(--rule-hot);border-radius:0 var(--r) var(--r) 0;
  font-size:14px;line-height:1.65;white-space:pre-wrap;overflow-wrap:anywhere;
}
.enqNotes{margin:14px 0 0;font-size:13px}
.enqNotes summary{cursor:pointer;color:var(--c-700);font-weight:600}
.enqNotes pre{
  margin:10px 0 0;padding:12px 14px;background:var(--wash);
  border:1px solid var(--rule-soft);border-radius:var(--r);
  font:400 12.5px/1.6 var(--mono);white-space:pre-wrap;overflow-wrap:anywhere;
}
.enqReply{display:grid;gap:8px;margin:20px 0 0;
          border-top:1px solid var(--rule-soft);padding-top:18px}
.enqReply label{font-size:13px;font-weight:600}
.enqReply textarea{
  padding:12px 13px;background:var(--wash);color:var(--ink);
  border:1px solid var(--rule);border-radius:var(--r);
  font:400 14px/1.6 var(--sans);resize:vertical;
}
.enqReply textarea:focus{
  outline:none;border-color:var(--c-600);background:var(--sheet);
  box-shadow:0 0 0 3px var(--c-50);
}
.enqActions{display:flex;gap:10px;flex-wrap:wrap;margin-top:4px}
@media (max-width:720px){
  .enqWhen{text-align:left;white-space:normal}
  .enqFacts{grid-template-columns:1fr;gap:2px 0}
  .enqFacts dt{margin-top:10px}
}

.legal{
  white-space:pre-wrap;font:400 13.5px/1.75 var(--sans);color:var(--ink);
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  box-shadow:var(--lift);padding:26px 28px;overflow-x:auto;max-width:var(--measure);
}

/* ── licence agreement / legal document ─────────────────────
   A sticky table of contents beside a readable column. The clause
   numbers hang in their own gutter so the text aligns down the page. */
.legalDoc{display:grid;gap:40px;align-items:start;
  grid-template-columns:minmax(0,220px) minmax(0,1fr);margin:6px 0 32px}
.legalToc{position:sticky;top:calc(env(safe-area-inset-top,0px) + 80px);
  font-size:13px;border-left:2px solid var(--rule);padding-left:16px}
.legalTocHead{display:block;font-size:11px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--ink-faint);margin-bottom:10px}
.legalToc ol{list-style:none;margin:0;padding:0;counter-reset:toc;display:flex;flex-direction:column;gap:7px}
.legalToc li{counter-increment:toc}
.legalToc a{display:block;color:var(--ink-soft);text-decoration:none;line-height:1.35}
.legalToc a::before{content:counter(toc) ". ";color:var(--ink-faint);font-variant-numeric:tabular-nums}
.legalToc a:hover{color:var(--c-700)}
.legalBody{min-width:0;max-width:68ch}
.legalBody h1{font-size:30px;margin:0 0 6px;line-height:1.15}
.legalMeta{font-size:12.5px;color:var(--ink-faint);margin:0 0 24px;
  padding-bottom:18px;border-bottom:1px solid var(--rule)}
.legalBody section{margin:0 0 30px;scroll-margin-top:90px}
.legalBody h2{font-size:17px;margin:0 0 14px;display:flex;gap:10px;align-items:baseline}
.legalBody h2 .secNum{color:var(--c-600);font-variant-numeric:tabular-nums;flex:none}
.legalBody p{font-size:14px;line-height:1.7;color:var(--ink);margin:0 0 12px;max-width:66ch}
.legalBody .clause{display:grid;grid-template-columns:46px 1fr;gap:10px;align-items:start}
.legalBody .clause .cnum{font-weight:700;color:var(--ink-soft);
  font-variant-numeric:tabular-nums;font-size:13px;padding-top:1px}
.legalList{margin:0 0 14px;padding:0;list-style:none;display:flex;flex-direction:column;gap:8px;
  counter-reset:la}
.legalList li{counter-increment:la;position:relative;padding-left:30px;font-size:14px;
  line-height:1.6;color:var(--ink);max-width:62ch}
.legalList li::before{content:"(" counter(la,lower-alpha) ")";position:absolute;left:0;top:0;
  color:var(--ink-faint);font-weight:600}
.legalBackTop{margin-top:26px;padding-top:16px;border-top:1px solid var(--rule);font-size:13px}
.legalBackTop a{color:var(--c-700);text-decoration:none}
@media(max-width:800px){
  .legalDoc{grid-template-columns:1fr;gap:20px}
  .legalToc{position:static;border-left:0;border-bottom:1px solid var(--rule);
    padding:0 0 16px;columns:2;column-gap:20px}
}

/* ── footer ─────────────────────────────────────────────── */
footer{
  border-top:1px solid var(--rule);background:var(--sheet);
  padding:48px clamp(16px,3vw,48px) 40px;font-size:13px;color:var(--ink-soft);line-height:1.8;
  margin-top:auto;
}
.footCols{
  max-width:none;margin:0;display:grid;gap:32px;
  grid-template-columns:1.6fr 1fr 1fr 1.2fr;align-items:start;
}
.footCols h4{
  font-size:11px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink);margin:0 0 12px;
}
.footCols p{font-size:12.5px;line-height:1.7;margin:0 0 10px}
.footCols a{color:var(--ink-soft);text-decoration:none;display:block;
  font-size:12.5px;padding:2px 0}
.footCols a:hover{color:var(--ink);text-decoration:none}
.footBrand{display:flex;align-items:center;gap:10px;margin-bottom:12px}
/* Same wordmark face as the header, sized to sit at the mark's height. */
.footBrand span{font-family:var(--mono);font-size:20px;font-weight:800;
  letter-spacing:-.02em;color:var(--ink)}
.footNote{
  max-width:none;margin:32px 0 0;padding-top:20px;
  border-top:1px solid var(--rule);font-size:11.5px;color:var(--ink-faint);
  display:flex;justify-content:space-between;gap:18px;flex-wrap:wrap;
}
.footNote a{color:var(--ink-faint)}
.footNote a:hover{color:var(--ink)}

/* ── responsive ─────────────────────────────────────────── */
@media (max-width:1000px){
  .bag{grid-template-columns:1fr}
  .summary{position:static}
  .footCols{grid-template-columns:1fr 1fr}
}
@media (max-width:860px){
  .topIn{padding:10px 16px;gap:12px;flex-wrap:wrap;position:relative}
  .navBurger{display:flex;order:3;margin-left:10px}
  .topTools{order:2;margin-left:auto}
  /* The nav drops down below the bar, full width, when the burger toggles
     the hidden checkbox. Closed by default; no script involved. */
  .top nav{
    order:4;display:none;flex-direction:column;align-items:stretch;gap:2px;
    width:100%;margin-top:10px;padding-top:10px;border-top:1px solid var(--rule);
  }
  .navToggle:checked ~ nav{display:flex}
  .top nav a{padding:11px 6px;border-radius:8px;font-size:15px}
  .top nav a:hover{background:var(--wash)}
  .top nav a.navCta{text-align:center;margin-top:6px}
  .top nav .inline{display:block}
  .top nav .navBtn{width:100%;justify-content:center;margin-top:6px}
  /* Burger → X when open. */
  .navToggle:checked ~ .navBurger span:nth-child(1){transform:translateY(7px) rotate(45deg)}
  .navToggle:checked ~ .navBurger span:nth-child(2){opacity:0}
  .navToggle:checked ~ .navBurger span:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
}
@media (max-width:720px){
  main{padding:34px 16px 64px}
  .hero{margin:-34px -16px 0;padding:40px 16px 44px}
  h1,.hero.plain .heroIn h1{font-size:30px}
  .heroIn h1{font-size:34px}
  h2{font-size:21px}
  .statement{font-size:15.5px}
  .initial{font-size:54px}
  .offer{padding:22px;border-radius:var(--r-lg)}
  .offerCard{flex:1 1 100%}
  .footCols{grid-template-columns:1fr}
  table.data{font-size:12.5px}
  .item{flex-wrap:wrap}
  .itemBody{flex:1 1 100%;order:-1}
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{animation-duration:.01ms !important;transition-duration:.01ms !important}
  .cardItem:hover{transform:none}
}

/* Printed, this is a receipt or an invoice. The chrome is furniture
   for a screen and only gets in the way on paper. */
@media print{
  .top,.announce,footer,.heroActions,.btn,.filters,.searchBar{display:none}
  body{background:#fff}
  .card,.summary,.item,.plan{box-shadow:none;border-color:#ccc}
}

/* ════════════════════════════════════════════════════════════
   app.initcap.pro — the instrument.

   Everything below is scoped to body.app and keeps the console
   palette the desktop application uses. The page this shell wraps
   is apps/MeridianSCP/app/index.html, which draws itself dark; a
   daylight frame around it would read as a rendering fault rather
   than as a design.

   The variables are the same names the daylight site uses, so the
   components above are inherited rather than restated. Only the
   handful that cannot be expressed as a colour swap — the lift
   shadows, which are black on white paper and useless on a dark
   plate — are overridden by rule.
   ════════════════════════════════════════════════════════════ */
body.app{
  --paper:#03080d;
  --sheet:rgba(10,26,38,.62);
  --wash:rgba(16,40,56,.7);
  --rule:rgba(77,216,255,.22);
  --rule-soft:rgba(77,216,255,.12);
  --rule-hot:rgba(77,216,255,.55);
  --ink:#d7f2ff;
  --ink-soft:#6f97ad;
  --ink-mid:#628da6;
  --ink-faint:#587c90;
  --c-50:rgba(77,216,255,.10);
  --c-100:rgba(77,216,255,.22);
  --c-500:#4dd8ff;
  --c-600:#4dd8ff;
  --c-700:#7fe4ff;
  --c-800:#a6edff;
  --c-900:#d7f2ff;
  --stamp:#2ee696;
  --stamp-bg:rgba(46,230,150,.12);
  --amber:#ffb84d;
  --amber-bg:rgba(255,184,77,.12);
  --star:#ffb84d;
  --red:#ff5a5a;
  --red-bg:rgba(255,90,90,.12);
  --lift:none;
  --lift-hi:0 10px 30px rgba(0,0,0,.45);
  background:var(--paper);color:var(--ink);
}
body.app::before{
  content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(77,216,255,.07), transparent 60%),
    linear-gradient(rgba(77,216,255,.030) 1px, transparent 1px) 0 0/100% 34px,
    linear-gradient(90deg, rgba(77,216,255,.030) 1px, transparent 1px) 0 0/34px 100%;
}
body.app header,body.app main,body.app footer{position:relative;z-index:1}
body.app .top{
  background:linear-gradient(180deg, rgba(77,216,255,.07), rgba(3,8,13,.86));
  backdrop-filter:blur(12px);
}
body.app footer{background:transparent}
body.app main{max-width:1060px}
body.app a{color:#4dd8ff}
body.app a:hover{color:#a6edff}
body.app .brandName,body.app .brand .cap{color:#4dd8ff}
/* On the dark app host the [I] takes the host's cyan — still no tile. */
body.app .mark{color:#4dd8ff}
body.app .btn.primary{background:rgba(77,216,255,.16);border-color:#4dd8ff;color:#4dd8ff}
body.app .btn.primary:hover{background:rgba(77,216,255,.26);color:#a6edff}
body.app .btn.go{background:rgba(77,216,255,.22);border-color:#4dd8ff;color:#d7f2ff}
body.app .bagBtn{background:rgba(77,216,255,.16);border-color:#4dd8ff;color:#4dd8ff}
body.app .form input[type=text],body.app .form input[type=email],
body.app .form input[type=password],body.app .stack input,body.app .stack select{
  background:rgba(3,12,18,.75);color:var(--ink);
}
body.app ::selection{background:rgba(77,216,255,.28);color:#eaffff}
body.app ::-webkit-scrollbar-track{background:#03080d}
body.app ::-webkit-scrollbar-thumb{background:rgba(77,216,255,.3)}
.who{font-size:12.5px;color:var(--ink-soft)}
.appGate{max-width:460px;margin:8vh auto 0}
.appGate .form{margin-top:24px}

/* product page: system requirements, guides and videos */
table.reqs{width:100%;max-width:860px;border-collapse:collapse;font-family:var(--sans);font-size:15px;margin:6px 0 10px}
table.reqs th{text-align:left;vertical-align:top;width:170px;padding:11px 14px 11px 0;
  border-bottom:1px solid var(--rule);font-weight:600}
table.reqs td{padding:11px 0;border-bottom:1px solid var(--rule)}
table.reqs tr:last-child th,table.reqs tr:last-child td{border-bottom:none}
.media{display:grid;gap:22px;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));margin:10px 0 18px}
.media figure{margin:0}
.media video{width:100%;aspect-ratio:16/9;background:#000;border-radius:6px;display:block}
.media figcaption{font-family:var(--sans);font-size:14.5px;margin-top:8px}
.guides{list-style:none;padding:0;margin:4px 0 24px;font-family:var(--sans)}
.guides li{padding:8px 0;border-bottom:1px solid var(--rule)}
.guides li:last-child{border-bottom:none}
.guides .meta{margin-left:8px}
.releases{margin:6px 0 24px}
.release{padding:14px 0;border-bottom:1px solid var(--rule)}
.release:last-child{border-bottom:none}
.release h3{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 2px}
.release h4{margin:10px 0 2px;font-family:var(--sans);font-size:14px}
.olderVersions{margin:10px 0 2px;font-family:var(--sans)}
.olderVersions summary{cursor:pointer;font-size:14px;color:var(--c-600)}
.olderVersions form.inline{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:8px 0 0}
.olderVersions select{padding:7px 9px;font:inherit;border:1px solid var(--rule);border-radius:var(--r-sm);background:var(--plate);color:inherit}
@media (max-width:600px){table.reqs th{width:auto;display:block;padding-bottom:2px;border-bottom:none}
  table.reqs td{display:block;padding-top:0}}
/* ════════════════════════════════════════════════════════════
   THE SELLING PARTS
   ──────────────────────────────────────────────────────────
   Added with the shop-front rework. Everything above dresses the
   firm; this section is the handful of components whose only job
   is to turn a visitor into a customer or a conversation.

   The rule they all follow: a slot that has nothing real in it
   renders NOTHING. No stock photography, no placeholder quote,
   no "Trusted by thousands". A page that is honest about being
   new reads better than one caught implying it is not.
   ════════════════════════════════════════════════════════════ */

/* ── the trust bar ──────────────────────────────────────────
   Four facts under the hero, each checkable against the product
   or the licence. These are the answers to what somebody about
   to spend money is actually wondering, so they go above the
   fold rather than on an About page nobody opens. */
.trust{
  display:grid;gap:1px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));
  background:var(--rule);border:1px solid var(--rule);border-radius:var(--r-lg);
  overflow:hidden;margin:36px 0 0;box-shadow:var(--lift);
}
.trust > div{background:var(--sheet);padding:18px 20px}
.trust b{
  display:flex;align-items:center;gap:7px;font-size:13px;font-weight:700;
  letter-spacing:-.01em;color:var(--ink);margin-bottom:5px;
}
.trust span{display:block;font-size:12.5px;line-height:1.55;color:var(--ink-soft)}
.trust svg{width:15px;height:15px;color:var(--c-600);flex:none}

/* ── a product's own pictures ───────────────────────────────
   The single biggest thing on a page that sells software, and
   the one thing this site could not show. A screenshot is the
   product; prose about a screenshot is not.

   The frame is deliberately plain — a hairline and a radius —
   because the image has to be the loudest thing in it. Every
   image carries its caption as alt text; the store refuses a
   screenshot without one. */
.shots{display:flex;flex-direction:column;gap:14px;margin:26px 0 0}
.shot{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  overflow:hidden;box-shadow:var(--lift);
}
.shot img,.shot video{display:block;width:100%;height:auto;background:var(--wash)}
.shot figcaption{
  padding:11px 16px;border-top:1px solid var(--rule-soft);
  font-size:12.5px;line-height:1.5;color:var(--ink-soft);
}
/* More than one screenshot: a strip that scrolls rather than a
   carousel, because a carousel needs script and hides the thing
   it is showing. */
.shotStrip{
  display:grid;gap:14px;grid-auto-flow:column;grid-auto-columns:minmax(280px,1fr);
  overflow-x:auto;padding-bottom:6px;margin:26px 0 0;
}
.shotStrip .shot{min-width:0}
/* The empty state, shown to STAFF only — a visitor never sees a
   gap where a picture should be. */
.shotNone{
  border:1px dashed var(--rule-hot);border-radius:var(--r-lg);
  padding:22px;background:var(--wash);font-size:13px;color:var(--ink-soft);
}

/* ── reaching a person ──────────────────────────────────────
   A green WhatsApp button, a phone number, and a form. Each is
   rendered only when the setting behind it is filled in: a
   contact route that is advertised and not answered costs more
   than one that was never offered. */
.waBtn{
  display:inline-flex;align-items:center;gap:9px;padding:11px 18px;
  background:#1faf52;border:1px solid #189945;color:#fff;
  border-radius:var(--r);font:700 13.5px/1.2 var(--sans);
  text-decoration:none;box-shadow:var(--lift);
}
.waBtn:hover{background:#189945;color:#fff;text-decoration:none}
.waBtn svg{width:17px;height:17px;flex:none}
.waHours{display:block;font-size:11.5px;color:var(--ink-faint);margin-top:7px}

/* The contact block: the form beside the other ways through. */
.reach{
  display:grid;gap:22px;grid-template-columns:minmax(0,1.5fr) minmax(260px,1fr);
  align-items:start;margin-top:8px;
}
.reachSide{display:flex;flex-direction:column;gap:14px}
.reachCard{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-lg);
  padding:22px;box-shadow:var(--lift);
}
.reachCard h3{margin-bottom:8px}
.reachCard p{font-size:13px;line-height:1.6;color:var(--ink-soft);margin:0 0 14px}
.reachCard p:last-child{margin-bottom:0}
.reachCard .dl{display:flex;flex-direction:column;gap:3px;font-size:13px}
.reachCard .dl span{color:var(--ink-faint);font-size:11.5px}
.reachCard .dl a{font-weight:600}

/* ── the launch list ────────────────────────────────────────
   One field in the footer. Nothing is sent to an address until
   somebody opens a link sent TO it, which is what makes an open
   form safe to have at all. */
.listBox{display:flex;gap:8px;margin-top:10px;max-width:340px}
.listBox input{
  flex:1;min-width:0;background:var(--wash);border:1px solid var(--rule);
  border-radius:var(--r);padding:9px 12px;font:400 12.5px var(--sans);color:var(--ink);
}
.listBox input:focus{outline:none;border-color:var(--c-600);background:var(--sheet)}
.listBox .btn{flex:none;padding:9px 14px;font-size:12px}

/* A page that exists only to say one thing: confirmed, or gone. */
.said{
  max-width:52ch;margin:6vh auto 0;text-align:center;
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r-xl);
  padding:40px 32px;box-shadow:var(--lift);
}
.said .ring{
  width:52px;height:52px;display:grid;place-items:center;margin:0 auto 18px;
  border-radius:999px;background:var(--stamp-bg);color:var(--stamp);
  border:1px solid var(--stamp);
}
.said .ring.quiet{background:var(--wash);color:var(--ink-soft);border-color:var(--rule)}
.said .ring svg{width:24px;height:24px}
.said h1{font-size:25px;margin-bottom:10px;max-width:none}
.said p{font-size:14px;line-height:1.65;color:var(--ink-soft);margin:0 0 10px}
.said .btn{margin-top:18px}

/* ── a honeypot ─────────────────────────────────────────────
   A field a person cannot see and a crawler fills in. Moved off
   screen rather than display:none, because some bots skip
   anything that is display:none and this is meant to be found by
   them and not by anybody else. aria-hidden and tabindex keep it
   away from a screen reader and the keyboard. */
.trap{
  position:absolute!important;left:-9999px!important;width:1px;height:1px;
  overflow:hidden;
}

/* ════════════════════════════════════════════════════════════
   app.initcap.pro — the console's own panes.

   views-scp.js renders the browser version of MERIDIAN SCP, and
   its classes had no stylesheet at all: the panes were arriving
   as unstyled block elements. Laid out here the way the desktop
   console lays them out — what you are connected to on the left,
   what came back on the right — and scoped to body.app so none
   of it can reach the daylight site.
   ════════════════════════════════════════════════════════════ */
body.app .console{
  display:grid;gap:18px;grid-template-columns:minmax(260px,340px) minmax(0,1fr);
  align-items:start;
}
body.app .console > .left,body.app .console > .right{min-width:0}
body.app .left,body.app .right{display:flex;flex-direction:column;gap:14px}

body.app .srvCard{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  padding:16px 18px;
}
body.app .srvHead{
  display:flex;align-items:center;gap:9px;font:600 12px/1 var(--sans);
  letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft);
  margin-bottom:12px;
}
body.app .srvDot{
  width:8px;height:8px;border-radius:999px;background:var(--stamp);flex:none;
  box-shadow:0 0 0 3px rgba(46,230,150,.18);
}
body.app .srvRows{display:flex;flex-direction:column;gap:8px;font-size:13px}
body.app .srvRows > div{
  display:flex;justify-content:space-between;gap:12px;
  padding-bottom:8px;border-bottom:1px solid var(--rule-soft);
}
body.app .srvRows > div:last-child{border-bottom:none;padding-bottom:0}
body.app .srvRows span{color:var(--ink-soft)}
body.app .srvRows b{font-family:var(--mono);font-weight:500;color:var(--ink)}

/* The file browser: a header row, then rows that behave like a
   list and not like a table, so a long name wraps instead of
   pushing the size column off the pane. */
body.app .files{
  background:var(--sheet);border:1px solid var(--rule);border-radius:var(--r);
  overflow:hidden;
}
body.app .fhead,body.app .frow{
  display:grid;grid-template-columns:1fr 92px 108px 84px;gap:10px;
  padding:9px 14px;align-items:center;font-size:12.5px;
}
body.app .fhead{
  background:var(--wash);border-bottom:1px solid var(--rule);
  font:600 11px/1 var(--sans);letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink-faint);
}
body.app .frow{border-bottom:1px solid var(--rule-soft)}
body.app .frow:last-child{border-bottom:none}
body.app .frow:hover{background:rgba(77,216,255,.05)}
body.app .fn{min-width:0;overflow-wrap:anywhere}
body.app .fn a{font-weight:500}
body.app .fs,body.app .fk{font-family:var(--mono);font-size:11.5px;color:var(--ink-soft)}
body.app .fs{text-align:right;font-variant-numeric:tabular-nums}
body.app .fa{text-align:right}
body.app .dir .fn a{font-weight:600}
body.app .dir .fn a::before{content:'▸ ';color:var(--ink-faint)}

/* Where you are, as a path you can click back up. */
body.app .crumbs{
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font:500 12px/1.6 var(--mono);color:var(--ink-soft);
  padding:10px 14px;background:var(--wash);
  border:1px solid var(--rule);border-radius:var(--r-sm);
}
body.app .crumbs a{text-decoration:none}
body.app .crumbs .sep{color:var(--ink-faint)}
body.app .crumbs .here{color:var(--ink);font-weight:600}

body.app .toolbar{
  display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  padding:12px 14px;background:var(--sheet);
  border:1px solid var(--rule);border-radius:var(--r);
}
body.app .toolbar .grow{flex:1;min-width:0}

@media (max-width:860px){
  body.app .console{grid-template-columns:1fr}
  body.app .fhead,body.app .frow{grid-template-columns:1fr 78px 72px}
  body.app .fk{display:none}
}

/* ── responsive, for the selling parts ──────────────────── */
@media (max-width:860px){
  .reach{grid-template-columns:1fr}
}
@media (max-width:720px){
  .said{margin-top:3vh;padding:30px 22px;border-radius:var(--r-lg)}
  .trust{grid-template-columns:1fr}
  .shotStrip{grid-auto-flow:row;grid-auto-columns:auto}
}

.signedAs{font-size:11.5px;color:var(--ink-faint)}

/* ============================================================
   NIX Link (the free Android app): its "Free" stamp, the QR card
   and popup, and the illustrated set-up guide. Kept in the sheet
   because the site's CSP (style-src 'self') strips inline <style>
   and style="" - so these must be real classes, not inline.
   ============================================================ */
.stamp.free{color:#0a7d55;background:#e6f9f0;border-color:#9ae0c4}

/* NIX's chamfered dark card (top-left & bottom-right corners cut) */
.nl-clip{clip-path:polygon(18px 0,100% 0,100% calc(100% - 18px),calc(100% - 18px) 100%,0 100%,0 18px)}
.nl-edge{display:inline-block;line-height:0;vertical-align:top;background:linear-gradient(135deg,rgba(0,216,255,.55),rgba(0,216,255,.12));
  padding:1.5px;filter:drop-shadow(0 0 22px rgba(0,216,255,.22))}
.nl-body{display:block;background:linear-gradient(135deg,#0a1822,#050a10);padding:22px;text-align:center}
.nl-body img{display:block;width:240px;max-width:72vw;height:auto}
.nl-cap{display:block;margin-top:12px;color:#00d8ff;letter-spacing:.16em;font-size:12px}
.nl-get{margin:18px 0}

/* the "Show QR code" popup, shown only when its #id is the :target */
.qr-modal{display:none}
.qr-modal:target{display:flex;position:fixed;inset:0;z-index:1000;align-items:center;
  justify-content:center;background:rgba(2,6,10,.82);padding:20px}
.qr-modal .qr-back{position:absolute;inset:0}
.qr-modal .qr-dialog{position:relative}
.qr-modal .qr-title{color:#00d8ff;letter-spacing:.14em;font-size:13px;margin:0 0 14px}
.qr-modal .qr-sub{color:#7894a0;font-size:13px;margin:14px 0 0}
.qr-modal .qr-sub a{color:#00d8ff}
.qr-modal .qr-x{position:absolute;top:-14px;right:-14px;width:34px;height:34px;border-radius:50%;
  background:#0a1822;border:1px solid rgba(0,216,255,.4);color:#00d8ff;font-size:18px;line-height:32px;
  text-align:center;text-decoration:none}

/* the illustrated set-up steps */
.nl-steps{list-style:none;padding:0;margin:18px 0;display:grid;gap:14px}
.nl-step{display:flex;gap:16px;align-items:center;background:var(--card,#fff);border:1px solid var(--rule,#e2e8f0);
  border-radius:14px;padding:14px 16px}
.nl-step .nl-illus{flex:0 0 80px;line-height:0;display:flex;justify-content:center}
.nl-step .nl-illus svg{width:64px;height:120px;display:block}
.nl-step .nl-txt{font-size:14.5px;color:var(--ink-soft,#475569)}
.nl-step .nl-txt b{color:var(--ink,#0f172a)}
.nl-num{display:inline-block;min-width:22px;height:22px;line-height:22px;text-align:center;border-radius:50%;
  background:#00d8ff;color:#04121a;font-weight:700;font-size:12px;margin-right:8px}
@media(max-width:560px){.nl-step{flex-direction:column;align-items:flex-start}}

/* NIX Link page hero (QR centred) and the NIX-page side-by-side block */
.nl-hero{text-align:center;margin:16px 0 26px}
.nl-hero .nl-get{margin:18px 0 6px}
.nl-side{display:flex;flex-wrap:wrap;gap:28px;align-items:center;margin:16px 0 8px}
.nl-side-qr{flex:0 0 auto}
.nl-side-get{flex:1;min-width:250px}
.nl-side-get .meta{max-width:52ch}

/* The composite card+QR image (the card is baked into the PNG now) */
.nl-qr{display:inline-block;width:290px;max-width:82vw;height:auto;vertical-align:top}

/* a real NIX Link screenshot in a phone frame, used in the set-up steps */
.nl-phone{display:inline-block;background:#05070a;border:3px solid #243542;border-radius:18px;padding:4px;
  width:132px;line-height:0;box-shadow:0 4px 16px rgba(0,0,0,.3)}
.nl-phone img{display:block;width:100%;height:auto;border-radius:9px}

/* The set-up guide as a card grid: two rows of three, bigger images, bulleted content. */
.nl-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin:18px 0 8px}
@media(max-width:880px){.nl-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.nl-grid{grid-template-columns:1fr}}
.nl-card{background:var(--card,#fff);border:1px solid var(--rule,#e2e8f0);border-radius:18px;padding:20px 18px;
  display:flex;flex-direction:column}
.nl-card-img{display:flex;justify-content:center;align-items:flex-end;min-height:260px;margin-bottom:14px}
.nl-card-title{margin:0 0 10px;color:var(--ink,#0f172a);font-size:16px;font-weight:700;display:flex;
  align-items:center;gap:9px}
.nl-card-bullets{margin:0;padding-left:20px;color:var(--ink-soft,#475569);font-size:14.5px;line-height:1.55}
.nl-card-bullets li{margin:6px 0}
.nl-card-bullets a{color:var(--c-600,#0369a1)}
.nl-card-bullets b{color:var(--ink,#0f172a)}
