/* Shared styles for the small ParcelFill pages (success, account, privacy).
   Tokens match site/index.html. */
:root { --ink:#12211d; --muted:#5d6e68; --paper:#f9faf6; --mist:#edf3ed; --line:#d7e2d8; --lime:#cbfb45; --green:#176b4b; --deep:#0b2e23; --coral:#ef8564; --amber:#fff7ed; --amber-ink:#9a3412; --red:#fef2f2; --red-ink:#991b1b; --ok:#ecfdf5; --ok-ink:#065f46; }
* { box-sizing:border-box; }
body { margin:0; color:var(--ink); background:var(--paper); font:16px/1.55 ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
a { color:var(--green); }
/* The support address links (env-banner.js): the colour of the sentence they sit in, underlined. */
a[data-mail] { color:inherit; text-decoration:underline; }
code { font-size:.88em; background:var(--mist); padding:.1em .35em; border-radius:5px; }
.shell { width:min(760px, calc(100% - 40px)); margin:auto; }
/* Sticky, and in flow: `position: sticky` reserves its own space, so nothing
   below shifts and no padding has to be added to compensate. On these pages the
   header IS the nav, so this is the whole of it. */
header { position:sticky; top:0; z-index:50; background:var(--deep); color:white; }
/* Where an anchor jump stops: under the sticky header, not behind it. Without
   this a help TOC link, or /help#stuck from a support email, left the heading
   20px from the top under a 74px bar (ui-audit #18). The header height was
   measured with headless Chrome on every page that loads this sheet, not
   guessed: 74px from 761px up, where the links share the brand's row, and
   98px at 760px and under, where the language menu takes the brand's row
   and the links the next (the 760px block below). That is the SHORT bar, the
   task pages' (account, success, 404). The reading pages carry the landing
   page's bar and its own three values: see the bar-full block at the foot of
   this sheet. Each value carries 8px of air so a heading
   does not sit flush against the bar; on these pages that air falls inside the
   heading's own top margin, so no sliver of the section above shows through.
   As scroll-padding on the page, as on the landing page, not scroll-margin
   on every [id]: it also clears a focused control that has no id, and a new
   anchor needs no edit here. */
:root { --bar:82px; }
html { scroll-padding-top:var(--bar); }
/* One focus ring on every control: the green the text inputs have, lime on the
   dark header, where green would not show (the language list is white, so it
   keeps the green). The skip link is out of sight until it takes focus, then a
   pill at the top left over everything. */
:focus-visible { outline:3px solid var(--green); outline-offset:2px; }
header :focus-visible { outline-color:var(--lime); }
.lang-list :focus-visible { outline-color:var(--green); }
.skip { position:fixed; top:8px; left:8px; z-index:100; padding:.5rem .8rem; border-radius:8px; background:white; color:var(--ink); font-weight:700; }
.skip:not(:focus) { clip-path:inset(50%); width:1px; height:1px; overflow:hidden; white-space:nowrap; }
.skip:focus-visible { outline-color:var(--lime); }
/* A heading focus lands on when the control it was on is gone (account.html), or the page's title once a sign-in has drawn the account: it is not a control, so it draws no ring. */
h1[tabindex="-1"]:focus-visible, h2[tabindex="-1"]:focus-visible, p[tabindex="-1"]:focus-visible { outline:none; }
/* nav.js moves focus to the section a link scrolled to (and gives it tabindex -1 to take it): it is not a control, so it draws no ring. */
section[tabindex="-1"]:focus, main[tabindex="-1"]:focus, div[tabindex="-1"]:focus { outline:none; }
header nav { display:flex; align-items:center; justify-content:space-between; gap:20px; padding:22px 0; }
/* The links are grouped so `space-between` has two children whatever the count.
   With three loose children it parks the middle link dead centre, which is what
   these pages looked like once a second link was added. */
.nav-links { display:flex; align-items:center; flex-wrap:wrap; gap:8px 20px; }
/* The language menu (A-02): the header nav's last child, after .nav-links,
   the shape the landing page's nav has. A plain <details>: it opens and
   closes by click or keyboard with no script. With a third child
   space-between would park the links mid-bar, so .nav-links takes the free
   space on its left and the nav's gap sets the menu off from it. The pill
   is 28px, under the 30px brand mark, so the bar keeps its 74px, and the
   header has no overflow rule to clip the menu below it. `.lang-menu
   .lang-list a` outranks `header nav a:not(.brand)`, which would paint the
   menu's links the bar's mint on its white. The phone bar is further down,
   after the footer rules. */
.nav-links { margin-left:auto; }
/* The links are a list that is also the phone's menu (a native popover, the
   landing page's pattern): on a wide screen the browser's popover box (fixed,
   bordered, white, padded, scrolling) is undone and it stays the row it was.
   Its left margin is the rule above's; width is left to the phone rules. */
.nav-links { position:static; width:auto; height:auto; margin-top:0; margin-right:0; margin-bottom:0; padding:0; overflow:visible; border:0; background:none; color:inherit; list-style:none; }
/* The phone bar's own parts (a Pricing button, the menu button, and the menu's
   row of language pills): none shows on a wide screen. The 760px block below
   brings them in where popovers work. */
header .nav-buy, header .nav-menu, .nav-links .nav-langs { display:none; }
.lang-menu { position:relative; flex-shrink:0; }
.lang-menu summary { display:flex; align-items:center; gap:.35rem; height:28px; padding:0 .7rem; border:1px solid #3f6a5a; border-radius:999px; color:#d9ebe1; font-size:.86rem; font-weight:650; letter-spacing:0; white-space:nowrap; cursor:pointer; list-style:none; }
.lang-menu summary::-webkit-details-marker { display:none; }
.lang-menu summary::after, .lang-menu[open] summary::after { content:"\25BE"; color:inherit; font-size:.8em; line-height:1; }
.lang-menu summary:hover { color:white; border-color:#d9ebe1; }
.lang-menu[open] summary { background:white; border-color:white; color:var(--ink); }
.lang-short { display:none; }
.lang-globe { display:inline-flex; align-items:center; }
.lang-list { position:absolute; right:0; top:calc(100% + 8px); z-index:60; display:grid; min-width:180px; padding:6px; border:1px solid var(--line); border-radius:12px; background:white; box-shadow:0 12px 30px rgba(11,46,35,.18); }
.lang-menu .lang-list a { display:block; margin:0; padding:.45rem .7rem; border-radius:8px; color:var(--ink); font-size:.9rem; font-weight:600; line-height:1.4; text-decoration:none; white-space:nowrap; }
.lang-menu .lang-list a:hover { background:var(--mist); }
.lang-menu .lang-list a[aria-current="page"] { background:var(--mist); font-weight:800; }
/* The list eases in (entrance only; closing is instant). */
.lang-list { transition:opacity .18s ease, transform .18s ease; }
@starting-style {
  .lang-menu[open] .lang-list { opacity:0; transform:translateY(-4px); }
}
/* So does the phone menu. Its own block: a browser that does not know
   :popover-open drops this one and keeps the language list's above. */
#nav-menu { transition:opacity .18s ease, transform .18s ease; }
@starting-style {
  #nav-menu:popover-open { opacity:0; transform:translateY(-4px); }
}
.brand { display:flex; align-items:center; gap:.65rem; color:white; font-weight:800; letter-spacing:-.03em; text-decoration:none; }
.brand-mark { display:grid; width:30px; height:30px; place-items:center; background:var(--lime); color:var(--deep); border-radius:9px; font-size:1.05rem; }
header nav a:not(.brand) { color:#d9ebe1; font-size:.92rem; text-decoration:none; }
/* A 24px target at least (WCAG 2.5.8; audit finding 10 measured these at
   23px), the padding handed back as negative margin so the bar keeps its
   height and the links their gaps. On .nav-links, not `nav a`: that also
   matches the language pills, which are big enough already. */
.nav-links a { display:inline-block; padding:.5rem .25rem; margin:-.5rem -.25rem; }
/* The phone's Pricing button: the bar's one buy action, lime on the dark bar
   as on the landing page. After `header nav a:not(.brand)` on purpose: same
   weight, so order lets it set the colour. */
header nav a.nav-buy { padding:.55rem 1rem; font-size:.9rem; background:var(--lime); color:var(--deep); border-color:var(--lime); }
header nav a.nav-buy:hover { background:#d8ff6b; }
.eyebrow { margin:0 0 14px; color:var(--green); font-size:.76rem; font-weight:800; letter-spacing:.14em; text-transform:uppercase; }
h1 { margin:0 0 14px; font-size:clamp(2rem, 5vw, 3rem); line-height:1.03; letter-spacing:-.055em; }
h2 { margin:36px 0 10px; font-size:1.35rem; letter-spacing:-.03em; }
/* Chinese headings. The negative tracking above tightens Latin type and
   squeezes CJK glyphs, which are drawn for zero tracking. `line-break:strict`
   asks for the strictest rules on which punctuation may start a line.
   :lang(zh) matches zh-Hans and zh-Hant, and its specificity also beats a
   page's own `h2 { letter-spacing }` (help.html). */
:lang(zh) h1, :lang(zh) h2, :lang(zh) h3 { letter-spacing:0; line-break:strict; }
.lead { margin:0 0 26px; color:var(--muted); font-size:1.08rem; }
main { padding:56px 0 80px; }
.panel { padding:26px; border:1px solid var(--line); border-radius:18px; background:white; }
.button { display:inline-flex; align-items:center; justify-content:center; gap:.55rem; border:1px solid var(--deep); border-radius:999px; padding:.75rem 1.2rem; background:var(--deep); color:white; font:inherit; font-weight:750; text-decoration:none; cursor:pointer; transition:transform .18s, background .18s; }
.button:hover { background:#164838; transform:translateY(-2px); }
.button:active { transform:translateY(0) scale(.98); transition-duration:.08s; }
.button.lime { background:var(--lime); color:var(--deep); border-color:var(--lime); }
.button.alt { background:transparent; color:var(--ink); border-color:var(--line); }
.button[disabled], .button[aria-disabled="true"] { opacity:.55; cursor:default; transform:none; }
/* A form that is sending marks its button aria-disabled instead of disabled,
   so the button keeps keyboard focus; the flag in the page's script stops a
   second submit, and this stops a second click. */
.button[aria-disabled="true"] { pointer-events:none; }
/* The wait on the success page: the page sets --p (tries spent, 0 to 1) and
   the bar follows it. Nothing here loops: it only moves when a try is made. */
.tries { height:4px; margin-top:14px; border-radius:999px; background:var(--line); overflow:hidden; }
.tries i { display:block; height:100%; background:var(--green); transform-origin:0 50%; transform:scaleX(var(--p, 0)); transition:transform .18s ease; }
.key-row { display:flex; flex-wrap:wrap; gap:10px; align-items:center; }
.key { flex:1 1 300px; padding:.8rem 1rem; border-radius:12px; background:var(--deep); color:var(--lime); font:700 1.15rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing:.04em; word-break:break-all; }
.note { margin:16px 0 0; padding:12px 14px; border-radius:10px; font-weight:650; font-size:.94rem; }
.note.warn { background:var(--amber); color:var(--amber-ink); }
.note.err { background:var(--red); color:var(--red-ink); }
.note.ok { background:var(--ok); color:var(--ok-ink); }
.steps { display:grid; gap:12px; margin:0; padding:0; list-style:none; counter-reset:s; }
.steps li { counter-increment:s; display:flex; gap:12px; align-items:baseline; }
.steps li::before { content:counter(s); flex:0 0 26px; height:26px; display:grid; place-items:center; border-radius:50%; background:var(--lime); color:var(--deep); font-size:.8rem; font-weight:900; }
label { display:block; margin:0 0 6px; font-weight:700; }
/* Ordinary text by default. The monospace below is opt-in, because it was
   written for a license key — a string read character by character — and an
   email address or a browser version set in it just looks wrong and fits
   fewer characters in the same box. */
input[type=text] { width:100%; padding:.75rem .9rem; border:1px solid #7f8f88; border-radius:10px; font:inherit; background:white; color:var(--ink); }
input[type=text].mono { font:600 1rem ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
/* The box's own edge is #7f8f88, 3.39:1 on the page (the 1.33:1 of --line is the
   edge of a decoration, not of a control: WCAG 1.4.11 asks 3:1 of the control). */
/* Green, never lime: lime on a white field measures 1.21:1, under the 3:1 a
   focus indicator needs (WCAG 1.4.11). The same ring as the landing page's
   checkout field. */
input[type=text]:focus { outline:3px solid var(--green); outline-offset:2px; border-color:var(--green); }
form .button { margin-top:14px; }
.placeholder { background:#fff3c4; padding:0 .25em; border-radius:4px; }
.prose p, .prose li { color:#2c3b36; }
/* A reading line, not the 760px shell: help, privacy and terms ran 95 to 110
   characters across, past the 60 to 75 the eye follows. On the reading pages
   only (.prose), plus the lead under a title; forms, panels and the success
   steps are not narrowed. */
.prose p, .prose li, .lead { max-width:68ch; }
.prose ul { padding-left:1.2rem; }
footer { padding:26px 0; color:var(--muted); font-size:.86rem; border-top:1px solid var(--line); }
/* 16px tall links padded past 24px, the padding handed back so the footer's
   lines keep their spacing. inline-block, so the padding sizes the box. */
footer a { display:inline-block; padding:.35rem 0; margin:-.35rem 0; color:inherit; }
[hidden] { display:none !important; }
/* The language pills (A-02), at the foot of every page: dark text on white
   pills, the current one filled. Their own rules, which `header nav` above
   no longer reaches: unscoped, `nav a:not(.brand)` outranked `.langs a` and
   painted them the bar's mint on white, 1.3:1 (docs/ui-audit.md #2), and
   `nav`'s space-between spread them across the page. margin:0 so no
   footer-wide link rule can shift them. */
.langs { display:flex; flex-wrap:wrap; justify-content:flex-start; gap:8px; margin:0; padding:0; }
.langs a { margin:0; padding:.3rem .7rem; border:1px solid var(--line); border-radius:999px; background:white; color:var(--ink); font-size:.86rem; font-weight:650; text-decoration:none; }
.langs a[aria-current="page"] { background:var(--deep); border-color:var(--deep); color:white; }
footer .langs { margin-top:14px; }
/* A phone, up to 760px, gets the landing page's bar: the brand and the
   language menu (its short name) on the first row, the menu at the right
   end by `order` (in the markup it follows the links, the order a keyboard
   reaches them on a wide screen), and the links on a row of their own
   under them, in the landing page's size and 8px apart. Inside .nav-links
   the menu pushed the links onto a third row, a 103-134px sticky bar; this
   is 98px, the landing page's, wherever the links fit one row. They do not
   on success-fr below 384px or success below 327px, whose three labels are
   wider than the screen: there they wrap 8px apart, as before, a 128px bar.
   Placed after the header rules on purpose: the link size overrides
   `header nav a:not(.brand)` by order, not by weight. */
@media (max-width:760px) {
  header nav { flex-wrap:wrap; gap:10px 18px; padding:18px 0; }
  .brand { order:-2; }
  header nav > details.lang-menu { order:-1; margin-left:auto; }
  .nav-links { order:0; width:100%; margin-left:0; gap:8px; }
  header nav a:not(.brand) { font-size:.88rem; }
  .lang-long { display:none; }
  .lang-short { display:inline; }
  /* 98px of header, the links on their own row, plus the same 8px of air.
     success and success-fr wrap their three links to a third row (128px) at
     the narrowest widths, but those pages have no anchor to land on. This is
     the bar of a browser without popovers. */
  :root { --bar:106px; }
  /* One row on a phone, the landing page's bar: the brand, a Pricing button,
     and a menu button that opens the links and the languages as a popover.
     44px controls in 10px of padding make the 64px bar, and --bar is that
     exactly, so the open menu starts right under it. It renders in the top
     layer, so the sticky header cannot clip it. A browser without popovers
     skips this block and keeps the wrapped rows above. Every rule that
     changes an existing element is scoped to a header that has #nav-menu, so
     a page whose header has no menu keeps the rows. */
  @supports selector(:popover-open) {
    :root:has(#nav-menu) { --bar:64px; }
    header nav:has(#nav-menu) { flex-wrap:nowrap; gap:8px; padding:10px 0; }
    header .nav-buy, header .nav-menu { display:inline-flex; height:44px; }
    header nav a.nav-buy { margin-left:auto; }
    header .nav-menu { align-items:center; justify-content:center; width:44px; padding:0; border:1px solid #3f6a5a; border-radius:10px; background:none; color:#d9ebe1; font:inherit; font-size:1.25rem; line-height:1; cursor:pointer; transition:transform .08s ease; }
    header .nav-menu:active { transform:scale(.98); }
    header .nav-menu::before { content:"\2630"; }
    header nav:has(#nav-menu:popover-open) .nav-menu { background:white; border-color:white; color:var(--deep); }
    header nav:has(#nav-menu:popover-open) .nav-menu::before { content:"\2715"; }
    /* The header's language menu gives way to the menu's last row, the same
       four links as pills. */
    header nav:has(#nav-menu) > details.lang-menu { display:none; }
    #nav-menu:not(:popover-open) { display:none; }
    #nav-menu { position:fixed; inset:var(--bar) 0 auto; flex-direction:column; flex-wrap:nowrap; align-items:stretch; gap:0; width:auto; max-height:calc(100dvh - var(--bar)); margin:0; padding:0 20px 16px; overflow:auto; background:var(--deep); font-size:1rem; box-shadow:0 18px 30px rgba(0,0,0,.25); }
    #nav-menu li { border-top:1px solid #244a3c; }
    /* Pricing is the bar's button here. */
    #nav-menu li:has(> a[href$="#pricing"]) { display:none; }
    #nav-menu a:not(.button) { display:flex; align-items:center; min-height:44px; margin:0; padding:0; color:#d9ebe1; font-size:1rem; }
    #nav-menu .nav-langs { display:flex; flex-wrap:wrap; gap:8px; padding:12px 0 0; }
    #nav-menu .nav-langs a { padding:0 .9rem; border:1px solid var(--line); border-radius:999px; background:white; color:var(--ink); font-size:.9rem; font-weight:650; }
    #nav-menu .nav-langs a[aria-current="page"] { background:var(--lime); border-color:var(--lime); color:var(--deep); }
  }
}

/* ---- the two public forms (bug-report.html, contact.html) ---- */
textarea, select { width:100%; padding:.75rem .9rem; border:1px solid #7f8f88; border-radius:10px; font:inherit; background:white; color:var(--ink); }
textarea { min-height:150px; resize:vertical; line-height:1.55; }
/* The same ring as `input[type=text]:focus` above: the message box and the
   dropdown showed the browser's own. */
textarea:focus, select:focus { outline:3px solid var(--green); outline-offset:2px; border-color:var(--green); }
.field { margin:0 0 18px; }
.field:last-of-type { margin-bottom:0; }
.hint { margin:6px 0 0; color:var(--muted); font-size:.88rem; font-weight:500; }
/* A plan card's status line when it needs attention (account page): the note colours. */
.hint.warn { color:var(--amber-ink); font-weight:650; }
.hint.err { color:var(--red-ink); font-weight:650; }
/* A long address or a code hint must wrap, or a 64-character email pushes the phone page sideways. */
#who, #code-hint { overflow-wrap:anywhere; }
.optional { color:var(--muted); font-weight:500; }
/* A required field says so beside its label, as an optional one does. The
   words are aria-hidden because the control's own `required` already tells a
   screen reader. Its error sits under the control (forms.js check()). */
.required { color:var(--muted); font-weight:500; }
.field-error { margin:6px 0 0; color:var(--red-ink); font-size:.88rem; font-weight:650; }
input[aria-invalid="true"], textarea[aria-invalid="true"] { border-color:var(--red-ink); }

/* A group of radio answers (goodbye.html): the legend is the question and each
   answer is a whole-row target, so a thumb does not have to find a 20 px circle. */
fieldset.choices { margin:0 0 18px; padding:0; border:0; min-width:0; }
.choices legend { padding:0; margin:0 0 8px; font-weight:650; }
.choice { display:flex; align-items:center; gap:10px; min-height:44px; margin:0 0 6px; padding:8px 12px; border:1px solid var(--line); border-radius:10px; background:white; font-weight:500; cursor:pointer; }
.choice input { flex:none; width:20px; height:20px; margin:0; accent-color:var(--green); }
.choice:has(input:checked) { border-color:var(--green); background:var(--paper); }
.choice:has(input:focus-visible) { outline:3px solid var(--green); outline-offset:2px; }
.choices[aria-invalid="true"] .choice { border-color:var(--red-ink); }
.drop:has(input[aria-invalid="true"]) { border-color:var(--red-ink); }

/* The file list is built from the chosen files, so the browser's own "5 files"
   summary never has to be the only thing on screen. */
.shots { margin:10px 0 0; padding:0; list-style:none; }
.shots li { display:flex; align-items:center; gap:10px; padding:8px 10px; border:1px solid var(--line); border-radius:10px; margin:0 0 6px; font-size:.9rem; }
.shots .name { flex:1 1 auto; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.shots .size { color:var(--muted); font-variant-numeric:tabular-nums; }
.shots button { border:1px solid var(--line); border-radius:8px; background:white; color:var(--red-ink); font:inherit; font-weight:700; padding:2px 8px; cursor:pointer; }
.drop { display:block; padding:16px; border:1px dashed var(--line); border-radius:12px; background:var(--paper); text-align:center; cursor:pointer; font-weight:650; }
.drop input { position:absolute; width:1px; height:1px; opacity:0; }
/* That input is 1 px and invisible, so the ring the browser draws on it is
   too: a keyboard user tabbing to it saw nothing at all. The box around it
   carries the ring instead. */
.drop:focus-within { outline:3px solid var(--green); outline-offset:2px; }
.count { color:var(--muted); font-weight:500; }

/* Turnstile renders its own iframe; this only reserves the room so the button
   does not jump when it appears. */
.guard { margin:18px 0 0; min-height:65px; }

/* A form that is sending shows it on the button: a lime bar along its foot. A
   button of the account page that has started a request (aria-busy) wears the same bar.
   It loops only while the request is in flight (aria-busy is set for exactly
   that long), and the reduced-motion rule at the foot of this sheet stops it. */
@keyframes busy { 0% { transform:scaleX(.1); } 100% { transform:scaleX(1); } }
form[aria-busy="true"] button[type="submit"], button[aria-busy="true"] { position:relative; overflow:hidden; }
form[aria-busy="true"] button[type="submit"]::after, button[aria-busy="true"]::after { content:""; position:absolute; left:0; bottom:0; width:100%; height:3px; background:var(--lime); transform-origin:0 50%; animation:busy 1.2s ease infinite; }
/* Lime shows on the dark buttons; the pale ones (Cancel at period end, Remove, End now) get the green. */
.button.alt[aria-busy="true"]::after, .device-actions button[aria-busy="true"]::after { background:var(--green); }
/* A report with screenshots knows how much has gone (bug-report.html sets --p
   from the upload's progress): the bar shows that fraction instead of looping. */
form[data-progress] button[type="submit"]::after { animation:none; transform:scaleX(var(--p, 0)); transition:transform .18s ease; }

/* What replaces a form once it has been sent: a status panel that takes focus
   (the page's script focuses it, so a screen reader reads it). It arrives with
   the page's own entrance, and its confirmation flashes once, green on green,
   so the eye finds it. The panel is focusable only so it can be focused: it
   is not a control, so it has no ring. */
@keyframes arrive { from { opacity:0; transform:translateY(4px); } to { opacity:1; transform:none; } }
@keyframes flash { 0% { background:#ecfdf5; } 35% { background:#bbf7d0; } 100% { background:#ecfdf5; } }
.sent { animation:arrive .18s ease both; }
.sent .note.ok { animation:flash 1.2s ease .18s 1; }
.sent:focus { outline:none; }
/* The line an account action changed rises in and flashes once (account.html).
   The connect code is lime on deep green, which the flash's pale green would
   bury, so it only rises in. */
.pf-changed { animation:arrive .18s ease both, flash 1.2s ease .18s 1; }
.code-big.pf-changed { animation:arrive .18s ease both; }
.sent h2 { margin-top:0; }
.sent .next { display:flex; flex-wrap:wrap; gap:6px 18px; margin:18px 0 0; }

/* ---- account.html: the browsers on a license, and connect codes (3.105.0) ---- */
.devices { margin:10px 0 0; padding:0; list-style:none; }
.device { display:flex; flex-wrap:wrap; align-items:flex-start; gap:6px 12px; padding:10px 12px; border:1px solid var(--line); border-radius:10px; margin:0 0 8px; font-size:.92rem; }
.device-main { flex:1 1 260px; min-width:0; display:flex; flex-direction:column; gap:2px; }
.device-name { font-weight:750; overflow-wrap:anywhere; }
.device-who { color:var(--ink); overflow-wrap:anywhere; }
.device-meta { color:var(--muted); font-size:.84rem; overflow-wrap:anywhere; }
/* A browser past the plan's limit: the same amber the warning note above the list uses. */
.device-stops { align-self:flex-start; margin-top:4px; padding:1px 8px; border-radius:6px; background:var(--amber); color:var(--amber-ink); font-size:12px; font-weight:650; overflow-wrap:anywhere; }
.device-actions { display:flex; gap:6px; flex:1 1 100%; min-width:0; }
.device-actions button { flex:0 0 auto; border:1px solid var(--line); border-radius:8px; background:white; color:var(--green); font:inherit; font-weight:700; padding:2px 8px; cursor:pointer; }
/* The buttons sit left, under the row's text, at every width: a Remove that asks a second time puts a longer label (and Keep) after itself, and the corner the pointer is on never moves. Only the armed one may shrink, and wrap, to stay on this line. */
.device-actions button.pf-armed { flex:0 1 auto; min-width:0; }
.device-actions button.danger { color:var(--red-ink); }
.device-edit { flex:1 1 100%; display:grid; grid-template-columns:minmax(0, 1fr) minmax(0, 1fr); gap:8px 12px; align-items:end; padding-top:6px; }
.device-edit label { display:flex; flex-direction:column; gap:4px; font-weight:650; font-size:.86rem; }
.device-edit .button { margin-top:0; }
.device-edit .note { grid-column:1 / -1; }
/* Connect a browser (account.html): a summary that holds the panel's heading, folded once a browser is connected. */
#connect > summary { cursor:pointer; }
#connect > summary h2 { display:inline; }
#connect[open] > summary { margin-bottom:0; }
.code-row { display:flex; flex-wrap:wrap; gap:8px; align-items:flex-end; margin-top:10px; }
/* The count box's own label, over it: the row lines its bottoms up. */
.code-field label { margin:0 0 4px; font-size:.86rem; font-weight:650; }
.code-row select { width:auto; }
input[type=number] { padding:.75rem .9rem; border:1px solid #7f8f88; border-radius:10px; font:inherit; background:white; color:var(--ink); }
.code-big { margin:12px 0 4px; padding:.7rem 1rem; border-radius:12px; background:var(--deep); color:var(--lime); font:700 1.7rem/1.2 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing:.14em; text-align:center; overflow-wrap:anywhere; }
.code-status { margin:6px 0 0; font-weight:650; font-variant-numeric:tabular-nums; }
/* Cancel at period end and the invoice list. Cancel wears the warning amber so
   it never reads as the page's main action; the table is plain on purpose, an
   invoice's own page does the rest. */
/* Three classes deep because `.button.alt` sets the same two properties. */
.button.alt.cancel-plan { color:var(--amber-ink); border-color:var(--amber-ink); }
details.inv summary { cursor:pointer; font-weight:750; margin-top:18px; }
table.invoices { width:100%; border-collapse:collapse; font-size:.92rem; margin-top:10px; }
table.invoices th, table.invoices td { text-align:left; padding:8px 6px; border-bottom:1px solid var(--line); }
table.invoices th { font-size:.78rem; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
table.invoices td.num { font-variant-numeric:tabular-nums; }
/* The date stays on one line: it wrapped onto three on a phone. Only the date: the amount beside it is one word, and two nowrap cells and the links were 13px wider than a 375px screen. */
table.invoices td.date { white-space:nowrap; }
/* A language with longer dates (French: "10 nov. 2026") still made the table 13px wider than a 375px screen. The list scrolls inside its own box; the page never scrolls sideways. */
details.inv { max-width:100%; overflow-x:auto; }
/* A live region that is heard and not seen (the standard clip pattern): a two-press control says its new label here, so the words are not also written onto the page, where a line that appears pushes the controls down from under the pointer. */
.visually-hidden { position:absolute; width:1px; height:1px; margin:-1px; padding:0; border:0; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; }
/* A button that asks for a second press: amber, with the 8 seconds draining along its edge. */
.pf-armed { position:relative; overflow:hidden; max-width:100%; white-space:normal; overflow-wrap:anywhere; text-align:left; background:#fff7ed !important; border-color:#b45309 !important; color:#7c2d12 !important; transition:background .15s ease, color .15s ease, border-color .15s ease; }
.pf-armed::after { content:""; position:absolute; left:0; bottom:0; height:3px; width:100%; background:#b45309; transform-origin:0 50%; animation:pf-drain 8s linear forwards; }
@keyframes pf-drain { to { transform:scaleX(0); } }
@media (prefers-reduced-motion:reduce) { .pf-armed { transition:none; } .pf-armed::after { animation:none; } }
@media (max-width:560px) {
  .device-edit { grid-template-columns:minmax(0, 1fr); }
  /* With the date held on one line the four columns are wider than a phone's panel: tighter cells and type, so the table fits and nothing scrolls sideways. */
  table.invoices { font-size:.86rem; }
  table.invoices th, table.invoices td { padding:8px 4px; }
  table.invoices th { letter-spacing:.03em; }
  /* Remove sat 6px from Edit and 29px tall: a thumb's slip disconnected a browser. A long label wraps inside its button instead of pushing Keep off the screen. */
  .device-actions { gap:10px; flex-wrap:wrap; }
  /* The armed Remove keeps its place beside Edit and takes the rest of the line (never less than 9em) for its label; Keep goes on beside it if there is room, else under it. */
  .device-actions button.pf-armed { flex:1 1 9em; }
  .device-actions button { min-height:44px; padding:.5rem .9rem; white-space:normal; overflow-wrap:anywhere; text-align:left; }
  /* A help figure scaled to a phone's width printed its labels at about 4px.
     It keeps a readable width and scrolls sideways inside its own box (the
     figure takes focus, so a keyboard can scroll it: help*.html names it). */
  .fig { overflow-x:auto; }
  .fig svg { min-width:600px; }
}
/* Motion is new to this sheet (the language list's ease-in): honour reduced
   motion the way the landing page does. */
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation:none !important; transition:none !important; } }

/* ---- bar-full: the reading pages keep the landing page's top bar ----
   help, contact, bug-report, privacy and terms (every language) carry
   class="bar-full" on <body> and show the landing page's bar: the same seven
   items in the same order (the four in-page links point at the landing page's
   sections), the lime Get started button, the same geometry. The task pages
   (account, success, 404) keep the short bar above: nobody reads them to be
   convinced, and the short bar is measured to stay exactly as it was.
   Only what differs from the short bar is set here; the rest (the language
   menu, the phone menu, the popover rules) is shared. The page's content
   stays in its 760px column: only the header's shell widens.
   --bar is the sticky bar's height, measured in headless Chrome on the
   landing page and on these pages in all four languages (the two agree to
   the pixel): 86px from 761px up, one row; 98px at 760px and under in a
   browser without popovers, where the links wrap under the brand; 64px
   where popovers work (the one-row phone bar, 44px controls in 10px of
   padding). The same three values as the landing page, on its breakpoints.
   The short bar's values are the ones in the comment above `--bar`. */
.bar-full header > .shell { width:min(1160px, calc(100% - 40px)); }
.bar-full .nav-links { flex-wrap:nowrap; gap:24px; }
.bar-full .nav-links a:not(.button):hover { color:white; }
/* After `.nav-links a` (the text links' 24px target and negative margin) and
   `header nav a:not(.brand)` (their mint): three classes outrank both. */
.bar-full .nav-links a.button { display:inline-flex; margin:0; padding:.55rem 1rem; background:var(--lime); color:var(--deep); border-color:var(--lime); font-size:.9rem; }
.bar-full .nav-links a.button:hover { background:#d8ff6b; }
:root:has(> .bar-full) { --bar:86px; }
/* The landing page lands a section flush under its bar: the section's own
   padding is the air. A heading on a reading page has none, so it keeps the
   8px the short bar's --bar carries. Added here and not to --bar, which must
   stay the bar's real height on these pages: the phone menu hangs from it. */
html:has(> .bar-full) { scroll-padding-top:calc(var(--bar) + 8px); }
/* From 980px down the language menu shows its short name and the bar's gaps
   tighten, as on the landing page. */
@media (max-width:980px) {
  .bar-full .lang-long { display:none; }
  .bar-full .lang-short { display:inline; }
  .bar-full header nav { gap:14px; }
  .bar-full .nav-links { gap:10px; }
}
/* A phone: the links wrap under the brand, 14px between rows, 8px between
   links, and Get started goes (it points where Pricing does). Where popovers
   work the menu replaces all of it, and the rules above for the one-row bar
   (`header nav:has(#nav-menu)`, `#nav-menu`) outrank these. */
@media (max-width:760px) {
  .bar-full header nav { gap:10px 18px; }
  .bar-full .nav-links { flex-wrap:wrap; gap:14px 8px; }
  .bar-full .nav-links li:last-child { display:none; }
  :root:has(> .bar-full) { --bar:98px; }
  @supports selector(:popover-open) {
    :root:has(> .bar-full) { --bar:64px; }
  }
}

/* ---- checkout.html: the address, and the sale broken down before Stripe opens ----
   Reached from a plan card as checkout.html?plan=pro&period=yearly. A task
   page, so it keeps the short bar; only its width differs: body.wide widens
   every .shell on this page (header, main, footer) to 1040px, so the brand
   sits over the left column and the summary card ends where the header does.
   Two columns above 860px: the address and the pay button on the left, the
   summary on the right, sticky under the bar. At 860px and under it is one
   column with the summary above the form; .co-main steps out of the grid
   (display:contents) so the title can stay above the summary while the form
   goes below it. Amounts never wrap (a figure split across two lines reads as
   two figures); labels may. */
.wide .shell { width:min(1040px, calc(100% - 40px)); }
.co-grid { display:grid; grid-template-columns:minmax(0, 1fr) 420px; gap:56px; align-items:start; }
.co-main form .button { margin-top:18px; }
.co-main .hint { margin-top:14px; max-width:52ch; font-size:.9rem; }
/* A line is counted in ch, the width of a 0: a Chinese line of that measure is half as many characters, and left a one-character last line. */
:lang(zh) .co-main .hint { max-width:none; }
.co-main .note a { color:inherit; font-weight:700; }
.co-none .button { margin-top:6px; }
.co-sum { padding:22px 24px; border:1px solid var(--line); border-radius:16px; background:white; }
.co-sum h2 { margin:0; font-size:1.05rem; }
.co-top { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:10px 8px; margin-bottom:14px; }
/* The period switch: a pill group, the pressed one filled. Colour is not the
   only sign of which is pressed: its label is heavier too, and aria-pressed
   says it to a screen reader. */
.co-period { display:inline-flex; padding:3px; border:1px solid var(--line); border-radius:999px; background:var(--mist); }
.co-period button { min-height:30px; padding:0 12px; border:0; border-radius:999px; background:none; color:var(--ink); font:inherit; font-size:.88rem; font-weight:600; cursor:pointer; }
.co-period button[aria-pressed="true"] { background:var(--deep); color:white; font-weight:800; }
.co-plan { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:16px; }
.co-plan b { display:block; font-size:1.15rem; font-weight:800; letter-spacing:-.02em; }
.co-plan span { display:block; color:var(--muted); font-size:.86rem; }
.co-plan a { display:inline-block; flex-shrink:0; padding:.35rem 0; margin:-.35rem 0; font-size:.92rem; }
.co-rows { margin:0; padding:0; list-style:none; font-variant-numeric:tabular-nums; }
.co-rows li { display:flex; justify-content:space-between; gap:16px; padding:9px 0; border-top:1px solid var(--line); font-size:.95rem; }
.co-rows li span:last-child { flex-shrink:0; white-space:nowrap; font-weight:650; text-align:right; }
.co-rows .save span { color:var(--green); }
/* The tax line says where the figure comes from, in words: it may wrap, where an amount may not. */
.co-rows .muted span:last-child { flex-shrink:1; min-width:0; white-space:normal; color:var(--muted); font-weight:500; }
.co-rows .total { border-top:2px solid var(--ink); padding-top:12px; font-size:1.12rem; font-weight:800; }
.co-rows .total span:last-child { font-weight:800; }
.co-saves { margin:10px 0 0; color:#2c3b36; font-size:.9rem; font-weight:650; }
.co-after { margin:12px 0 0; color:var(--muted); font-size:.88rem; }
.co-after + .co-after { margin-top:6px; }
.co-perks { display:grid; gap:6px; margin:16px 0 0; padding:14px 0 0; border-top:1px solid var(--line); list-style:none; color:#2c3b36; font-size:.9rem; }
.co-perks li::before { content:"\2713"; content:"\2713" / ""; margin-right:8px; color:var(--green); font-weight:900; }
@media (min-width:861px) {
  .co-sum { position:sticky; top:calc(var(--bar) + 24px); }
}
@media (max-width:860px) {
  .co-grid { grid-template-columns:minmax(0, 1fr); gap:24px; }
  .co-main { display:contents; }
  .co-head { order:1; }
  .co-sum { order:2; }
  .co-main form, .co-none { order:3; }
  .co-period button { min-height:44px; }
}
