/* ===========================================================================
   The Crest Suite site: ONE stylesheet, every page.

   Before this file, all fifteen pages carried their own copy of the :root
   tokens, the header, the footer, the buttons and the modals. A colour changed
   in one place and drifted everywhere else. Now a page ships its own structure
   and nothing else.

   The language, unchanged from the app: flat opaque surfaces, hairlines instead
   of cards, one accent per zone, no glow, no gradient used as decoration, system
   type only. What IS new (2026-07-25) is rhythm: the old page was one unbroken
   sheet of #0b0c0e for nine screens, which read as dead. Sections now alternate
   grounds and each app's zone carries its own accent, so scrolling feels like
   walking through three rooms rather than down one corridor.

   Accent zones: put data-accent="cobalt" (Take) or "sage" (Minutes) on a
   <section> and every accented thing inside it follows. Default is Crest amber.
   Never mix two accents inside one component.
   =========================================================================== */

:root{
  --bg:#0b0c0e; --bg2:#0e0f11; --bg3:#121316;
  --panel:#111113; --inset:#0d0e10;
  --hair:rgba(255,255,255,.08); --hair2:rgba(255,255,255,.05); --hair3:rgba(255,255,255,.14);
  --t1:rgba(245,245,244,.92); --t2:rgba(245,245,244,.60); --t3:rgba(245,245,244,.38);
  --fill:rgba(255,255,255,.06); --fill2:rgba(255,255,255,.10);
  --amber:#ffb000; --amber-ink:#171410;
  --green:#35c06a; --red:#e5493d;
  --cob:#6fa0e8; --sage:#6fb6a3; --rec:#d96a5e;
  /* The zone accent. Sections override it; components only ever read it. */
  --accent:var(--amber); --accent-ink:#171410;
  --mono:ui-monospace,"SF Mono",Menlo,monospace;
  --maxw:1120px; --wide:1320px; --r:12px;
  /* Two column widths the whole site agrees on. --reading is a long-form
     measure (the changelog, the support page, the FAQ); --narrow is a single
     form. They were written as inline max-width numbers on four pages, so
     "the reading column" was four independent decisions that could drift. */
  --reading:800px; --narrow:620px;
  --spring:cubic-bezier(.32,1.18,.36,1);
}
[data-accent="cobalt"]{--accent:var(--cob);--accent-ink:#0b1220}
[data-accent="sage"]{--accent:var(--sage);--accent-ink:#08150f}
[data-accent="amber"]{--accent:var(--amber);--accent-ink:var(--amber-ink)}

*{box-sizing:border-box;margin:0;padding:0}
/* `hidden` must actually hide, everywhere, forever. The browser's own
   [hidden]{display:none} is a UA rule, so ANY author rule that sets display
   beats it, and this site sets display on almost everything. Live symptoms
   before this line existed (2026-07-26): the empty sale badge in the Crest Pro
   card rendered as a stray amber pill (.badge is inline-flex), "Write a review"
   showed even with no reviews (.cta-row is flex), and a stopped recording in
   the notch demo kept showing its running timer next to "Saved". Every one of
   those is markup that said hidden and CSS that overruled it. */
[hidden]{display:none!important}
html{scroll-behavior:smooth;background:var(--bg);scroll-padding-top:76px}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
body{background:var(--bg);color:var(--t2);
  font-family:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI",sans-serif;
  font-size:15px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{max-width:100%;height:auto;display:block}
.mono{font-family:var(--mono)}
.num{font-variant-numeric:tabular-nums}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
.wrap.wide{max-width:var(--wide)}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ---------------------------------------------------------------- sections
   Ground rhythm. `section` is the deep ground; .lift is one step up; .sunk is
   one step down. Alternating them is what gives the scroll a pulse. */
section{position:relative;padding:104px 0;border-top:1px solid var(--hair2)}
section:first-of-type{border-top:0}
section.lift{background:var(--bg2)}
section.sunk{background:#08090b}
section.tight{padding:72px 0}
@media(max-width:700px){section{padding:76px 0}}

/* An accent zone announces itself with a single hairline at its top edge, the
   width of the content. That is the whole costume. */
section[data-accent]::before{content:"";position:absolute;top:-1px;left:50%;transform:translateX(-50%);
  width:min(var(--maxw),calc(100% - 48px));height:1px;background:var(--accent);opacity:.5}

h1,h2,h3,h4{color:var(--t1);letter-spacing:-.022em;line-height:1.08;text-wrap:balance;font-weight:650}
h1{font-size:clamp(38px,6.2vw,72px);letter-spacing:-.032em;line-height:1.02}
h2{font-size:clamp(27px,4.2vw,42px)}
h3{font-size:19px;letter-spacing:-.01em}
p{text-wrap:pretty}
.center{text-align:center}
.muted{color:var(--t2)}
.dim{color:var(--t3)}
.lead{font-size:clamp(15.5px,1.6vw,18px);color:var(--t2);max-width:62ch}
.center .lead{margin-left:auto;margin-right:auto}

.eyebrow{font-family:var(--mono);font-size:11px;font-weight:600;
  letter-spacing:.22em;text-transform:uppercase;color:var(--t3);
  display:inline-flex;align-items:center;gap:10px}
.eyebrow::before{content:"";width:16px;height:2px;border-radius:1px;background:var(--accent)}
.center .eyebrow{justify-content:center}
.sec-head{max-width:660px;margin-bottom:48px;display:flex;flex-direction:column;gap:15px}
/* Two ways to ask for a centred head, and only one of them worked. `.center` on
   an ANCESTOR centred the box; `.center` on the head itself centred only its
   text, so a 660px box stayed pinned to the left of a 1120px wrap while the
   words inside it were centred against nothing. Seventeen heads across five
   pages were written the second way, including the pricing head. */
.center .sec-head,.sec-head.center{margin-left:auto;margin-right:auto}
.sec-head p{font-size:16px;color:var(--t2)}

/* ---------------------------------------------------------------- buttons */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:600;font-size:14.5px;
  padding:13px 22px;border-radius:10px;border:1px solid transparent;cursor:pointer;
  font-family:inherit;white-space:nowrap;
  transition:transform .14s ease,background .18s ease,border-color .18s,color .18s}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:translateY(0)}
.btn-primary{background:var(--accent);color:var(--accent-ink)}
.btn-primary:hover{filter:brightness(1.08)}
.btn-ghost{background:var(--fill);color:var(--t1);border-color:var(--hair)}
.btn-ghost:hover{background:var(--fill2);border-color:var(--hair3)}
.btn-line{background:transparent;color:var(--accent);border-color:color-mix(in srgb,var(--accent) 50%,transparent)}
.btn-line:hover{background:color-mix(in srgb,var(--accent) 8%,transparent)}
.btn-lg{padding:15px 26px;font-size:15.5px}
.btn.full{width:100%}
.btn svg{width:15px;height:15px}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.55;pointer-events:none}
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px}
.center .cta-row{justify-content:center}
.fine{font-size:12.5px;color:var(--t3);margin-top:15px;line-height:1.7}
.fine a{color:var(--t2);border-bottom:1px solid var(--hair);padding-bottom:1px}
.fine a:hover{color:var(--t1)}
.textlink{color:var(--accent);font-weight:600}
.textlink:hover{text-decoration:underline;text-underline-offset:3px}

/* ------------------------------------------------------------------- nav */
header{position:fixed;top:0;left:0;right:0;z-index:60;border-bottom:1px solid transparent;
  transition:background .25s,border-color .25s,backdrop-filter .25s}
header.scrolled{background:rgba(11,12,14,.88);border-bottom-color:var(--hair2);backdrop-filter:saturate(160%) blur(14px)}
nav{display:flex;align-items:center;justify-content:space-between;height:64px;gap:18px}
.brand{display:flex;align-items:center;gap:9px;font-weight:650;font-size:15.5px;color:var(--t1);flex:none}
.brand .mark{width:22px;height:12px;border-radius:0 0 7px 7px;background:#000;
  border:1px solid var(--hair);border-top:0;position:relative}
.brand .mark::after{content:"";position:absolute;left:50%;top:3px;transform:translateX(-50%);
  width:4px;height:4px;border-radius:50%;background:var(--amber)}
.navlinks{display:flex;align-items:center;gap:24px}
.navlinks a.link{font-size:13.5px;color:var(--t2);transition:color .2s;white-space:nowrap}
.navlinks a.link:hover,.navlinks a.link[aria-current="page"]{color:var(--t1)}
.navlinks .btn{padding:9px 16px;font-size:13px}

/* The narrow header, before and after the menu existed.
   BEFORE (the bug): .opt vanished at 860 and every .link at 600, and NOTHING
   replaced them, so a phone got a brand mark, a Get button, and no way to reach
   /take, /minutes, /products, /support or /account from any of 40 pages.
   NOW: suite.js builds a menu button and an overlay out of these same anchors.
   Every rule that hides a link is scoped to .has-navmenu, which suite.js sets
   only AFTER the menu is actually in the DOM. If that script never arrives the
   old thresholds still apply and the header keeps what it can fit, rather than
   hiding navigation behind a button that does not exist.
   The three .has-navmenu rules are repeated inside suite.js's injected sheet,
   because the 28 SEO pages load that script and their own inline CSS but never
   this file. Change them in both places or the two headers disagree. */
@media(max-width:860px){
  .navlinks{gap:16px}
  .navlinks .link.opt{display:none}
  .has-navmenu .navlinks .link{display:none}
  .has-navmenu .navmenu-btn{display:inline-flex}
}
@media(max-width:600px){
  .navlinks .link{display:none}
  .has-navmenu .navlinks .btn{display:none}
}
/* At 320-340px the app rooms' ghost buttons ("See Minutes in depth") overflowed
   the viewport by 36px, the only horizontal scroll on the site. Let the action
   column go full width and the labels wrap there. */
@media(max-width:360px){
  .roomact{align-items:stretch;width:100%}
  .roomact .btns .btn{white-space:normal}
}
/* Between 601 and 860 the Get button sits next to the menu button, and the menu
   button is added by a script, so it would step left the moment that script
   ran. Hold its width open from here and hand it back in the same frame the
   real button lands. Below 601 the Get button is gone and there is nothing to
   the left of the trigger to move, so nothing is reserved. */
@media(min-width:601px) and (max-width:860px){
  .navlinks{padding-right:60px}
  .has-navmenu .navlinks{padding-right:0}
}

/* ------------------------------------------------------------------ hero */
.hero{padding-top:150px;padding-bottom:74px;border-top:0}
.hero.center h1{max-width:16ch;margin:20px auto 0}
.hero h1 em{font-style:normal;color:var(--accent)}
.hero .lead{margin-top:22px}
.hero.center .lead{margin-top:22px}
@media(max-width:700px){.hero{padding-top:118px}}

/* --------------------------------------------------- the real-UI showcase
   Screenshots are the argument, so they get room. A shot sits in a frame with
   a hairline and a caption that says, plainly, that it is real. */
.shot{border:1px solid var(--hair);border-radius:14px;overflow:hidden;background:var(--inset);
  box-shadow:0 18px 40px -28px rgba(0,0,0,.75)}
.shot img{width:100%;display:block}
.shot-cap{font-size:12px;color:var(--t3);margin-top:12px;text-align:center}
/* A film sits in the same seated frame as a shot. The poster is dark, so the
   ground behind letterboxing is plain black, and the video never floats. */
.film{border:1px solid var(--hair);border-radius:14px;overflow:hidden;background:#000;
  box-shadow:0 18px 40px -28px rgba(0,0,0,.75);margin-top:34px}
.film video{display:block;width:100%;height:auto}
.showcase{margin-top:52px}
.showcase.bleed{max-width:var(--wide)}

/* Side by side: words and a picture, with the picture taking the wider column.
   `.flip` puts the picture first on desktop and NEVER on mobile, where the
   words always lead. */
.band{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(28px,5vw,64px);align-items:center}
.band.flip{grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr)}
.band.flip .band-copy{order:2}
.band.flip .band-art{order:1}
.band + .band{margin-top:clamp(64px,9vw,112px)}
@media(max-width:900px){
  .band,.band.flip{grid-template-columns:1fr;gap:32px}
  .band.flip .band-copy{order:1}.band.flip .band-art{order:2}
}
.band-copy h2{margin-top:14px}
.band-copy .lead{margin-top:16px}

/* Feature bullets. These used to be hollow squares, which read as UNCHECKED
   checkboxes sitting next to every claim. A tick, in the zone's accent. */
.checks{list-style:none;display:flex;flex-direction:column;gap:14px;margin-top:26px}
/* The marker is absolute, not a flex sibling: as a flex child it made the bold
   lead-in and the sentence after it two separate columns, so every bullet read
   as a broken two-line fragment. */
.checks li{position:relative;padding-left:29px;font-size:14.5px;color:var(--t2);line-height:1.55}
.checks li::before{content:"";position:absolute;left:0;top:2px;width:17px;height:17px;border-radius:50%;
  background:color-mix(in srgb,var(--accent) 16%,transparent);
  border:1px solid color-mix(in srgb,var(--accent) 45%,transparent);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.6 6.2l2.2 2.2 4.6-4.8' fill='none' stroke='%23fff' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:center;background-size:11px}
.checks li b{color:var(--t1);font-weight:600}

/* ---------------------------------------------------------------- cards */
.grid{display:grid;gap:1px;background:var(--hair2);border:1px solid var(--hair2);border-radius:14px;overflow:hidden}
.grid.c2{grid-template-columns:repeat(2,1fr)}
.grid.c3{grid-template-columns:repeat(3,1fr)}
.grid.c4{grid-template-columns:repeat(4,1fr)}
.grid > *{background:var(--bg);padding:26px 24px}
section.lift .grid > *{background:var(--bg2)}
/* c3 used to drop straight from three columns to ONE at 940, so a tablet and a
   wide phone read a three-up grid as a single tall stack while c4 next to it
   was still showing two. Same rhythm for both now: halve first, stack last. */
@media(max-width:940px){.grid.c3,.grid.c4{grid-template-columns:repeat(2,1fr)}
  /* Three tiles on two columns strands the third; let it take the full row so
     the grid still packs. c4 grids hold multiples of two and never need this. */
  .grid.c3 > :last-child{grid-column:1/-1}}
@media(max-width:640px){.grid.c2,.grid.c3,.grid.c4{grid-template-columns:1fr}}
.card h3{font-size:16px;margin-bottom:9px}
.card p{font-size:13.8px;color:var(--t2);line-height:1.62}
.card .ico{width:20px;height:20px;stroke:var(--accent);fill:none;stroke-width:1.7;margin-bottom:14px}

/* -------------------------------------------------------------- the table
   Comparison. Feature rows only. Competitor names in plain text, no logos,
   and never a price we have not verified this week. */
.tblwrap{overflow-x:auto;border:1px solid var(--hair2);border-radius:14px;-webkit-overflow-scrolling:touch}
table.cmp{width:100%;border-collapse:collapse;font-size:14px;min-width:600px}
table.cmp th,table.cmp td{padding:15px 16px;text-align:left;border-bottom:1px solid var(--hair2);vertical-align:top}
table.cmp thead th{font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;
  color:var(--t3);background:var(--inset);white-space:nowrap;position:sticky;top:0}
table.cmp thead th.us{color:var(--accent)}
table.cmp tbody tr:last-child td{border-bottom:0}
table.cmp td:first-child{color:var(--t1);font-weight:550;width:34%}
table.cmp td.us{color:var(--t1);background:color-mix(in srgb,var(--accent) 5%,transparent)}
table.cmp .yes{color:var(--green);font-weight:600}
table.cmp .no{color:var(--t3)}
table.cmp .part{color:var(--amber)}
.cmp-note{font-size:12px;color:var(--t3);margin-top:14px;line-height:1.65}

/* ------------------------------------------------------------- pricing */
.plans{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;align-items:stretch}
@media(max-width:980px){.plans{grid-template-columns:repeat(2,1fr)}}
@media(max-width:580px){.plans{grid-template-columns:1fr}}
/* Not every page sells four things. /crest has three plans and /take and
   /minutes have two, and each of them said so with an INLINE style. An inline
   grid-template-columns beats every media query in this file, so those three
   grids never collapsed at all: /crest kept three columns down to a 390px
   phone, at 100px per card. Same numbers, as classes, so the breakpoints can
   reach them. Desktop rendering is unchanged. */
.plans.plans-3{grid-template-columns:repeat(3,1fr);max-width:880px;margin-inline:auto}
.plans.plans-2{grid-template-columns:repeat(2,1fr);max-width:680px;margin-inline:auto}
@media(max-width:860px){.plans.plans-3{grid-template-columns:1fr 1fr}
  /* Three cards on two columns: the bundle card (always last) takes the full
     row, which packs the grid and features the thing worth featuring. */
  .plans.plans-3 > .plan:last-child{grid-column:1/-1}}
@media(max-width:580px){.plans.plans-3,.plans.plans-2{grid-template-columns:1fr}}
.plan{border:1px solid var(--hair2);border-radius:14px;padding:26px 22px 24px;background:var(--panel);
  display:flex;flex-direction:column;gap:12px;position:relative}
.plan.hero-plan{border-color:color-mix(in srgb,var(--amber) 45%,transparent);background:#131211}
.plan .tag{position:absolute;top:-1px;right:16px;transform:translateY(-50%);
  font-family:var(--mono);font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  background:var(--amber);color:var(--amber-ink);padding:4px 9px;border-radius:5px}
.plan h3{font-size:16.5px}
.plan .amt{font-size:38px;font-weight:660;color:var(--t1);letter-spacing:-.03em;line-height:1;
  font-variant-numeric:tabular-nums;display:flex;align-items:baseline;gap:7px}
.plan .amt small{font-size:12.5px;font-weight:500;color:var(--t3);letter-spacing:0}
.plan .desc{font-size:13.4px;color:var(--t2);flex:1;line-height:1.6}
.plan .why{font-size:12px;color:var(--t3);line-height:1.6}
.plan .btn{margin-top:2px}
.plan .owned{font-size:12px;color:var(--green);font-weight:600}
/* The free way in, under every buy button. */
.tryline{font-size:12px;color:var(--t3);text-align:center;margin-top:2px}
.tryline a{color:var(--t2);border-bottom:1px solid var(--hair)}
.tryline a:hover{color:var(--t1)}

/* ---------------------------------------------------------------- FAQ */
.faq{max-width:800px;margin:0 auto}
.faq details{border-bottom:1px solid var(--hair2)}
.faq summary{cursor:pointer;list-style:none;padding:22px 40px 22px 0;font-size:16px;color:var(--t1);
  font-weight:550;position:relative}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:6px;top:29px;width:9px;height:9px;
  border-right:1.6px solid var(--t3);border-bottom:1.6px solid var(--t3);transform:rotate(45deg);
  transition:transform .2s var(--spring)}
.faq details[open] summary::after{transform:rotate(-135deg)}
.faq details p{padding:0 0 22px;font-size:14.5px;color:var(--t2);max-width:70ch}

/* -------------------------------------------------------------- modals */
.modal{position:fixed;inset:0;z-index:220;display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.76);padding:20px}
.modal[hidden]{display:none}
.modal-card{width:min(92vw,430px);background:#141518;border:1px solid var(--hair);border-radius:16px;
  padding:28px 26px;position:relative;box-shadow:0 40px 90px -30px rgba(0,0,0,.85)}
.modal-card h3{font-size:19px;margin-bottom:8px}
.modal-card p{font-size:13.5px;color:var(--t2);margin-bottom:16px;line-height:1.6}
.modal-x{position:absolute;top:6px;right:8px;background:none;border:none;color:var(--t3);
  font-size:23px;cursor:pointer;line-height:1;width:44px;height:44px;
  display:flex;align-items:center;justify-content:center}
.modal-x:hover{color:var(--t1)}
.field{margin-bottom:13px}
.field label{display:block;font-size:12px;color:var(--t3);margin-bottom:6px;font-weight:550}
input[type=email],input[type=password],input[type=text],textarea{width:100%;background:var(--inset);
  border:1px solid var(--hair2);border-radius:9px;padding:12px 14px;color:var(--t1);
  font:inherit;font-size:14.5px;outline:none;transition:border-color .16s}
input:focus,textarea:focus{border-color:var(--accent)}
textarea{resize:vertical;min-height:96px}
/* A locked checkout field. Signed in, the address IS the account, so it reads as
   a stated fact rather than an empty box waiting to be filled in wrongly. */
input.locked{color:var(--t2);background:rgba(255,255,255,.03);cursor:default}
input.locked:focus{border-color:var(--hair2)}
/* The way out of the lock: quiet, because buying for somebody else is the rare
   case, but a real button rather than fine print, because it has to be findable. */
.colink{display:block;margin:9px 0 0;padding:0;background:none;border:0;
  font:inherit;font-size:12.5px;color:var(--accent);cursor:pointer;text-align:left}
.colink:hover{text-decoration:underline;text-underline-offset:3px}
.err{display:block;color:var(--red);font-size:12.5px;min-height:16px;margin:8px 0 2px;line-height:1.45}
.ok-note{color:var(--green)}
.hintline{font-size:11.5px;color:var(--t3);margin-top:12px;text-align:center;line-height:1.6}

/* -------------------------------------------------------------- footer */
footer{border-top:1px solid var(--hair2);padding:54px 0 46px;background:#08090b}
.foot{display:flex;flex-wrap:wrap;gap:30px;justify-content:space-between;align-items:flex-start}
.foot-cols{display:flex;flex-wrap:wrap;gap:52px}
.foot-col{display:flex;flex-direction:column;gap:11px;min-width:110px}
.foot-col b{font-size:11px;font-family:var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--t3);font-weight:600}
.foot-col a{font-size:13.5px;color:var(--t2)}
.foot-col a:hover{color:var(--t1)}
.foot-tail{margin-top:42px;padding-top:24px;border-top:1px solid var(--hair2);
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;font-size:12.5px;color:var(--t3)}

/* ------------------------------------------------------------- reveals
   Fails OPEN: if IntersectionObserver never runs, everything is visible. */
.rv{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .6s var(--spring)}
.rv.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.rv{opacity:1;transform:none;transition:none}}

/* -------------------------------------------------------------- toast */
.toast{position:fixed;left:50%;bottom:28px;transform:translateX(-50%) translateY(14px);
  background:#17181c;border:1px solid var(--hair);border-radius:10px;padding:11px 18px;
  font-size:13.5px;color:var(--t1);opacity:0;pointer-events:none;transition:opacity .22s,transform .22s;z-index:300}
.toast.show{opacity:1;transform:translateX(-50%) translateY(0)}

/* ---------------------------------------------------------------- misc */
.badge{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10.5px;
  font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--accent);
  border:1px solid color-mix(in srgb,var(--accent) 34%,transparent);border-radius:999px;padding:4px 11px}
.rule{height:1px;background:var(--hair2);border:0;margin:0}
.stack{display:flex;flex-direction:column;gap:16px}
.row{display:flex;gap:12px;flex-wrap:wrap;align-items:center}

/* The nav wears each app's accent as a 6px square, so the three products are
   distinguishable before anyone reads a word. Shared here rather than copied
   into each page's own <style>, which is where it started. */
.navlinks .nav-app{display:inline-flex;align-items:center;gap:7px}
.navlinks .nav-app .sq{width:6px;height:6px;border-radius:2px;flex:none}
