:root{--blue:#0071E3;--blue-h:#0077ED;--link:#06c;--ink:#1D1D1F;--grey:#6E6E73;--grey-l:#86868B;--line:#D2D2D7;--hair:#E8E8ED;--panel:#F5F5F7;--green:#248A3D;
--sans:-apple-system,BlinkMacSystemFont,"SF Pro Text","SF Pro Display","Helvetica Neue",system-ui,sans-serif}

/* ===== SuperFile pricing =====
 * Page-specific only. The nav, the localbar, the footer and .btn all come from /assets/base.css,
 * realnav.css and localnav.css, which load AFTER this file — see AGENTS.md. Nothing here may
 * redeclare .gnav / .localbar / .lb* or check-nav.mjs fails the build.
 *
 * Structure follows the reference the four plans have to survive: a period switch above the cards,
 * one column per plan, and a full comparison table underneath for the person who does not believe
 * the cards. Light, in the site's own tokens — the featured column carries the emphasis in ink
 * rather than the whole page going dark.
 */
.ld{opacity:0;transform:translateY(12px);animation:prin .6s cubic-bezier(.2,.7,.2,1) forwards;animation-delay:var(--d,0s)}
@keyframes prin{to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.ld{animation:none;opacity:1;transform:none}}

main.prmain{max-width:1140px;padding:0 22px 40px}
/* Visually hidden, still read out. Used for the comparison table's <caption>: on screen the <h2>
   above it already names the table, but a screen reader that lands inside the table gets no
   heading — clip-path rather than display:none, which removes it from the accessibility tree too. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.prh2{font-size:clamp(25px,3vw,34px);font-weight:600;letter-spacing:-.028em;text-align:center;margin:0}
.prsub{font-size:16px;color:var(--grey);text-align:center;max-width:56ch;margin:10px auto 0;line-height:1.45}
/* No .btn.dark here: every other call to action on this page is blue, and the one at the foot being
   ink made it look like a different kind of button rather than the same one again. */

/* hero
 * Four stacked centred lines used to run before the first price: the localbar's "Pricing", a warm
 * pill, an eyebrow that also said "Pricing", then the headline — and the pill and the lede both said
 * "join the waitlist". One announcement, one headline, one sentence now, which puts the cards about
 * 90px further up the page. On a 390x844 phone that is the difference between a sliver of the first
 * card and its price.
 *
 * The wash used to live here, on the hero, and stopped at the container's edge — 1140px of tint with
 * white either side of it, which is a panel rather than a page. It has moved to the body (see the
 * wash block below), so it runs the full width of the window and continues down behind the cards.
 * Nothing decorative is left on this section: two washes stacked over the same 300px put a brighter
 * blob behind the headline, and the headline is the LCP element — the least useful place on the page
 * to draw the eye with a gradient rather than with the words. */
.prhero{position:relative;text-align:center;padding:clamp(24px,4.2vh,46px) 0 clamp(8px,1.5vh,14px)}

/* wash
 * Ported from WeTransfer's pricing page, where the cards sit on a cool wash that clears to white by
 * the time the page gets to prose. Measured off theirs rather than remembered: a pale periwinkle
 * around rgb(241,243,255), deepest at the left, gone at the right.
 *
 * On the BODY, not on a section: full-bleed is the whole point of it and a 100vw child would add a
 * scrollbar's width of horizontal overflow (nothing on this page sets overflow-x:hidden — the old
 * container-width wash exists because of exactly that). The body has the window's width already.
 *
 * Two radials rather than one linear: a radial is zero in every direction at its own edge, so the
 * wash cannot end in a seam, which is the failure the previous version was fixed for. background-size
 * bounds how far down it reaches — about as far as the foot of the cards — so the comparison table
 * and everything under it are on plain white. #fff last, because body's own background is being
 * replaced and not just added to.
 *
 * In our tokens, not theirs: system indigo top-left for the periwinkle lean and our own blue
 * top-right, both at single-digit alpha. Theirs is a violet our page uses nowhere else. */
body:has(main.prmain){
  background:
    radial-gradient(78% 70% at 10% 1%,rgba(88,86,214,.17) 0%,rgba(88,86,214,.055) 46%,rgba(88,86,214,0) 78%) no-repeat,
    radial-gradient(72% 58% at 90% -3%,rgba(0,113,227,.13) 0%,rgba(0,113,227,.03) 48%,rgba(0,113,227,0) 78%) no-repeat,
    #fff;
  background-size:100% 1280px,100% 1020px;
}
/* Was the palette of the "Draft — not published" admin strip above it (#FFF6E0/#F2E0B4/#8A5A00) —
   an announcement dressed as a caution. A live dot says the waitlist is open, which it is.
   The chip is the one thing in the header that moves: it fades up on load with the plan cards
   (which carry .ld with staggered --d delays), and its dot breathes. Deliberately NOT on the
   headline — that is the LCP element, and an entrance animation on it delays the largest paint on
   the page to buy nothing. */
.prbanner{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;font-weight:500;letter-spacing:-.005em;color:#2B2B2F;background:#fff;border:1px solid var(--hair);border-radius:999px;padding:6px 14px 6px 11px;margin:0 0 clamp(13px,1.8vh,18px);box-shadow:0 1px 2px rgba(0,0,0,.045);animation:prchip .45s cubic-bezier(.2,.7,.2,1) both}
.prbanner::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:var(--green);box-shadow:0 0 0 3px rgba(36,138,61,.15);animation:prpulse 2.6s ease-in-out infinite}
.prbanner:empty{display:none}
@keyframes prchip{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes prpulse{0%,100%{box-shadow:0 0 0 3px rgba(36,138,61,.15)}50%{box-shadow:0 0 0 5px rgba(36,138,61,.07)}}
@media (prefers-reduced-motion:reduce){
  .prbanner{animation:none}
  .prbanner::before{animation:none}
}
.preyebrow{font-size:14.5px;font-weight:600;letter-spacing:-.01em;color:var(--blue);margin:0 0 8px}
/* In the hero the eyebrow is an optional kicker, not a second copy of the tab title: blank by
   default and gone, but type anything into it in Page Admin and it comes back — as a quiet kicker
   rather than blue text that reads like a link. (.preyebrow keeps its blue elsewhere: the join
   dialog uses it for the plan name.) */
.prhero .preyebrow{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--grey-l);margin:0 0 9px}
.prhero .preyebrow:empty{display:none}
/* 56px on a 1140px container read like a subhead of the page it is the headline of. 64px fills the
   measure; the tracking tightens as the size grows because -.035em that looks right at 36px is loose
   at 64px. Phone keeps its 36px floor — the clamp only ever gets bigger than it was. */
.prh1{font-size:clamp(36px,5.2vw,64px);font-weight:600;letter-spacing:-.04em;line-height:1.03;margin:0;text-wrap:balance}
@media (max-width:640px){.prh1{letter-spacing:-.032em;line-height:1.06}}
.prlede{font-size:clamp(16.5px,1.6vw,19px);color:var(--grey);line-height:1.45;letter-spacing:-.01em;max-width:52ch;margin:clamp(12px,1.6vh,17px) auto 0;text-wrap:pretty}

/* available today
 *
 * Deliberately NOT a fifth card. Everything below this is a waitlist; these three are the only
 * things on the page anybody can pay for right now, and if they were rendered as cards they would
 * compete with the plans for the same glance and win — a $100 extension next to a $200/user/month
 * plan reads as the cheap option rather than a different purchase. So: one tinted panel, one row
 * each, price on the right, a real link on the end. Reads as a shelf, not a menu.
 *
 * An empty items array collapses the whole section (:has on an empty list), so removing the last
 * row in Pricing Admin removes the band rather than leaving a titled void.
 */
/* Translucent white rather than the warm grey --panel: the panel sits on the cool wash now, and a
   warm grey over a cool blue is the one combination that reads as dirt rather than as two layers.
   Letting a little of the wash through is also what keeps it a shelf on the page instead of a card
   floating above it. */
.prnow{margin:clamp(20px,3.4vh,30px) 0 0;background:rgba(255,255,255,.62);border:1px solid rgba(255,255,255,.9);box-shadow:0 1px 2px rgba(20,24,60,.03);border-radius:22px;padding:clamp(20px,3vh,28px) clamp(18px,2.4vw,26px)}
.prnow:has(.prnow-list:empty){display:none}
.prnow-hd{text-align:center;max-width:62ch;margin:0 auto}
.prnow-h{font-size:clamp(19px,2vw,23px);font-weight:600;letter-spacing:-.022em;margin:0;color:var(--ink)}
/* The green dot is the whole claim: these are live. Kept as a pseudo-element so the heading text
   stays a plain editable string in the draft. */
.prnow-h::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--green);margin-right:9px;vertical-align:.08em;box-shadow:0 0 0 3px rgba(36,138,61,.16)}
.prnow-sub{font-size:13.5px;color:var(--grey);line-height:1.5;margin:8px 0 0;text-wrap:pretty}
.prnow-sub:empty{display:none}
.prnow-list{display:flex;flex-direction:column;gap:8px;margin:clamp(15px,2.2vh,20px) 0 0}
/* Three columns: what it is (flexible), what it costs (fixed, right-aligned so the prices line up
   into a column you can compare down), and the link (fixed). */
.prnowrow{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:center;gap:clamp(12px,2vw,22px);background:#fff;border:1px solid var(--hair);border-radius:16px;padding:14px 16px}
.prnowt{display:flex;flex-direction:column;gap:2px;min-width:0}
.prnowt b{font-size:14.5px;font-weight:600;letter-spacing:-.014em;color:var(--ink)}
.prnowt>span{font-size:12.5px;color:var(--grey);line-height:1.4}
.prnowp{display:flex;flex-direction:column;align-items:flex-end;gap:1px;text-align:right}
.prnowp b{font-size:17px;font-weight:600;letter-spacing:-.02em;color:var(--ink);font-variant-numeric:tabular-nums}
.prnowp>span{font-size:11.5px;color:var(--grey-l);white-space:nowrap}
/* Outline, not solid blue. The plans' CTAs are solid; making these solid too would put five primary
   buttons on one screen and none of them would read as the primary. */
.prnowb{display:inline-flex;align-items:center;justify-content:center;font-size:13.5px;font-weight:500;letter-spacing:-.01em;color:var(--link);text-decoration:none;background:#fff;border:1px solid var(--line);border-radius:999px;padding:9px 16px;white-space:nowrap;transition:background .18s ease,border-color .18s ease,color .18s ease}
.prnowb:hover{background:var(--link);border-color:var(--link);color:#fff}
/* Under ~700px the three columns cannot each hold their content: the price collapses onto the
   title's line (still right-aligned against it) and the link takes the full width beneath. */
@media (max-width:700px){
  .prnowrow{grid-template-columns:minmax(0,1fr) auto;gap:6px 14px}
  .prnowb{grid-column:1/-1;margin-top:8px}
  .prnowt>span{margin-top:2px}
}

/* period switch — monthly / annually, with Business as its own button on the right.
 * Three columns so the pill stays centred on the page no matter how wide the Business button is:
 * an empty first column balances it. An empty .prbizwrap (no business block in the draft) collapses,
 * and the pill is still centred because the two 1fr columns are still there. */
.prswitchwrap{text-align:center;padding:clamp(14px,2.4vh,24px) 0 0}
.prswitchrow{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:12px}
.prswitchrow .prswitch{grid-column:2;justify-self:center}
.prbizwrap{grid-column:3;justify-self:end;min-width:0}
.prbizwrap:empty{display:none}
.prbizbtn{display:inline-flex;align-items:center;gap:8px;font-family:var(--sans);font-size:14px;font-weight:500;letter-spacing:-.01em;color:var(--ink);background:#fff;border:1px solid var(--line);border-radius:999px;padding:10px 18px;cursor:pointer;white-space:nowrap;transition:background .18s ease,border-color .18s ease,box-shadow .18s ease}
.prbizbtn:hover{background:#FBFBFD;border-color:#BFBFC6;box-shadow:0 1px 3px rgba(0,0,0,.06)}
.prbizbtn svg{color:var(--grey-l);flex:none}
.prbizbtn:hover svg{color:var(--ink)}
.prswitch{display:inline-flex;gap:4px;background:var(--panel);border-radius:999px;padding:4px;max-width:100%}
.prswitch button{display:flex;align-items:baseline;gap:7px;font-family:var(--sans);font-size:14px;font-weight:500;color:var(--grey);background:none;border:0;border-radius:999px;padding:9px 18px;cursor:pointer;white-space:nowrap;transition:background .18s ease,color .18s ease,box-shadow .18s ease}
.prswitch button:hover{color:var(--ink)}
.prswitch button.on{background:#fff;color:var(--ink);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.1),0 0 0 .5px rgba(0,0,0,.04)}
/* The discount is the only reason anyone touches this switch, and it was 11px of green text tucked
   behind the word "Annually". A tinted pill gives it the weight of the offer it is. */
.prswitch button i{font-style:normal;font-size:10.5px;font-weight:600;letter-spacing:-.005em;color:#1B6B2F;background:rgba(36,138,61,.11);border-radius:6px;padding:2px 6px;line-height:1.35}
.prswitch button.on i{background:rgba(36,138,61,.14)}
.prswitchnote{font-size:13px;color:var(--grey-l);margin:12px 0 0;min-height:1em}

/* plan cards */
/* Flex, not a fixed 4-up grid: a labelled group frame holds a variable number of cards and has to
   take that many shares of the row, so that a card inside a frame comes out the same width as a bare
   card beside it. --n is the card count, written by the server. */
.prcards{display:flex;align-items:stretch;gap:12px;margin:clamp(18px,3vh,28px) 0 0}
.prcards>.prcard{flex:1 1 0;min-width:0}

/* A labelled frame around a run of plans — the one thing a flat row of cards cannot do is say who a
   group of them is for, which leaves the reader to work out from four prices which two are aimed at
   them. `soft` is the "best for business" case: tinted, so it groups without competing with the
   plan you are selling. `solid` is for a single card you want read first. */
/* The basis is the frame's own chrome (8px padding a side plus an 8px gap between each pair of cards)
 * and the growth is the card count. Free space then divides evenly across every card on the row, so a
 * card inside a frame comes out exactly as wide as a bare one — with flex-basis:0 the frame's padding
 * came out of its own children and the two framed cards were visibly narrower than their neighbours. */
.prbox{flex:var(--n,1) 1 calc(var(--n,1) * 8px + 8px);min-width:0;display:flex;flex-direction:column;gap:8px;padding:8px;border-radius:26px}
.prbox-l{margin:0;padding:4px 6px 0;text-align:center;font-size:11.5px;font-weight:650;letter-spacing:.03em}
.prbox-in{display:flex;align-items:stretch;gap:8px;flex:1;min-width:0}
.prbox-in>.prcard{flex:1 1 0;min-width:0;border-radius:18px}
.prbox.soft{background:#EDF2FE}
.prbox.soft .prbox-l{color:var(--blue)}
.prbox.solid{background:var(--blue)}
.prbox.solid .prbox-l{color:#fff}
/* Inside a solid frame the frame is the highlight, so the card does not need its own border doing the
   same job — but its button should still be the filled one, because that is the card being pointed at. */
.prbox.solid .prcard{border-color:transparent;box-shadow:none}
.prbox.solid .prcard .prcta{background:var(--blue);color:#fff;box-shadow:none}
.prbox.solid .prcard .prcta:hover{background:var(--blue-h)}
.prcard{position:relative;display:flex;flex-direction:column;background:#fff;border:1px solid var(--hair);border-radius:22px;padding:26px 22px 24px}
/* A highlight, not an inversion. .feat used to paint the card solid ink, which works for exactly one
 * card; two of them side by side read as a black slab with the other plans hiding beside it. A
 * doubled border marks the plans you can just buy and leaves all four legible. box-shadow rather
 * than border-width so the highlight does not resize the card and knock the row out of alignment. */
.prcard.feat{border-color:var(--blue);box-shadow:0 0 0 1px var(--blue)}
.prbadge{position:absolute;top:-10px;left:22px;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;background:var(--blue);color:#fff;border-radius:999px;padding:4px 10px}
.prname{font-size:19px;font-weight:600;letter-spacing:-.02em;margin:0}
.prtag{font-size:13px;color:var(--grey);line-height:1.4;margin:6px 0 0;min-height:3.4em}
.prprice{margin:18px 0 0;display:flex;align-items:baseline;gap:8px;flex-wrap:wrap}
/* "From" rides on its own line above the number rather than inline beside it: inline it competed
   with the strike-through annual anchor for the same slot, and on the one card that has both the
   price wrapped to three lines. */
.prfrom{flex:0 0 100%;font-size:12px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--grey-l);margin-bottom:2px}
.prwas{font-size:17px;color:var(--grey-l);text-decoration:line-through;text-decoration-thickness:1px}
.prnum{font-size:38px;font-weight:600;letter-spacing:-.035em;line-height:1}
.prunit{font-size:13px;color:var(--grey)}
/* On the cards the unit always takes its own line. Left inline it fitted beside $20, $100 and $200
   and wrapped under $1,000 — so one card in four had its price two lines tall and the four "billed
   annually" notes no longer sat on a line together. */
.prcard .prunit{flex:0 0 100%;margin-top:2px}
.prbilled{font-size:12px;color:var(--grey-l);margin:7px 0 0;min-height:1.3em}
/* A free plan has no billing line and no per-user unit, so the two reserved slots under its figure are
 * a hole rather than alignment. Reclaim the billed one — nothing is ever written into it. */
.prcard[data-free] .prbilled{display:none}
/* Why this number is what it is — the seat minimum, the accreditation it carries, the reason it is
   fifty times the card beside it. Not min-height'd: only the cards that need it have it, and a
   reserved empty line on the other three would push their features out of alignment. */
.prpnote{font-size:12px;color:var(--grey);line-height:1.4;margin:8px 0 0;padding:8px 10px;background:var(--panel);border-radius:9px}
/* The CTA sits at the bottom of every card (margin-top:auto), not under the price. The cards are
   stretched to equal height, and the plans do not have equal amounts to say — Institutional has four
   features and no roadmap list, Enterprise has six and one — so a CTA under the price left the fourth
   card ending in a visible void. At the bottom, all four buttons land on one line and the slack
   collects above them where it reads as breathing room. */
.prcta{display:block;width:100%;text-align:center;font-family:var(--sans);font-size:15px;font-weight:500;background:var(--blue);color:#fff;border:0;border-radius:12px;padding:12px 14px;margin:22px 0 0;cursor:pointer;transition:background .15s,box-shadow .15s}
.prcta:hover{background:var(--blue-h)}
.prcard .prcta{margin-top:auto}
/* The footnote under the button. margin-top:auto stays on the CTA above rather than moving here, so
   the slack in a short card collects above the pair and the note keeps reading as part of the button
   rather than as the last feature. Small and centred: it is a condition on what you are about to
   press, not something you get. */
.prctanote{font-size:11.5px;line-height:1.4;color:var(--grey-l);text-align:center;margin:9px 2px 0}
/* Four identical blue buttons made the highlight border decorative. Solid for the two plans you can
   buy on your own; outlined for the two that go through a conversation. Same size, same position —
   the difference is weight, not hierarchy of importance. */
.prcard:not(.feat) .prcta{background:#fff;color:var(--blue);box-shadow:inset 0 0 0 1px var(--line)}
.prcard:not(.feat) .prcta:hover{background:#fff;box-shadow:inset 0 0 0 1px var(--blue)}
.prfeat{list-style:none;margin:20px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
/* `display:flex` above beats the browser's own [hidden]{display:none}, so the seat dialog's two tick
 * lists — one per mode — were BOTH on show, and an Enterprise Core seat listed what Institutional
 * adds. Any class that sets display has to restate this; hidden is not self-enforcing. */
.prfeat[hidden]{display:none}
.prfeat li{position:relative;font-size:13.5px;line-height:1.4;padding-left:22px;color:#333336}
.prfeat li::before{content:"";position:absolute;left:0;top:4px;width:14px;height:14px;border-radius:50%;background:#E7F4EC url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'><path d='M3.4 7.3l2.2 2.2 5-5' fill='none' stroke='%23248A3D' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/12px no-repeat}
.prsoon{margin:18px 0 0;padding:14px 0 0;border-top:1px solid var(--hair)}
.prsoon h4{font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--grey-l);margin:0 0 8px}
.prsoon ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:6px}
.prsoon li{position:relative;font-size:12.5px;color:var(--grey);padding-left:14px;line-height:1.35}
.prsoon li::before{content:"";position:absolute;left:2px;top:7px;width:4px;height:4px;border-radius:50%;background:var(--grey-l)}
.prnote{font-size:12.5px;color:var(--grey-l);text-align:center;max-width:74ch;margin:22px auto 0;line-height:1.5}
.prnote:empty{display:none}

/* compliance strip — the attestations that decide whether a regulated buyer can even start the
 * conversation, so they sit under the prices rather than three pages away on /security. A logo is
 * an admin upload; with none, the name itself is the badge, which is why an empty strip is invisible
 * (:empty) instead of a row of grey rectangles waiting for artwork. */
.prcomply{padding:clamp(30px,4vh,46px) 0 0}
.prcomply:empty{display:none}
.prcomply-h{font-size:12px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--grey-l);text-align:center;margin:0}
.prcomply-h:empty{display:none}
.prcomply-sub{font-size:13px;color:var(--grey);text-align:center;margin:8px 0 0;line-height:1.5}
.prcomply-sub:empty{display:none}
/* A grid, not a centred wrap. Six pills of six different widths, centre-justified, produced a
   staircase: 4+2 on the desktop row and a different indent on every line of the phone. Equal columns
   make it a block of attestations, which is what it is. */
/* Two groups, each with its own label, because "held" and "intended" cannot look the same on a page
   that quotes prices. The group collapses when its list is empty, so a draft where everything is
   still in progress shows one labelled list rather than an orphaned heading. */
.prcertgrp{margin:18px 0 0}
.prcertgrp:has(.prcerts:empty){display:none}
.prcertlab{display:flex;align-items:center;justify-content:center;gap:8px;font-size:11.5px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--grey-l);text-align:center;margin:0}
/* The tick / clock is redundant with the wording, on purpose: the two lists must not be told apart
   by colour alone, and the label already says which is which in words.
   --i is set on the LABEL, not on ::before: a custom property declared inside the ::before rule
   applies to the pseudo-element itself and therefore beats the value inherited from the h3, which
   silently left the in-progress group wearing the tick. On the element, the pseudo inherits whichever
   value the more specific .soon rule below leaves standing. */
.prcertlab{--i:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><path d='M3.6 8.4l2.7 2.7 6-6' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/></svg>")}
.prcertlab::before{content:"";display:inline-block;width:14px;height:14px;flex:none;background:currentColor;-webkit-mask:var(--i) center/14px no-repeat;mask:var(--i) center/14px no-repeat}
#prCertsLive .prcertlab{color:#1B6B2F}
.prcertgrp.soon .prcertlab{color:var(--grey-l);--i:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'><circle cx='8' cy='8' r='6.1' fill='none' stroke='black' stroke-width='1.6'/><path d='M8 4.6V8l2.4 1.7' fill='none' stroke='black' stroke-width='1.6' stroke-linecap='round'/></svg>")}
/* Flex rather than grid, purely so a short list centres: the in-progress group is usually one or two
   items, and a lone card pinned to the left third of a 3-up grid reads as a layout fault. The basis
   is an exact third, so a full list lays out identically to the grid it replaces. --pc is the number
   of columns, so the two media queries below only have to change one number. */
.prcerts{display:flex;flex-wrap:wrap;justify-content:center;gap:10px;max-width:860px;margin:10px auto 0;padding:0;list-style:none;--pc:3}
.prcert{flex:0 1 calc((100% - (var(--pc) - 1) * 10px) / var(--pc))}
.prcerts:empty{display:none}
/* In-progress badges are dashed and unsaturated — an outline you can see is provisional from across
   the room, so nobody screenshots the strip and reads six certifications into it. */
.prcertgrp.soon .prcert{background:transparent;border-style:dashed;border-color:var(--line)}
.prcertgrp.soon .prcert-t b{color:var(--grey)}
.prcert{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--hair);border-radius:14px;padding:11px 15px;min-height:56px}
.prcert img{display:block;height:26px;width:auto;max-width:96px;object-fit:contain;flex:none}
.prcert-t{display:flex;flex-direction:column;gap:1px;min-width:0}
.prcert-t b{font-size:13px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.prcert-t span{font-size:11.5px;color:var(--grey-l);line-height:1.3}
.prcert-t span:empty{display:none}
/* The whole pill is the link when there is one to follow, so it is the same target as the ones there
   is not — a name that happens to be verifiable should not become a smaller thing to press. */
.prcert a{display:flex;align-items:center;gap:10px;width:100%;color:var(--link);text-decoration:none}
.prcert a:hover .prcert-t b{text-decoration:underline}
/* A logo alone says which attestation it is; repeating the name beside it is noise. */
.prcert.haslogo .prcert-t b{display:none}
.prcert.haslogo .prcert-t span{font-size:11px}

/* comparison table
 *
 * Two scroll problems, two different fixes, because one element cannot be the scroll container for
 * both axes:
 *
 *   • Narrow screens. The table is wider than the screen and always will be — five columns of prices
 *     do not fit in 390px, and squeezing them into it produces a table nobody can read. So it scrolls
 *     sideways, and the FEATURE column is pinned (position:sticky;left:0 resolves against
 *     .prtblscroll): without it you scroll right to see Enterprise and no longer know which of
 *     twenty-five rows you are looking at. A fade at the right edge and a one-line hint say the
 *     sideways scroll is there; both are driven from _pricing.js off the real scroll geometry, so
 *     neither ever claims there is more table when there isn't.
 *   • Wide screens. The header row used to carry position:sticky;top:0 and never once stuck, because
 *     sticky resolves against the nearest scrolling ancestor — which was the horizontal scroller,
 *     only as tall as the table. Once there is room for the whole table we hand the horizontal
 *     overflow back (overflow:visible) so top: resolves against the page, and the column names stay
 *     with you down all twenty-five rows. top is the 52px localbar, which covers the 44px nav.
 *
 * .prtblwrap owns the border and the radius and does NOT scroll, so the fade can be positioned
 * against it. .prtblscroll (#prMatrix, server-filled) is the scroller.
 */
.prcompare{padding:clamp(40px,6vh,68px) 0 0;scroll-margin-top:96px}
.prtblwrap{position:relative;margin:clamp(18px,3vh,26px) 0 0;border:1px solid var(--hair);border-radius:18px;background:#fff}
.prtblscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;border-radius:18px}
/* Right-edge fade — only while there is genuinely more table to the right (data-more from JS). Above
   the sticky header (z-index 4) so it fades the column names too. */
.prtblwrap::after{content:"";position:absolute;top:1px;bottom:1px;right:1px;width:38px;z-index:6;pointer-events:none;opacity:0;transition:opacity .2s ease;border-radius:0 17px 17px 0;background:linear-gradient(to left,#fff 12%,rgba(255,255,255,0))}
.prtblwrap[data-more]::after{opacity:1}
.prtblhint{font-size:12.5px;color:var(--grey-l);text-align:center;margin:11px 0 0}
.prtblhint[hidden]{display:none}
/* Footnote for the table itself — what "Add-on" costs, what "Planned" means. The table can now say
   "Add-on $50" in a cell, but the cell has no room to say what the $50 buys. */
.prtblnote{font-size:12.5px;color:var(--grey);text-align:center;max-width:74ch;margin:12px auto 0;line-height:1.5;text-wrap:pretty}
.prtblnote:empty{display:none}
.prtbl{width:100%;border-collapse:collapse;font-size:13.5px;min-width:720px}
.prtbl th,.prtbl td{text-align:center;padding:12px 14px;border-bottom:1px solid var(--hair)}
/* top:0 here, not the localbar's 52px: while the scroller still owns the horizontal overflow it is
   also the sticky viewport, and a 52px threshold against a scrollport the header already sits at the
   top of pushes it 52px DOWN — an empty white band inside the table. The real offset is set with the
   overflow hand-back below, where the page is the scrollport. */
.prtbl thead th{position:sticky;top:0;background:#FBFBFD;font-size:12px;font-weight:600;letter-spacing:-.005em;color:var(--ink);z-index:3;border-bottom:1px solid var(--line)}
/* The pinned feature column. Opaque, or the plan columns slide visibly under the row labels. */
.prtbl th.f,.prtbl td.f{position:sticky;left:0;z-index:2;background:#fff;text-align:left;color:#333336;font-weight:400;width:34%;min-width:250px}
.prtbl thead th.f{z-index:4;background:#FBFBFD;color:var(--grey-l);font-size:11px;letter-spacing:.05em;text-transform:uppercase;font-weight:600}
/* Only once you have actually scrolled: a permanent shadow would just be a stray column rule. */
.prtblwrap[data-sx] .prtbl th.f,.prtblwrap[data-sx] .prtbl td.f{box-shadow:7px 0 13px -9px rgba(0,0,0,.28)}
/* The wrap's radius cannot clip the table (it must not scroll, and on wide screens the scroller has
   no overflow either), so the corner cells carry their own. */
.prtbl thead th:first-child{border-top-left-radius:17px}
.prtbl thead th:last-child{border-top-right-radius:17px}
/* :first-child, not td:first-child — the row label is a <th scope="row"> (it IS a header for its
   row, and a screen reader reading a lone tick needs to be told which feature it belongs to), so a
   td-only selector silently stopped matching the corner. */
/* tbody:last-of-type, not tbody: there is now one tbody per feature group (see renderPricing), so a
   plain `tbody tr:last-child` rounded the last row of EVERY group and rubbed out the rule between
   groups. Only the final row of the final group is a corner. */
.prtbl tbody:last-of-type tr:last-child>:first-child{border-bottom-left-radius:17px}
.prtbl tbody:last-of-type tr:last-child>:last-child{border-bottom-right-radius:17px}
.prtbl tbody:last-of-type tr:last-child>th,.prtbl tbody:last-of-type tr:last-child>td{border-bottom:0}
/* Twenty-five rows across five columns: something has to tell you which row your eye is on. The
   pinned label is opaque and overrides #fff, so it has to be tinted with the rest of the row. */
@media (hover:hover){.prtbl tbody tr:not(.prgrp):hover>td,.prtbl tbody tr:not(.prgrp):hover>th.f{background:#F7F7FA}}
.prtbl tr.prgrp td{background:var(--panel);text-align:left;padding:11px 14px;border-bottom:1px solid var(--hair)}
/* The group row spans every column, so its label would scroll off with them. Pinned instead — a
   coloured band with its heading gone reads as a rendering fault. */
.prtbl tr.prgrp i.prgrph{position:sticky;left:14px;display:inline-block;font-style:normal;max-width:100%}
.prtbl tr.prgrp b{font-size:12px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:var(--ink)}
.prtbl tr.prgrp span{font-size:12px;color:var(--grey);font-weight:400;letter-spacing:normal;text-transform:none;margin-left:8px}
/* Phone accordion. Twenty-two rows × five columns on a 390px screen is a wall you scroll past
   rather than read, so under 740px each group folds and only the first is open — you choose which
   fourteen rows you care about instead of being handed all twenty-two. The toggle is wired in
   _pricing.js and only there: without JS every group stays open, which is the correct fallback for a
   comparison table. .prg[data-fold] marks a group the script has actually taken charge of, so the
   chevron and the pointer can never appear on a heading that does nothing. */
.prg[data-fold] tr.prgrp i.prgrph{cursor:pointer;display:flex;align-items:center;gap:8px;width:100%}
.prg[data-fold] tr.prgrp i.prgrph::after{content:"";width:9px;height:9px;flex:none;margin-left:auto;border-right:1.6px solid var(--grey);border-bottom:1.6px solid var(--grey);transform:rotate(45deg) translateY(-2px);transition:transform .2s ease}
.prg[data-fold][aria-expanded="false"] tr.prgrp i.prgrph::after{transform:rotate(-45deg) translateX(-2px)}
.prg[data-fold] tr.prgrp i.prgrph:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:6px}
/* A folded group keeps its heading row and hides only its feature rows, so the table never loses the
   labels that say what is behind each fold. */
.prg[data-fold][aria-expanded="false"] tr:not(.prgrp){display:none}
/* Folded, the group heading is the only thing in its group, so it should not read as a band with
   nothing under it. A rule under it closes it off. */
.prg[data-fold][aria-expanded="false"] tr.prgrp td{border-bottom:1px solid var(--line)}
@media (max-width:740px){
  /* The pinned label column stops being an advantage once it is over half the screen — with two plan
     columns visible you compare two plans, and with the label taking 158px of 390 you compare one. */
  .prtbl tr.prgrp i.prgrph{max-width:calc(100vw - 68px)}
}
/* 860px is where the content column (viewport − 44px of padding) clears the table's 720px minimum,
   so handing the horizontal overflow back cannot introduce a sideways scrollbar — and the header row
   starts sticking to the page instead of to a container the same height as itself. */
@media (min-width:860px){
  .prtblscroll{overflow:visible}
  /* Now the page is the scrollport, so the offset can be the height of what is already pinned up
     there: the 52px localbar, which covers the 44px nav. */
  .prtbl thead th{top:52px}
}
.prtbl td.v{color:var(--grey);font-size:12.5px}
.prtbl td .yes{display:inline-block;width:16px;height:16px;border-radius:50%;background:#E7F4EC url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'><path d='M3.4 7.3l2.2 2.2 5-5' fill='none' stroke='%23248A3D' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/></svg>") center/13px no-repeat;vertical-align:middle}
.prtbl td .no{color:#C7C7CC;font-size:15px}
.prtbl td .pill{display:inline-block;font-size:11px;font-weight:600;border-radius:999px;padding:3px 9px;background:var(--panel);color:var(--grey)}
.prtbl td .pill.add{background:#EAF3FE;color:#0B5FBF}
.prtbl td .pill.plan{background:#F3F1FB;color:#5B4BB5}

/* how to buy */
.prbuy{padding:clamp(40px,6vh,68px) 0 0;scroll-margin-top:96px}
.prroutes{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin:clamp(18px,3vh,26px) 0 0}
.prroute{background:var(--panel);border-radius:18px;padding:24px 22px}
.prroute .prn{font-size:12px;font-weight:700;letter-spacing:.06em;color:var(--grey-l);margin:0 0 10px}
.prroute h3{font-size:17px;font-weight:600;letter-spacing:-.018em;margin:0 0 6px}
.prroute p{font-size:13.5px;color:var(--grey);line-height:1.5;margin:0}

/* questions */
.prfaq{padding:clamp(40px,6vh,68px) 0 0}
.prqa{max-width:760px;margin:clamp(18px,3vh,26px) auto 0}
.prqa details{border-bottom:1px solid var(--hair)}
.prqa summary{display:flex;justify-content:space-between;gap:16px;align-items:center;list-style:none;cursor:pointer;font-size:16px;font-weight:500;letter-spacing:-.012em;padding:17px 2px}
.prqa summary::-webkit-details-marker{display:none}
.prqa summary::after{content:"+";font-size:19px;font-weight:300;color:var(--grey-l);line-height:1}
.prqa details[open] summary::after{content:"\2212"}
.prqa p{font-size:14.5px;color:var(--grey);line-height:1.55;margin:0;padding:0 2px 18px;max-width:66ch}

/* close */
.prclose{text-align:center;background:var(--panel);border-radius:24px;padding:clamp(38px,6vh,62px) 24px;margin:clamp(40px,6vh,68px) 0 0}
.prclose .prsub{margin-bottom:22px}
.prfoot{font-size:11px;color:var(--grey-l);text-align:center;line-height:1.5;max-width:80ch;margin:34px auto 0}

/* join sheet — the point of the page */
/* z-index above the cookie bar's 240 — same as the cookie preference centre, and for the same
 * reason. At 120 the bar floated over the dialog and, on a first visit, sat exactly on top of the
 * Join waitlist button: the one click the page exists to collect, swallowed by the consent banner. */
.prsheet{position:fixed;inset:0;z-index:260;display:flex;align-items:center;justify-content:center;padding:20px}
.prsheet[hidden]{display:none}
.prsheet-bg{position:absolute;inset:0;background:rgba(0,0,0,.44);animation:prfade .2s ease}
@keyframes prfade{from{opacity:0}}
.prsheet-card{position:relative;background:#fff;border-radius:22px;width:min(440px,100%);max-height:calc(100vh - 40px);overflow:auto;padding:30px 28px 26px;animation:prpop .24s cubic-bezier(.2,.7,.2,1)}
@keyframes prpop{from{opacity:0;transform:translateY(14px) scale(.98)}}
@media (prefers-reduced-motion:reduce){.prsheet-bg,.prsheet-card{animation:none}}
.prx{position:absolute;right:16px;top:16px;border:0;background:#E9E9EB;color:#6E6E73;width:27px;height:27px;border-radius:50%;cursor:pointer;font-size:12px;line-height:27px;padding:0}
.prx:hover{background:#DEDEE2}
.prsheet-card h3{font-size:23px;font-weight:600;letter-spacing:-.024em;margin:0}
.prsheet-card .preyebrow{margin-bottom:5px}
.prsheet-sub{font-size:13.5px;color:var(--grey);line-height:1.45;margin:8px 0 18px}
.prf{display:block;margin:0 0 12px}
/* Same trap as .prfeat: the seat field is toggled with [hidden], and display:block above outranks it —
 * so every plan's join form asked for a seat count, including the ones sold per person. */
.prf[hidden]{display:none}
.prf>span{display:block;font-size:12px;font-weight:500;color:var(--grey);margin:0 0 5px}
.prf>span i{font-style:normal;color:var(--grey-l);font-weight:400}
.prf input,.prf textarea{width:100%;font-family:var(--sans);font-size:15px;color:var(--ink);background:#fff;border:1px solid var(--line);border-radius:11px;padding:11px 13px;outline:none;transition:border-color .15s,box-shadow .15s;-webkit-appearance:none}
.prf textarea{resize:vertical;line-height:1.4}
.prf input:focus,.prf textarea:focus{border-color:var(--blue);box-shadow:0 0 0 4px rgba(0,113,227,.13)}
.prf input::placeholder,.prf textarea::placeholder{color:var(--grey-l)}
.prsubmit{width:100%;margin:6px 0 0}
.prsubmit:disabled{background:#9BCAF5;cursor:default}
.prf select{width:100%;font-family:var(--sans);font-size:15px;color:var(--ink);background:#fff url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'><path d='M1 1l4 4 4-4' fill='none' stroke='%236E6E73' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/></svg>") right 13px center/10px no-repeat;border:1px solid var(--line);border-radius:11px;padding:11px 34px 11px 13px;outline:none;-webkit-appearance:none;appearance:none;cursor:pointer;transition:border-color .15s,box-shadow .15s}
.prf select:focus{border-color:var(--blue);box-shadow:0 0 0 4px rgba(0,113,227,.13)}
.prmsg{font-size:13px;line-height:1.45;margin:12px 0 0;padding:10px 12px;border-radius:10px;background:var(--panel);color:var(--grey)}
.prmsg.bad{background:#FDECEC;color:#B3261E}
.prmsg.good{background:#E7F4EC;color:#1F7A43}

/* join dialog, two panels: admin-uploaded media on the left, the form on the right. With nothing
 * uploaded the media panel is genuinely empty, :empty collapses it, and the dialog is the same
 * single-column sheet it was before — no grey placeholder standing in for a picture. */
.prsheet-card.prjoin{display:flex;padding:0;width:min(880px,100%);overflow:hidden}
.prjoin-media{position:relative;flex:0 0 42%;background:var(--panel);overflow:hidden}
.prjoin-media:empty{display:none}
.prjoin-media img,.prjoin-media video{display:block;width:100%;height:100%;object-fit:cover}
.prjoin-media .prcap{position:absolute;left:0;right:0;bottom:0;margin:0;font-size:12.5px;line-height:1.4;color:#fff;padding:26px 20px 16px;background:linear-gradient(to top,rgba(0,0,0,.62),rgba(0,0,0,0))}
.prjoin-form{flex:1 1 auto;min-width:0;padding:30px 28px 26px;overflow:auto;max-height:calc(100vh - 40px)}

/* business dialog — per seat, per year, with a minimum order and a running total */
.prbiz-card{width:min(470px,100%)}
.prbiz-name{margin:0 0 2px}
.prbiz-price{display:flex;align-items:baseline;gap:7px;margin:10px 0 0}
.prbiz-price .prnum{font-size:34px}
.prbiz-feat{margin:18px 0 0;gap:8px}
.prbiz-feat li{font-size:13px}
/* Requirements. Rows, not chips: each one is a name, a line saying what it actually means and a
 * price, and those three do not fit on a chip. The whole block collapses when the draft configures
 * no requirements, so a plain per-seat dialog stays plain — :has on the empty <ul>, because the
 * server fills the <ul> and cannot reach the wrapper's attributes. */
.prreqs{margin:20px 0 0;padding:16px 0 0;border-top:1px solid var(--hair)}
.prreqs:has(.prreqlist:empty){display:none}
.prreq-lab{display:block;font-size:14px;font-weight:500;letter-spacing:-.01em}
.prreqlist{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-direction:column;gap:6px}
.prreq label{display:flex;align-items:flex-start;gap:10px;padding:10px 12px;border:1px solid var(--line);border-radius:12px;cursor:pointer;transition:border-color .15s ease,background .15s ease}
.prreq label:hover{background:#FBFBFD}
/* Ticked rows are tinted as well as checked: with five of these stacked, a 16px box is not enough to
 * see at a glance what the running price is made of. */
.prreq label:has(input:checked){border-color:var(--blue);background:#F5F9FF}
.prreq input{margin:1px 0 0;width:16px;height:16px;flex:none;accent-color:var(--blue)}
.prreq-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.prreq-t b{font-size:13.5px;font-weight:550;letter-spacing:-.01em;color:var(--ink)}
.prreq-t span{font-size:12px;color:var(--grey);line-height:1.4}
.prreq-p{flex:none;font-size:13px;font-weight:600;color:var(--blue);white-space:nowrap;padding-top:1px}
.prreq-note{font-size:12px;color:var(--grey-l);line-height:1.45;margin:10px 0 0}
.prreq-note:empty{display:none}
.prseats{display:flex;align-items:center;justify-content:space-between;gap:14px;margin:20px 0 0;padding:14px 0 0;border-top:1px solid var(--hair)}
.prseats-lab{font-size:14px;font-weight:500;letter-spacing:-.01em}
.prstep{display:flex;align-items:center;gap:2px;background:var(--panel);border-radius:11px;padding:3px}
.prstepb{width:32px;height:32px;border:0;background:#fff;color:var(--ink);border-radius:8px;font-size:17px;line-height:1;cursor:pointer;box-shadow:0 0 0 .5px rgba(0,0,0,.06);transition:background .15s,color .15s}
.prstepb:hover{background:#EFEFF2}
.prstepb:disabled{color:#C7C7CC;cursor:default;background:#fff}
.prstep input{width:62px;height:32px;text-align:center;font-family:var(--sans);font-size:15px;font-weight:600;color:var(--ink);background:none;border:0;outline:none;-moz-appearance:textfield;appearance:textfield}
.prstep input::-webkit-outer-spin-button,.prstep input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.prseats-note{font-size:12px;color:var(--grey-l);line-height:1.45;margin:9px 0 0}
.prseats-note:empty{display:none}
.prtotal{display:flex;align-items:baseline;justify-content:space-between;gap:14px;margin:16px 0 0;padding:14px 16px;background:var(--panel);border-radius:14px}
.prtotal span{font-size:13.5px;color:var(--grey)}
.prtotal-l{display:flex;flex-direction:column;gap:2px;min-width:0}
.prtotal i{font-style:normal;font-size:11.5px;color:var(--grey-l);line-height:1.35}
.prtotal i:empty{display:none}
.prtotal b{font-size:23px;font-weight:600;letter-spacing:-.028em}
/* The primary label is editable ("Join Business Waitlist" by default) and base .btn padding is 28px
 * a side, which wrapped it to two lines inside a 470px dialog. Cancel takes only the width of its
 * own word so the long label keeps the rest, and nowrap makes a too-long one overflow visibly
 * rather than silently growing the button to two lines. */
.prbiz-act{display:flex;gap:9px;margin:18px 0 0}
.prbiz-act .btn{padding:12px 18px;font-size:15px;white-space:nowrap;text-align:center}
.prbiz-act #prBizCancel{flex:0 0 auto}
.prbiz-act #prBizGo{flex:1;min-width:0}
.prbiz-sales{font-size:12px;color:var(--grey-l);line-height:1.5;margin:14px 0 0;text-align:center}
.prbiz-sales:empty{display:none}
.prbiz-sales a{color:var(--link)}

/* draft ribbon — only rendered for a signed-in admin looking at an unpublished page, so it is
 * impossible for a visitor to see this and equally impossible for an admin to forget which they
 * are looking at. */
.prdraft{background:#FFF6E0;border-bottom:1px solid #F2E0B4;color:#8A5A00;font-size:12.5px;font-weight:500;text-align:center;padding:9px 16px}
.prdraft a{color:#8A5A00;text-decoration:underline}

@media (max-width:1040px){
  /* Wrap rather than shrink: a group frame keeps its cards together and takes a full row of its own,
     so the label still sits over the plans it describes instead of over one of them. */
  .prcards{flex-wrap:wrap;gap:14px}
  .prcards>.prcard{flex:1 1 260px}
  .prbox{flex:1 1 100%}
  .prtag{min-height:0}
  .prroutes{grid-template-columns:1fr}
}
@media (max-width:820px){
  /* Below this the media panel would squeeze the form into a column of two-word lines, so the
     dialog stacks: media as a band across the top, form under it. */
  .prsheet-card.prjoin{flex-direction:column;width:min(460px,100%);max-height:calc(100vh - 40px);overflow:auto}
  .prjoin-media{flex:none;height:190px}
  .prjoin-form{max-height:none;overflow:visible}
}
@media (max-width:820px){
  .prcerts{--pc:2}
}
@media (max-width:520px){
  .prcerts{--pc:1}
}
@media (max-width:640px){
  main.prmain{padding:0 16px 48px}
  .prcards{flex-direction:column}
  .prcards>.prcard,.prbox{flex:1 1 auto}
  .prbox-in{flex-direction:column}
  .prswitchrow{display:flex;flex-direction:column;align-items:center;gap:12px}
  /* Still a segmented switch, just full width. Stacked vertically it became two more boxes above the
     Business button — three stacked rectangles where the design is "pick one of two, then a button". */
  .prswitch{display:flex;width:100%;max-width:340px}
  .prswitch button{flex:1;justify-content:center;padding:9px 10px}
  .prbizwrap{width:100%;max-width:340px}
  .prbizbtn{width:100%;justify-content:center;padding:12px 18px}
  .prclose{border-radius:20px;margin-left:-4px;margin-right:-4px}
  .prsheet{padding:0;align-items:flex-end}
  .prsheet-card{width:100%;border-radius:22px 22px 0 0;max-height:92vh;padding-bottom:calc(26px + env(safe-area-inset-bottom))}
  .prsheet-card.prjoin{width:100%;padding-bottom:0}
  .prjoin-media{height:150px}
  .prjoin-form{padding-bottom:calc(26px + env(safe-area-inset-bottom))}
  .prbiz-card{padding-bottom:calc(26px + env(safe-area-inset-bottom))}
  /* A 250px feature column plus a 720px minimum left a 390px phone showing the feature names and
     Individual, with the other three plans off-screen and nothing saying so. Narrower and tighter, so
     two plan columns are visible at a time next to the pinned labels. */
  .prtbl{font-size:13px;min-width:560px}
  .prtbl th,.prtbl td{padding:11px 10px}
  .prtbl th.f,.prtbl td.f{width:auto;min-width:158px}
  .prtbl thead th{font-size:11.5px}
  .prtbl tr.prgrp td{padding:10px 10px}
  .prtbl tr.prgrp i.prgrph{left:10px}
  /* The note beside a group heading is a second line at this width, not a suffix. */
  .prtbl tr.prgrp span{display:block;margin-left:0;margin-top:2px}
}
