/* site.css: the one look of every Recharge page (/join, /me, /go, /done, /start, /partner, /admin), taken from the
   landing page and /join. The recorder (light.html) keeps its own look. Light only, as the landing page is.

   USE: <link rel="stylesheet" href="/site.css?v=3" /> first in <head>, then a short <style> with only what is the
   page's own. Bump ?v= in every page when this file changes (it is cached for 5 minutes). Class names are the API:
   rename nothing without changing every page. Mobile first. Breakpoints: phone <= 760px, between 761-899px (one
   centred column), computer >= 900px.

   INDEX (class: what it is, how to use it)
   Tokens     --navy --navy-2 --blue --blue-ink --link --green --pink --amber --danger --ink --muted --line --line-soft
              --line-strong --tint --card --tint-blue --tint-green --tint-pink --tint-amber --tint-grey
              --wash-blue --wash-pink --wash-amber (very light notice backgrounds) --r-sm --r-md --r-lg --shadow
              --s-1..--s-8 (4 8 12 16 24 32 48 64) --font
   Base       body gets the tint and its soft glow; h1 page title, h2 card title, h3 small heading; p and headings have
              no margins (space things with .stack or the page's own rules); a in --link; focus ring on everything.
   .tabular   numbers in columns (tabular figures).          .sr-only  hidden but read by screen readers.
   .muted     muted text.
   Layout
   .site        on <body>: a full-height column, the footer at the bottom. Put .site-main on the part that grows.
   .wrap        the page width (max 1120px) with the side gutters; .wrap-narrow max 640px (forms, one card).
   .site-header <header class="site-header wrap"><a class="brand" href="/"><img src="/brand/Logo_black_text.png"
                alt="Recharge" width="56" height="56"></a><div class="header-end">...</div></header>
   .language-picker  the page's language, top right on every page that has one (the landing page's picker): a pill
                with a globe, the current language's flag and a chevron, opening a small menu (flag + name, the current
                one ticked): <details class="language-picker" id="langPicker"><summary aria-label="Language: English">
                <svg class="language-globe" ..>..</svg><img class="language-flag" src="/brand/flags/gb.svg" alt=""
                aria-hidden="true" width="24" height="18"></summary><div class="language-options"><button type="button"
                data-pick-lang="en" lang="en" aria-current="true"><img class="language-flag" ..><span>English</span>
                </button><button type="button" data-pick-lang="zh" lang="zh-CN">..<span>简体中文</span></button></div>
                </details>. The options are 44px buttons that switch the language in place (the page's script, the same
                languagePicker() on every page, keeps the flag, the aria-label "Language: English" / "语言：简体中文" and
                the tick in step, and closes the menu after a choice, on Escape and on a click outside). Flags:
                /brand/flags/ (flag-icons, MIT, brand/flags/LICENSE.txt). Put it in .header-end (or straight in the
                .site-header) or in the app shell's .app-top-end (see App shell).
   .site-footer <footer class="site-footer"><div class="footer-inner wrap"><nav class="foot-links">a a a</nav>
                <p class="foot-copy">&copy; 2026 Recharge</p></div></footer>
   .page-title  <div class="page-title"><p class="eyebrow">..</p><h1>..</h1><p class="lead">..</p></div>
   .eyebrow     the small uppercase line above a title.      .lead  the muted line under a title.
   .grid-2      two columns on a computer, one (max 640px, centred) below.
   .stack       children spaced 16px apart; .stack-sm 8px, .stack-lg 24px.
   Components
   .card        white card (.card-flat: no shadow, for lists inside a card). h2 inside is the card title.
   .btn         navy button, 48px (icon: an <svg> or <img> inside). .btn-secondary white with a navy border,
                .btn-ghost text-style 44px, .btn-danger, .btn-sm 40px (dense tables on a computer only),
                .btn-block full width. Disabled: the disabled attribute. .btn-row: a row of buttons that wraps.
   .field       <div class="field"><label for=x>..</label><input id=x><p class="hint">..</p><p class="field-error">..</p></div>
                (.field-note is the same as .hint). Inputs 52px. Mark a bad input aria-invalid="true".
   .error       a form's message under its button (danger, centred, hidden when empty; give it role="alert").
   .check       <label class="check"><input type="checkbox"><span>..</span></label>, a 44px tap row.
   .seg         segmented control: <div class="seg" role="group"><button aria-pressed="true">7 days</button>..</div>
                (or role=tab with aria-selected). 44px tall.
   .tabs        <div class="tabs" role="tablist"><button role="tab" aria-selected="true">Clients <span class="count">12</span>
                </button>..</div> (links: aria-current="page"). Navy underline on the selected one; scrolls sideways.
   .chips       <div class="chips"><button class="chip" aria-pressed="true">All</button>..</div>, one row that scrolls
                sideways; selected is navy.
   .tag         status: <span class="tag tag-ok">Done</span>; .tag-ok .tag-warn .tag-bad .tag-info .tag-muted
                (a dot before the words; colour is never the only sign, the words say it).
   .badge       a small grey pill, e.g. <span class="badge">内部</span>.
   .notice      info box (blue); .notice-warn (amber), .notice-bad (pink). Links inside are bold.
   .toast       <div class="toast" role="status" hidden>Saved</div>; the page shows and hides it.
   .dialog      <dialog class="dialog"><h2 class="dialog-title">..</h2><div class="dialog-body">..</div>
                <div class="dialog-actions"><button class="btn-secondary">Cancel</button><button class="btn">OK</button>
                </div></dialog> (actions stack full width on phones, the primary on top).
   .empty       <div class="empty"><span class="icon-disc grey">svg</span><p>No clients yet</p><a class="btn">..</a></div>
   .icon-disc   a round icon background, 48px; .icon-disc-sm 36px; tints .blue .green .pink .amber .grey.
   .kv          <dl class="kv"><dt>Name</dt><dd>Sam</dd>..</dl>: two columns on a computer, stacked on phones.
   .table       <div class="table-wrap"><table class="table">..</table></div>: a computer data table, sticky header
                (give .table-wrap a max-height for it to stick inside), td.num right-aligned, td.actions nowrap,
                <span class="sub"> a muted second line. The wrap scrolls sideways with a fade on the side that hides more.
   .rows-as-cards  add to a .table: on phones every <tr> becomes a card; give each <td> data-label="Status" for its
                small label; td.actions becomes a full-width row of 44px buttons. One markup for both sizes.
   .list-rows   settings rows with a chevron, 56px: <ul class="list-rows"><li><a href="#">
                <span class="list-main">Title<span class="sub">detail</span></span></a></li></ul> (or <button>).
   .breadcrumb  <nav class="breadcrumb" aria-label="Breadcrumb"><ol><li><a>Clients</a></li><li aria-current="page">Sam</li></ol></nav>
   .skeleton    a loading block that shimmers (still for people who ask for less motion); set its width and height.
   App shell    the signed-in pages split into sections (/me, /partner, /admin): on a computer (>= 900px) a sidebar on
                the left; below 900px (phones and tablets alike) a compact top bar and the same sections as a bottom tab
                bar. ONE <nav> serves both sizes: there is no separate tab bar element, .app-side IS the tab bar below
                900px. Tokens --side-w (248px) --top-h (56px) --tabbar-h (64px) --tint-navy (the selected section)
                --nav-hover.
   .app-shell   on <body> instead of .site: <body class="app-shell"><a class="app-skip" href="#main">Skip to content</a>
                <header class="app-top">..</header><div class="app-side">..</div><main class="app-main" id="main"
                tabindex="-1">..</main></body>
   .app-skip    the skip link: off screen until focused, then a navy pill at the top left.
   .app-top     below 900px only: <header class="app-top"><a class="app-brand" href="#home"><img
                src="/brand/Logo_without_text.png" alt="Recharge" width="32" height="32"></a><span class="app-top-title"
                aria-hidden="true">Home</span><div class="app-top-end">at most one action (.app-icon-btn, or the
                .language-picker)</div></header>. The page keeps .app-top-title in step with the section (aria-hidden:
                the h1 says it). A .language-picker in .app-top-end stays on a computer too (the rest of the top bar is
                hidden there): at the top right of the content, on the line of the section's title row; the title row
                (.app-head), whatever comes before it in a section and a failed-load line (.app-content > .load-error)
                keep clear of it.
   .app-icon-btn  a 44px icon button (an svg inside; give it aria-label, or words after the svg).
   .app-side    the sidebar (a computer) and the bottom tab bar (below 900px): <div class="app-side"><a class="app-brand"
                href="#home"><img src="/brand/Logo_without_text.png" alt="" width="40" height="40"><span
                class="app-brand-name">Recharge</span></a><nav class="app-nav" aria-label="Sections">..</nav>
                <div class="app-side-end">..</div></div>. Its .app-brand and .app-side-end show on a computer only.
   .app-nav     the sections: <a href="#home" aria-current="page"><svg viewBox="0 0 24 24" aria-hidden="true">..</svg>
                <span class="app-nav-label">Home</span><span class="count">3</span></a> (Tabler-style 24px line icons,
                stroke from here; <button>s work too). Selected: aria-current="page" on exactly one. A computer: a navy
                tint row, navy and bold. Below 900px: a navy icon on a tinted pill and a navy bold label, the others
                muted. A .count is a badge at the row's end (a computer) or on the icon (below 900px).
   .app-side-end  the sidebar's foot (a computer): <p class="app-who">a•••@mail.com<span class="sub">Org</span></p> and
                rows like the nav's: <a class="app-side-row" href="#account">svg Account</a>, <button type="button"
                class="app-side-row">svg Sign out</button>. Below 900px they are hidden: put them in the Account section
                (or the top bar's one action).
   .app-main    the content: <main class="app-main" id="main" tabindex="-1"><div class="app-content">sections</div>
                (a .site-footer after .app-content sits at the bottom)</main>. .app-content: max 1120px, centred, with
                the gutters; below 900px padded so the tab bar never covers it.
   .app-section one section: <section class="app-section" id="sec-home" aria-labelledby="t-home" hidden>; its children
                are spaced 24px apart. The page shows one (from the hash: #home, #reports ..) and hides the rest.
   .app-head    the section's title row: <div class="app-head"><div class="app-head-text"><h1 class="app-title"
                id="t-home" tabindex="-1">Home</h1><p class="app-lead">..</p></div><div class="app-actions">buttons
                </div></div>. On a section change move focus to its .app-title. Below 900px the h1 is for screen
                readers only (the top bar shows the title); .app-head-sub (a sub-page: a .breadcrumb in .app-head-text
                above the h1, e.g. one client) keeps it shown.
*/

/* tokens: the landing page's palette, type, radii, shadow and spacing */
:root {
  --navy: #202c48; --navy-2: #2e4366; --blue: #35c1fc; --blue-ink: #139ad0; --link: #126a99; --eyebrow: #126d94;
  --green: #61e1a3; --pink: #fc7e9e; --amber: #9a6700; --amber-ink: #7a5200; --danger: #a22e43; --ok-ink: #0b5e3a;
  --ink: #202c48; --muted: #50607a; --line: #dce4ed; --line-soft: #e3eaf1; --line-strong: #7d8ca3; --line-hover: #c3d0dd;
  --tint: #f7fbfd; --card: #fff;
  --tint-blue: #e0f4ff; --tint-green: #d9f6e9; --tint-pink: #ffe2e9; --tint-amber: #fff1cc; --tint-grey: #eef1f5;
  --wash-blue: #eef8fd; --wash-blue-line: #cdeaf8; --wash-pink: #fff4f6; --wash-pink-line: #ffd3dd;
  --wash-amber: #fff8e6; --wash-amber-line: #f5dc9c;
  --r-sm: 10px; --r-md: 14px; --r-lg: 18px;
  --shadow: 0 12px 30px #202c481c;
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;
  --side-w: 248px; --top-h: 56px; --tabbar-h: 64px; --tint-navy: #e6ecf4; --nav-hover: #f0f4f8;
  --font: 'Segoe UI', Arial, 'PingFang SC', 'Noto Sans SC', 'Microsoft YaHei', 'Noto Sans CJK SC', sans-serif;
  color-scheme: light;
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  font-synthesis: none;
}

/* base: box sizing, [hidden] always wins, the tint with the landing page's soft glow at the top right */
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; background: var(--tint); color: var(--ink); -webkit-font-smoothing: antialiased; }
body { font: 16px/1.55 var(--font); -webkit-text-size-adjust: 100%; background: radial-gradient(900px 520px at 100% 0%, #eaf6fd, #eaf6fd00 70%), var(--tint); }
button, input, select, textarea { font: inherit; color: inherit; }
button, a, label { -webkit-tap-highlight-color: transparent; touch-action: manipulation; }
p, h1, h2, h3, ol, ul, dl, dd, figure { margin: 0; }
img, svg { max-width: 100%; }

/* headings: h1 the page title, h2 a card's title, h3 a small heading */
h1 { font-size: clamp(1.75rem, 6vw, 2.4rem); line-height: 1.15; letter-spacing: -.035em; font-weight: 700; text-wrap: balance; }
h2 { font-size: 1.55rem; line-height: 1.2; font-weight: 700; letter-spacing: -.035em; text-wrap: balance; }
h3 { font-size: 1.1rem; line-height: 1.35; font-weight: 650; letter-spacing: -.01em; }
html[lang^="zh"] h1, html[lang^="zh"] h2, html[lang^="zh"] h3 { letter-spacing: 0; }
@media (max-width: 760px) { h2 { font-size: 1.3rem; } }

/* links in the link blue, underlined in the landing page's blue */
a { color: var(--link); text-decoration-color: var(--blue); text-underline-offset: 4px; }

/* one focus ring everywhere (keyboard only) */
:focus-visible { outline: 3px solid var(--link); outline-offset: 3px; }

/* utilities: figures in columns, muted text, hidden but read aloud */
.tabular, .num { font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.sr-only { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* layout: the full-height page (footer at the bottom) and the page width with its gutters */
.site { min-height: 100vh; min-height: 100dvh; display: flex; flex-direction: column; }
.site-main { flex: 1 0 auto; }
.wrap { width: 100%; max-width: 1120px; margin-inline: auto; padding-inline: 16px; }
.wrap-narrow { max-width: 640px; }
@media (min-width: 761px) { .wrap { padding-inline: 24px; } }
@media (min-width: 900px) { .wrap { padding-inline: 32px; } }

/* the header: the logo left, a slot right (.header-end: the language picker, a sign-out, a name) */
.site-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 76px; padding-block: 10px; }
.brand { display: block; flex: none; }
.brand img { display: block; width: 56px; height: 56px; object-fit: contain; }
.header-end { display: flex; align-items: center; gap: 12px; min-width: 0; }
@media (max-width: 760px) { .site-header { min-height: 60px; padding-block: 6px; } .brand img { width: 44px; height: 44px; } }
@media (min-width: 761px) { .site-header { min-height: 96px; } .brand img { width: 72px; height: 72px; } }
@media (min-width: 900px) { .site-header { min-height: 88px; } }

/* the language picker (the landing page's): a pill with a globe, the flag and a chevron; a small menu of languages */
.language-picker { position: relative; flex: none; margin: 0; padding: 0; border: 0; color: var(--navy); font-size: .9375rem; line-height: 1.4; z-index: 30; }
.language-picker > summary { display: flex; align-items: center; justify-content: center; gap: 6px; list-style: none; cursor: pointer; min-height: 44px; padding: 10px 12px; border: 1px solid #c9d5e8; border-radius: 999px; background: #fcfcff; font-weight: 500; white-space: nowrap; transition: background-color .25s, border-color .25s; }
.language-picker > summary::-webkit-details-marker { display: none; }
.language-picker > summary:hover, .language-picker[open] > summary { background: #eff7fc; border-color: #9eb7d0; }
.language-picker > summary::after { content: ""; flex: none; width: 6px; height: 6px; margin: -4px 1px 0; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform .25s; }
.language-picker[open] > summary::after { transform: translateY(3px) rotate(225deg); }
.language-globe { display: block; flex: none; width: 16px; height: 16px; color: var(--link); }
.language-picker .language-flag { display: block; flex: none; width: 24px; height: 18px; object-fit: cover; border-radius: 2px; box-shadow: 0 0 0 1px #202c481a; }
.language-picker > summary .language-flag { width: 20px; height: 15px; }
.language-options { position: absolute; right: 0; top: calc(100% + 8px); width: 216px; max-height: min(360px, 65vh); overflow-y: auto; padding: 7px; background: #fff; border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: 0 12px 35px #202c481c; }
.language-options button { display: flex; align-items: center; gap: 11px; width: 100%; min-height: 44px; padding: 12px 14px; border: 0; border-radius: 8px; background: none; color: var(--navy); font-size: inherit; line-height: inherit; text-align: left; cursor: pointer; }
.language-options button:hover, .language-options button[aria-current] { background: #eaf7fd; }
.language-options button[aria-current] { color: var(--link); font-weight: 600; }
.language-options button[aria-current]::after { content: ""; flex: none; width: 5px; height: 10px; margin-left: auto; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg) translate(-1px, -2px); }
@media (max-width: 760px) { .language-picker > summary { padding: 10px; font-size: .8125rem; } }
@media print { .language-picker { display: none; } }

/* the footer: one line of small muted links and the year, a thin line above; centred and wrapping on phones */
.site-footer { flex: none; border-top: 1px solid var(--line-soft); padding-bottom: env(safe-area-inset-bottom, 0px); }
.footer-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; column-gap: 24px; padding-block: 8px; }
.foot-links { display: flex; flex-wrap: wrap; justify-content: center; column-gap: 20px; }
.foot-links a { display: inline-flex; align-items: center; min-height: 44px; padding-inline: 2px; font-size: .875rem; color: var(--muted); text-decoration: none; }
.foot-links a:hover { color: var(--navy); text-decoration: underline; text-decoration-color: var(--blue); text-underline-offset: 5px; }
.foot-copy { font-size: .875rem; line-height: 44px; color: var(--muted); }
@media (max-width: 760px) { .footer-inner { padding-block: 4px; } .foot-copy { line-height: 1.4; padding-bottom: 10px; } }
@media (min-width: 900px) { .footer-inner { justify-content: space-between; padding-block: 10px; } .foot-links { justify-content: flex-start; column-gap: 28px; } }

/* a page's title block: the eyebrow, the h1 and its muted lead line */
.eyebrow { text-transform: uppercase; letter-spacing: .21em; font-size: .72rem; font-weight: 650; color: var(--eyebrow); margin-bottom: 16px; }
.lead { color: var(--muted); line-height: 1.65; overflow-wrap: anywhere; }
.page-title { padding-block: 24px 16px; }
.page-title .lead { margin-top: 10px; max-width: 40em; font-size: 1.05rem; text-wrap: pretty; }
@media (max-width: 760px) { .page-title { padding-block: 16px 12px; } .page-title .eyebrow { margin-bottom: 8px; font-size: .66rem; } .page-title .lead { font-size: .94rem; line-height: 1.5; } }
html[lang^="zh"] .page-title .lead { word-break: keep-all; }

/* two columns on a computer; one centred column (max 640px) on a tablet; one column on a phone */
.grid-2 { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; align-items: start; }
@media (min-width: 761px) and (max-width: 899px) { .grid-2 { max-width: 640px; margin-inline: auto; gap: 24px; } }
@media (min-width: 900px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px; } }

/* vertical rhythm: children spaced evenly */
.stack > * + * { margin-top: 16px; }
.stack-sm > * + * { margin-top: 8px; }
.stack-lg > * + * { margin-top: 24px; }

/* the card: white, soft shadow, radius 18px; .card-flat for lists inside a card */
.card { padding: 20px; border: 1px solid var(--line-soft); border-radius: var(--r-lg); background: var(--card); box-shadow: var(--shadow); }
.card-flat { padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); }
@media (min-width: 761px) { .card { padding: 28px; } }
@media (min-width: 900px) { .card { padding: 32px; } }

/* buttons: navy primary, 48px, lifts a little on hover */
.btn, .btn-secondary, .btn-danger { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 48px; padding: 12px 22px; border: 1px solid var(--navy); border-radius: var(--r-sm); background: var(--navy); color: #fff; font-size: 1rem; font-weight: 600; line-height: 1.4; text-align: center; text-decoration: none; cursor: pointer; box-shadow: 0 4px 10px #202c4810; transition: background .35s, translate .35s, box-shadow .35s; }
.btn:hover { background: var(--navy-2); translate: 0 -2px; box-shadow: 0 7px 18px #202c4820; color: #fff; }
.btn:active, .btn-secondary:active, .btn-danger:active { translate: 0 0; }
.btn svg, .btn-secondary svg, .btn-danger svg, .btn-ghost svg { width: 20px; height: 20px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.btn img, .btn-secondary img, .btn-danger img, .btn-ghost img { width: 20px; height: 20px; flex: none; }
/* the white button with a navy border (the second choice) */
.btn-secondary { background: #fff; color: var(--navy); box-shadow: none; }
.btn-secondary:hover { background: var(--wash-blue); color: var(--navy); }
/* the button that deletes or withdraws */
.btn-danger { background: var(--danger); border-color: var(--danger); box-shadow: none; }
.btn-danger:hover { background: #8a2236; border-color: #8a2236; color: #fff; }
/* a text-style button (Not me, Change it): navy words underlined in blue, 44px tall */
.btn-ghost { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; border: 0; background: none; padding: 8px 4px; color: var(--navy); font-size: .94rem; font-weight: 600; cursor: pointer; text-decoration: underline; text-decoration-color: var(--blue); text-decoration-thickness: 1px; text-underline-offset: 6px; }
.btn-ghost:hover { color: var(--link); }
/* sizes: full width; 40px for dense tables on a computer only */
.btn-block { display: flex; width: 100%; }
.btn-sm { min-height: 40px; padding: 8px 14px; font-size: .9rem; gap: 6px; }
.btn-sm svg, .btn-sm img { width: 18px; height: 18px; }
/* disabled: faded, no lift */
.btn:disabled, .btn-secondary:disabled, .btn-danger:disabled, .btn-ghost:disabled { opacity: .6; cursor: default; translate: 0 0; }
.btn:disabled { box-shadow: 0 4px 10px #202c4810; background: var(--navy); }
.btn-secondary:disabled { background: #fff; }
.btn-danger:disabled { background: var(--danger); }
/* a row of buttons that wraps */
.btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* form fields: the label above, a 52px input, a muted hint and an error below */
.field + .field { margin-top: 18px; }
.field > label { display: block; margin: 0 0 8px; font-size: .94rem; font-weight: 600; color: var(--navy); }
.field :where(input:not([type="checkbox"], [type="radio"]), select, textarea) { width: 100%; min-height: 52px; padding: 0 14px; border: 1px solid var(--line); border-radius: var(--r-sm); background: #fff; font-size: 1.05rem; color: var(--navy); }
.field :where(textarea) { min-height: 104px; padding: 12px 14px; line-height: 1.5; resize: vertical; }
.field :where(select) { padding-right: 36px; appearance: none; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2350607a' stroke-width='2'/%3E%3C/svg%3E") no-repeat right 14px center; }
input:hover, select:hover, textarea:hover { border-color: var(--line-hover); }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 3px solid var(--link); outline-offset: 1px; border-color: var(--link); }
.field [aria-invalid="true"] { border-color: var(--danger); }
.hint, .field-note { margin-top: 8px; color: var(--muted); font-size: .88rem; line-height: 1.5; overflow-wrap: anywhere; }
.field-error { margin-top: 6px; color: var(--danger); font-size: .88rem; line-height: 1.5; }
.field-error:empty { display: none; }
html[lang^="zh"] .hint, html[lang^="zh"] .field-note { word-break: keep-all; }
@media (max-width: 760px) { .field > label { margin-bottom: 6px; } .hint, .field-note { margin-top: 6px; font-size: .875rem; } }
/* a form's message under its button */
.error { margin-top: 14px; color: var(--danger); font-size: .94rem; line-height: 1.5; text-align: center; }
.error:empty { display: none; }

/* a tick box row: the whole 44px row is the tap target */
.check { display: flex; align-items: flex-start; gap: 12px; min-height: 44px; padding-block: 10px; cursor: pointer; line-height: 1.5; }
.check input { flex: none; width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--navy); cursor: pointer; }

/* segmented control (ranges, choices): 44px, the chosen one navy; the others outlined at 3:1 */
.seg { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.seg > button, .seg > a { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; min-width: 44px; padding: 0 16px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: #fff; color: var(--navy); font-size: .94rem; font-weight: 600; text-decoration: none; cursor: pointer; }
.seg > :hover { background: var(--wash-blue); color: var(--navy); }
.seg > [aria-pressed="true"], .seg > [aria-selected="true"], .seg > [aria-current="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }

/* underline tabs: navy 3px under the selected one, a count badge; a long row scrolls sideways */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--line); overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs > button, .tabs > a { display: inline-flex; align-items: center; gap: 8px; flex: none; min-height: 48px; padding: 0 14px; border: 0; border-bottom: 3px solid transparent; margin-bottom: -1px; background: none; color: var(--muted); font-size: .96rem; font-weight: 600; text-decoration: none; white-space: nowrap; cursor: pointer; }
.tabs > :hover { color: var(--navy); }
.tabs > [aria-selected="true"], .tabs > [aria-current="page"] { color: var(--navy); border-bottom-color: var(--navy); }
.count { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; height: 22px; padding: 0 7px; border-radius: 999px; background: var(--tint-grey); color: var(--navy); font-size: .82rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.tabs > [aria-selected="true"] .count, .tabs > [aria-current="page"] .count { background: var(--navy); color: #fff; }

/* filter chips: one row that scrolls sideways, never wraps; the chosen one navy */
.chips { display: flex; gap: 8px; overflow-x: auto; padding-block: 2px; scrollbar-width: none; }
.chips::-webkit-scrollbar { display: none; }
.chip { display: inline-flex; align-items: center; gap: 6px; flex: none; min-height: 40px; padding: 0 14px; border: 1px solid var(--line-strong); border-radius: 999px; background: #fff; color: var(--navy); font-size: .9rem; font-weight: 600; white-space: nowrap; text-decoration: none; cursor: pointer; }
.chip:hover { background: var(--wash-blue); color: var(--navy); }
.chip[aria-pressed="true"], .chip[aria-current="true"] { background: var(--navy); border-color: var(--navy); color: #fff; }

/* status tags: a soft tint, dark words (AA) and a dot */
.tag { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: 999px; background: var(--tint-grey); color: var(--muted); font-size: .875rem; font-weight: 600; line-height: 1.4; white-space: nowrap; }
.tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.tag-ok { background: var(--tint-green); color: var(--ok-ink); }
.tag-warn { background: var(--tint-amber); color: var(--amber-ink); }
.tag-bad { background: var(--tint-pink); color: var(--danger); }
.tag-info { background: var(--tint-blue); color: var(--link); }
.tag-muted { background: var(--tint-grey); color: var(--muted); }

/* a small pill label (e.g. 内部) */
.badge { display: inline-flex; align-items: center; padding: 1px 8px; border-radius: 999px; background: var(--tint-grey); color: var(--navy); font-size: .74rem; font-weight: 700; line-height: 1.6; letter-spacing: .02em; white-space: nowrap; vertical-align: middle; }

/* notices: info (blue), warning (amber), bad news (pink); links inside are bold */
.notice { padding: 14px 16px; border-radius: var(--r-sm); background: var(--wash-blue); border: 1px solid var(--wash-blue-line); color: var(--navy); font-size: .94rem; line-height: 1.6; overflow-wrap: anywhere; }
.notice-warn { background: var(--wash-amber); border-color: var(--wash-amber-line); }
.notice-bad { background: var(--wash-pink); border-color: var(--wash-pink-line); }
.notice a { color: var(--link); font-weight: 600; text-decoration: underline; text-decoration-color: var(--blue); text-underline-offset: 4px; }
.notice-bad a { text-decoration-color: var(--pink); }

/* the toast: a short message at the bottom, centred (the page shows it and hides it) */
.toast { position: fixed; left: 50%; bottom: calc(24px + env(safe-area-inset-bottom, 0px)); translate: -50% 0; z-index: 50; max-width: calc(100% - 32px); padding: 12px 18px; border-radius: var(--r-md); background: var(--navy); color: #fff; font-size: .94rem; font-weight: 600; box-shadow: var(--shadow); text-align: center; }

/* the dialog: a centred card over a dark wash; the actions stack full width on phones */
.dialog { width: min(480px, calc(100% - 32px)); max-height: calc(100% - 32px); padding: 24px; border: 1px solid var(--line-soft); border-radius: var(--r-lg); background: var(--card); color: var(--ink); box-shadow: 0 24px 60px #14223d40; }
.dialog::backdrop { background: #14223d70; }
.dialog-title { font-size: 1.3rem; line-height: 1.25; }
.dialog-body { margin-top: 10px; color: var(--muted); line-height: 1.6; overflow-wrap: anywhere; }
.dialog-actions { display: flex; flex-direction: column-reverse; gap: 10px; margin-top: 24px; }
.dialog-actions > * { width: 100%; }
@media (min-width: 761px) { .dialog { padding: 28px; } .dialog-actions { flex-direction: row; justify-content: flex-end; } .dialog-actions > * { width: auto; } }

/* the empty state: an icon disc, one line, an optional action, centred */
.empty { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 32px 16px; text-align: center; color: var(--muted); }
.empty p { max-width: 28em; }

/* the round icon background: 48px (36px small), soft tints */
.icon-disc { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 48px; height: 48px; border-radius: 50%; background: var(--tint-blue); color: var(--navy); }
.icon-disc img, .icon-disc svg { width: 24px; height: 24px; }
.icon-disc-sm { width: 36px; height: 36px; }
.icon-disc-sm img, .icon-disc-sm svg { width: 18px; height: 18px; }
.icon-disc.blue { background: var(--tint-blue); }
.icon-disc.green { background: var(--tint-green); }
.icon-disc.pink { background: var(--tint-pink); }
.icon-disc.amber { background: var(--tint-amber); }
.icon-disc.grey { background: var(--tint-grey); }

/* key and value: stacked on phones, two columns on a computer */
.kv { display: grid; grid-template-columns: minmax(0, 1fr); }
.kv > dt { padding-top: 12px; color: var(--muted); font-size: .88rem; }
.kv > dd { padding-bottom: 12px; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.kv > dd:last-child { border-bottom: 0; }
@media (min-width: 761px) { .kv { grid-template-columns: minmax(9em, max-content) minmax(0, 1fr); column-gap: 24px; } .kv > dt, .kv > dd { padding-block: 12px; border-bottom: 1px solid var(--line); } .kv > dt:nth-last-child(2), .kv > dd:last-child { border-bottom: 0; } }

/* the data table (a computer): sticky header, row hover, numbers right, actions never wrap */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r-md); background: linear-gradient(to right, #fff 30%, #fff0) left / 32px 100% no-repeat local, linear-gradient(to left, #fff 30%, #fff0) right / 32px 100% no-repeat local, radial-gradient(farthest-side at 0 50%, #202c4826, #202c4800) left / 12px 100% no-repeat scroll, radial-gradient(farthest-side at 100% 50%, #202c4826, #202c4800) right / 12px 100% no-repeat scroll, #fff; }
.table { width: 100%; border-collapse: collapse; font-size: .94rem; line-height: 1.45; }
.table th { position: sticky; top: 0; z-index: 1; background: #f3f7fa; color: var(--muted); font-size: .875rem; font-weight: 650; text-align: left; white-space: nowrap; }
.table th, .table td { padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tbody tr:hover { background: #f5f9fc80; }
.table .num { text-align: right; white-space: nowrap; }
.table .actions { white-space: nowrap; text-align: right; }
.table .actions > * + * { margin-left: 6px; }
.table .sub, .list-rows .sub { display: block; margin-top: 2px; color: var(--muted); font-size: .875rem; }

/* phones: each row of a .rows-as-cards table is a card; labels come from data-label */
@media (max-width: 760px) {
  .table-wrap:has(> .rows-as-cards) { overflow: visible; border: 0; border-radius: 0; background: none; }
  .rows-as-cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .rows-as-cards, .rows-as-cards tbody, .rows-as-cards tr, .rows-as-cards td { display: block; width: 100%; }
  .rows-as-cards tr { padding: 6px 16px; border: 1px solid var(--line-soft); border-radius: var(--r-lg); background: var(--card); box-shadow: 0 6px 16px #202c4812; }
  .rows-as-cards tr + tr { margin-top: 12px; }
  .rows-as-cards tbody tr:hover { background: var(--card); }
  .rows-as-cards td, .rows-as-cards tbody tr:last-child td { display: flow-root; padding: 10px 0; border-bottom: 1px solid var(--line); text-align: right; overflow-wrap: anywhere; }
  .rows-as-cards td:last-child, .rows-as-cards tbody tr:last-child td:last-child { border-bottom: 0; }
  .rows-as-cards td[data-label]::before { content: attr(data-label); float: left; max-width: 45%; margin-right: 16px; padding-top: 2px; color: var(--muted); font-size: .875rem; font-weight: 600; text-align: left; }
  .rows-as-cards tbody tr > td.actions { display: flex; flex-wrap: wrap; gap: 8px; padding-block: 12px; white-space: normal; }
  .rows-as-cards td.actions::before { display: none; }
  .rows-as-cards td.actions > * { flex: 1 1 0; min-height: 44px; margin: 0; }
}

/* settings rows with a chevron (/me's Account list), 56px */
.list-rows { list-style: none; padding: 0; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--card); overflow: hidden; }
.list-rows > li + li { border-top: 1px solid var(--line); }
.list-rows > li > a, .list-rows > li > button { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 10px 16px; border: 0; background: none; color: var(--navy); font-size: 1rem; font-weight: 600; text-align: left; text-decoration: none; cursor: pointer; }
.list-rows > li > a::after, .list-rows > li > button::after { content: ""; flex: none; width: 8px; height: 8px; margin-left: auto; border-right: 2px solid var(--muted); border-top: 2px solid var(--muted); rotate: 45deg; }
.list-rows > li > :hover { background: var(--wash-blue); }
.list-rows .list-main { min-width: 0; flex: 1; }
.list-rows .sub { font-weight: 400; }

/* the breadcrumb: muted links, a slash between */
.breadcrumb ol { display: flex; flex-wrap: wrap; align-items: center; list-style: none; padding: 0; color: var(--muted); font-size: .88rem; }
.breadcrumb li + li::before { content: "/"; margin-inline: 8px; color: var(--line-strong); }
.breadcrumb a { display: inline-flex; align-items: center; min-height: 32px; color: var(--muted); }
.breadcrumb a:hover { color: var(--navy); }
.breadcrumb [aria-current="page"] { color: var(--navy); font-weight: 600; }

/* a loading block that shimmers */
.skeleton { display: block; min-height: 1em; border-radius: 8px; background: linear-gradient(90deg, #e8eef4 0%, #f3f7fa 50%, #e8eef4 100%) 0 0 / 200% 100%; animation: shimmer 1.4s linear infinite; }
@keyframes shimmer { to { background-position: -200% 0; } }

/* ---- the app shell (the signed-in pages): a sidebar on a computer, a top bar and a bottom tab bar below 900px ---- */
.app-shell { min-height: 100vh; min-height: 100dvh; }
/* the skip link: off screen until focused */
.app-skip { position: fixed; left: 12px; top: 12px; z-index: 100; padding: 10px 16px; border-radius: 999px; background: var(--navy); color: #fff; font-weight: 600; text-decoration: none; translate: 0 -200%; }
.app-skip:focus-visible { translate: 0 0; }
/* the brand: the logo and the portal's name */
.app-brand { display: flex; align-items: center; gap: 10px; min-width: 0; color: var(--navy); text-decoration: none; }
.app-brand img { display: block; flex: none; width: 40px; height: 40px; object-fit: contain; }
.app-brand-name { font-size: 1.05rem; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
/* the sections: rows with a line icon, the label and a count */
.app-nav { display: flex; flex-direction: column; gap: 2px; }
.app-nav > a, .app-nav > button, .app-side-row { position: relative; display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; padding: 10px 12px; border: 0; border-radius: var(--r-sm); background: none; color: var(--muted); font-size: 1rem; font-weight: 600; line-height: 1.3; text-align: left; text-decoration: none; cursor: pointer; transition: background-color .15s ease-out, color .15s ease-out; }
.app-nav > :hover, .app-side-row:hover { background: var(--nav-hover); color: var(--navy); }
.app-nav svg, .app-side-row svg, .app-icon-btn svg { flex: none; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.app-nav-label { min-width: 0; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.app-nav > [aria-current="page"] { background: var(--tint-navy); color: var(--navy); font-weight: 700; }
.app-nav .count { font-size: .875rem; }
.app-nav > [aria-current="page"] .count { background: var(--navy); color: #fff; }
/* the sidebar's foot: who is signed in, then rows (account, sign out) */
.app-side-end { display: flex; flex-direction: column; gap: 2px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); }
.app-who { padding: 4px 12px 8px; color: var(--navy); font-size: .94rem; font-weight: 600; overflow-wrap: anywhere; }
.app-who .sub { display: block; color: var(--muted); font-size: .875rem; font-weight: 400; }
/* a 44px icon button */
.app-icon-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 44px; min-height: 44px; padding: 0 10px; border: 1px solid var(--line-strong); border-radius: var(--r-sm); background: #fff; color: var(--navy); font-size: .94rem; font-weight: 600; text-decoration: none; cursor: pointer; }
.app-icon-btn:hover { background: var(--wash-blue); }
/* the content column and a section's title row */
.app-main { display: flex; flex-direction: column; min-width: 0; min-height: 100vh; min-height: 100dvh; }
.app-main:focus { outline: none; }
.app-content { flex: 1 0 auto; width: 100%; max-width: 1120px; margin-inline: auto; padding: 32px 40px 48px; }
.app-section > * + * { margin-top: 24px; }
.app-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 24px; }
.app-head-text { min-width: 0; flex: 1 1 20rem; }
.app-head-text > .breadcrumb { margin-bottom: 4px; }
.app-title { font-size: 1.75rem; line-height: 1.2; letter-spacing: -.02em; text-wrap: balance; }
html[lang^="zh"] .app-title { letter-spacing: 0; }
.app-title:focus, .app-section:focus { outline: none; }
.app-lead { margin-top: 6px; max-width: 65ch; color: var(--muted); line-height: 1.6; text-wrap: pretty; }
html[lang^="zh"] .app-lead { word-break: keep-all; }
.app-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

/* a computer: the sidebar on the left (sticky, scrolls on its own), the content on the right; no top bar */
@media (min-width: 900px) {
  .app-shell { display: grid; grid-template-columns: var(--side-w) minmax(0, 1fr); grid-template-areas: "side main"; }
  .app-top { display: none; }
  .app-side { grid-area: side; position: sticky; top: 0; z-index: 20; display: flex; flex-direction: column; gap: 24px; height: 100vh; height: 100dvh; padding: 20px 12px 16px; overflow-y: auto; border-right: 1px solid var(--line); background: #fff; }
  .app-side > .app-brand { padding: 0 8px; }
  .app-main { grid-area: main; }
  /* the top bar's language picker stays: at the top right of the content (its right edge, 40px in), on the title
     row's line; the title row, what comes before it in a section and a failed-load line keep 104px clear of it */
  .app-top:has(.language-picker) { display: contents; }
  .app-top:has(.language-picker) > :not(.app-top-end), .app-top-end > :not(.language-picker) { display: none; }
  .app-top-end:has(.language-picker) { grid-area: main; justify-self: end; align-self: start; position: relative; z-index: 25; display: flex; margin: 27px max(40px, calc((100% - 1120px) / 2 + 40px)) 0 0; }
  .app-shell:has(.app-top-end .language-picker) :is(.app-head, .app-section > :first-child, .app-content > .load-error) { margin-right: 104px; }
}
/* below 900px (phones and tablets): the top bar, the content, the tab bar fixed at the bottom */
@media (max-width: 899px) {
  .app-top { position: sticky; top: 0; z-index: 30; display: flex; align-items: center; gap: 12px; min-height: calc(var(--top-h) + env(safe-area-inset-top, 0px)); padding: env(safe-area-inset-top, 0px) 16px 0; border-bottom: 1px solid var(--line); background: #fff; }
  .app-top .app-brand img { width: 32px; height: 32px; }
  .app-top-title { min-width: 0; flex: 1; font-size: 1.1rem; font-weight: 700; color: var(--navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .app-top-end { display: flex; align-items: center; gap: 8px; margin-left: auto; }
  .app-side { position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; padding: 0 4px env(safe-area-inset-bottom, 0px); border-top: 1px solid var(--line); background: #fff; box-shadow: 0 -4px 16px #202c480d; }
  .app-side > .app-brand, .app-side-end { display: none; }
  .app-nav { flex-direction: row; gap: 0; height: var(--tabbar-h); max-width: 640px; margin-inline: auto; }
  .app-nav > a, .app-nav > button { flex: 1 1 0; flex-direction: column; justify-content: center; gap: 2px; min-width: 0; min-height: 44px; padding: 6px 2px; border-radius: 0; background: none; font-size: .875rem; line-height: 1.2; text-align: center; }
  .app-nav > :hover, .app-nav > [aria-current="page"] { background: none; }
  .app-nav svg { box-sizing: content-box; width: 24px; height: 24px; padding: 3px 16px; border-radius: 999px; transition: background-color .15s ease-out; }
  .app-nav > [aria-current="page"] svg { background: var(--tint-navy); }
  .app-nav-label { flex: none; max-width: 100%; }
  .app-nav .count { position: absolute; top: 2px; left: calc(50% + 8px); min-width: 20px; height: 20px; padding: 0 5px; }
  .app-main { min-height: calc(100vh - var(--top-h)); min-height: calc(100dvh - var(--top-h) - env(safe-area-inset-top, 0px)); }
  .app-content { padding: 16px 16px calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 32px); }
  .app-content:has(+ .site-footer) { padding-bottom: 32px; }
  .app-main > .site-footer { padding-bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px)); }
  .app-head:not(.app-head-sub) .app-title { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .app-head:not(.app-head-sub) .app-lead { margin-top: 0; }
  .app-title { font-size: 1.4rem; }
  .app-shell .toast { bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 16px); }
  /* typing: the keyboard is up, the tab bar steps aside */
  .app-shell:has(:is(input:not([type="checkbox"], [type="radio"], [type="button"], [type="submit"]), textarea):focus) .app-side { display: none; }
}
@media (min-width: 761px) and (max-width: 899px) { .app-content { padding-inline: 24px; } }
@media print { .app-top, .app-side, .app-skip { display: none !important; } .app-shell { display: block; } .app-content { padding: 0; } }

/* less motion: no lifts, no shimmer, no slides */
@media (prefers-reduced-motion: reduce) {
  .btn, .btn-secondary, .btn-danger { transition: none; }
  .btn:hover { translate: 0 0; }
  .skeleton { animation: none; }
  .app-nav > a, .app-nav > button, .app-side-row, .app-nav svg { transition: none; }
  .language-picker > summary, .language-picker > summary::after { transition: none; }
}
