/* Hong Kong Salaries Tax Calculator — single stylesheet, no framework. */

:root {
  --ink: #16211c;
  --ink-soft: #5a6b62;
  --line: #d8e0da;
  --bg: #f6f8f6;
  --card: #ffffff;
  --accent: #0b6b4f;
  --accent-soft: #e6f2ec;
  --warn: #8a5200;
  --warn-soft: #fdf3e0;
  --bad: #a52218;
  --bad-soft: #fdeceb;
  --good: #1c6b3c;
  --radius: 10px;
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #e8efea;
    --ink-soft: #9fb2a8;
    --line: #2c3a33;
    --bg: #121815;
    --card: #1a221e;
    --accent: #4cc79b;
    --accent-soft: #16302a;
    --warn: #f0bf6a;
    --warn-soft: #2e2415;
    --bad: #f08a80;
    --bad-soft: #33191a;
    --good: #6bd39b;
  }
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  font: 16px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  color: var(--ink);
  background: var(--bg);
}

.wrap {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 20px;
}

main {
  padding: 26px 20px 40px;
}

section {
  margin: 0 0 38px;
}

h2 {
  font-size: 1.2rem;
  margin: 0 0 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}

h3 {
  font-size: 1rem;
  margin: 22px 0 10px;
}

.lede,
.hint {
  color: var(--ink-soft);
  font-size: 0.92rem;
  max-width: 70ch;
}

.hint {
  margin: 0 0 12px;
}

/* ---------------------------------------------------------------- intake */
.dropzone {
  border: 2px dashed var(--line);
  border-radius: var(--radius);
  background: var(--card);
  padding: 34px 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.dropzone:hover,
.dropzone:focus-visible,
.dropzone.dragover {
  border-color: var(--accent);
  background: var(--accent-soft);
  outline: none;
}

.dropzone-main {
  margin: 0 0 4px;
  font-weight: 600;
}

.dropzone-sub {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.9rem;
}

.linkbtn {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

.status {
  min-height: 1.4em;
  font-size: 0.9rem;
  color: var(--ink-soft);
}

.status.error {
  color: var(--bad);
}

.notice-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

.notice-list button {
  width: 100%;
  text-align: left;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 14px;
  font: inherit;
  color: inherit;
  cursor: pointer;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 14px;
  align-items: baseline;
}

.notice-list button:hover {
  border-color: var(--accent);
}

.notice-list button[aria-current="true"] {
  border-color: var(--accent);
  box-shadow: inset 3px 0 0 var(--accent);
}

.notice-list .nl-year {
  font-weight: 650;
}

.notice-list .nl-meta {
  color: var(--ink-soft);
  font-size: 0.86rem;
}

.notice-list .nl-bad {
  color: var(--bad);
  font-size: 0.86rem;
}

/* ---------------------------------------------------------------- meta */
.metagrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 10px;
  margin-bottom: 14px;
}

.metagrid div {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 9px 12px;
}

.metagrid dt,
.metagrid .k {
  display: block;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}

.metagrid .v {
  font-weight: 600;
  word-break: break-word;
}

/* ---------------------------------------------------------------- tables */
.tablewrap {
  overflow-x: auto;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}

table {
  border-collapse: collapse;
  width: 100%;
  font-size: 0.92rem;
}

th,
td {
  padding: 8px 12px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}

thead th {
  background: var(--accent-soft);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

tbody tr:last-child td {
  border-bottom: none;
}

td.num,
th.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--mono);
}

tr.emphasis td {
  font-weight: 700;
  background: var(--accent-soft);
}

tr.indent td:first-child {
  padding-left: 28px;
  color: var(--ink-soft);
}

tr.rule td {
  border-top: 2px solid var(--line);
}

.ok {
  color: var(--good);
  font-weight: 600;
}

.mismatch {
  color: var(--bad);
  font-weight: 600;
}

/* ---------------------------------------------------------------- forms */
.controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin-bottom: 14px;
}

.ctrl {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.82rem;
  color: var(--ink-soft);
}

.ctrl abbr {
  cursor: help;
  border: 1px solid var(--line);
  border-radius: 50%;
  padding: 0 4px;
  text-decoration: none;
  font-size: 0.7rem;
}

select,
input[type="number"] {
  font: inherit;
  font-size: 0.95rem;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 7px 9px;
  min-width: 150px;
}

select:focus-visible,
input:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

button.secondary {
  font: inherit;
  font-size: 0.9rem;
  background: var(--card);
  color: var(--ink);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 14px;
  cursor: pointer;
}

button.secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 14px;
  margin-bottom: 14px;
}

.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px 16px;
}

.card h3:first-child {
  margin-top: 0;
}

.field {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  padding: 5px 0;
  border-bottom: 1px dotted var(--line);
}

.field:last-child {
  border-bottom: none;
}

.field label {
  font-size: 0.9rem;
  flex: 1 1 auto;
}

.field input {
  flex: 0 0 130px;
  min-width: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-family: var(--mono);
}

.field.count input {
  flex: 0 0 78px;
}

.field.check {
  justify-content: flex-start;
}

.field.check input {
  flex: 0 0 auto;
  order: -1;
}

.subtotal {
  margin: 12px 0 0;
  padding-top: 10px;
  border-top: 2px solid var(--line);
  display: flex;
  justify-content: space-between;
  font-size: 0.92rem;
}

.subtotal strong {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- result */
.card.result {
  border-color: var(--accent);
}

.bignum {
  font-size: 2rem;
  font-weight: 700;
  font-family: var(--mono);
  letter-spacing: -0.02em;
  margin: 4px 0 2px;
}

.bignum-label {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}

.kv {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 0;
  font-size: 0.92rem;
  border-bottom: 1px dotted var(--line);
}

.kv:last-child {
  border-bottom: none;
}

.kv span:last-child {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}

.badge {
  display: inline-block;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--accent-soft);
  color: var(--accent);
  font-weight: 650;
}

.badge.chosen {
  background: var(--accent);
  color: var(--card);
}

/* ---------------------------------------------------------------- notes */
.callout,
.msg {
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 0 0 12px;
  font-size: 0.9rem;
  border-left: 3px solid;
}

.msg ul,
.callout ul {
  margin: 6px 0 0;
  padding-left: 20px;
}

.msg.warn,
.callout {
  background: var(--warn-soft);
  border-color: var(--warn);
  color: var(--warn);
}

.msg.error {
  background: var(--bad-soft);
  border-color: var(--bad);
  color: var(--bad);
}

.msg.info {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--accent);
}

.notes,
.caveats {
  font-size: 0.9rem;
  color: var(--ink-soft);
  max-width: 78ch;
}

.caveats {
  list-style: none;
  padding: 0;
  display: grid;
  gap: 8px;
}

.caveats strong {
  color: var(--ink);
}

details summary {
  cursor: pointer;
  font-size: 0.92rem;
  padding: 6px 0;
}

a {
  color: var(--accent);
}

footer {
  padding: 18px 20px 30px;
  color: var(--ink-soft);
  font-size: 0.85rem;
  border-top: 1px solid var(--line);
}

@media (max-width: 560px) {
  .field {
    flex-wrap: wrap;
  }
  .bignum {
    font-size: 1.6rem;
  }
}

/* ------------------------------------------------------- language switcher */
.topline {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}

.topline h1 {
  margin-bottom: 6px;
}

.langswitch select {
  min-width: 0;
  padding: 5px 8px;
  font-size: 0.88rem;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.basis-h {
  margin: 14px 0 4px;
  font-size: 0.9rem;
}

.basis-sub {
  margin: 0 0 6px;
}

#source-list code {
  font-family: var(--mono);
  font-size: 0.8rem;
  opacity: 0.75;
}

/*
 * Chinese needs a slightly looser line height than Latin text at the same size,
 * and the CJK stack has to come first or the Latin faces above supply their own
 * fallback glyphs, which look thin and mismatched next to Han characters.
 */
html[lang^='zh'] body {
  font-family: "PingFang HK", "PingFang TC", "Hiragino Sans CJK TC", "Noto Sans CJK TC",
    "Microsoft JhengHei", system-ui, sans-serif;
  line-height: 1.7;
}

/* Chinese labels run longer, so give them room before the input. */
html[lang^='zh'] .field label {
  padding-right: 6px;
}

/* =========================================================== landing page */

/*
 * Sticky nav. Kept slim so the drop target is visible without scrolling on a
 * laptop, since the drop target is the call to action.
 */
.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--card) 88%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border-bottom: 1px solid var(--line);
}

.navinner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 54px;
  flex-wrap: wrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  text-decoration: none;
  color: var(--ink);
  font-weight: 650;
  font-size: 0.95rem;
}

.brand-mark {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--accent);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 750;
  letter-spacing: 0.02em;
}

.navlinks {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.navlinks a {
  color: var(--ink-soft);
  text-decoration: none;
  font-size: 0.9rem;
}

.navlinks a:hover {
  color: var(--accent);
}

/* ------------------------------------------------------------------- hero */
.hero {
  background:
    radial-gradient(1000px 340px at 50% -140px, var(--accent-soft), transparent 70%),
    var(--bg);
  padding: 52px 0 34px;
  text-align: center;
  border-bottom: 1px solid var(--line);
}

.hero.compact {
  padding: 38px 0 24px;
  text-align: left;
}

.hero-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 16px;
  padding: 4px 12px;
  border: 1px solid var(--accent);
  border-radius: 20px;
  background: var(--card);
  color: var(--accent);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.02em;
}

.hero-h1 {
  margin: 0 auto 14px;
  max-width: 22ch;
  font-size: clamp(1.85rem, 4.6vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.022em;
  font-weight: 750;
}

.hero.compact .hero-h1 {
  max-width: none;
  font-size: clamp(1.6rem, 3.4vw, 2.2rem);
}

/* The second clause is the whole pitch, so it gets the accent. */
.hero-h1-em {
  display: block;
  color: var(--accent);
}

.hero-sub {
  margin: 0 auto 26px;
  max-width: 58ch;
  font-size: 1.03rem;
  color: var(--ink-soft);
}

.hero.compact .hero-sub {
  margin-left: 0;
}

.hero .dropzone {
  max-width: 620px;
  margin: 0 auto;
  box-shadow: 0 1px 2px rgb(0 0 0 / 4%), 0 12px 28px -18px rgb(0 0 0 / 30%);
}

.dropzone-constraints {
  margin: 10px 0 0;
  font-size: 0.78rem;
  color: var(--ink-soft);
  letter-spacing: 0.01em;
}

.hero .status {
  margin: 12px 0 0;
}

.chips {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin: 22px 0 0;
  padding: 0;
}

.chips li {
  padding: 4px 11px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: var(--card);
  font-size: 0.8rem;
  color: var(--ink-soft);
}

/* Tick prefix, decorative only — the text already carries the meaning. */
.chips li::before {
  content: "✓";
  color: var(--accent);
  font-weight: 700;
  margin-right: 6px;
}

/* -------------------------------------------------------------- 3 steps */
.steps {
  list-style: none;
  counter-reset: step;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 14px;
  margin: 0;
  padding: 0;
}

.steps li {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 34px 16px 16px;
  font-size: 0.92rem;
  color: var(--ink-soft);
}

.steps strong {
  display: block;
  color: var(--ink);
  margin-bottom: 4px;
  font-size: 0.97rem;
}

.step-n {
  position: absolute;
  top: 14px;
  left: 16px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 750;
}

/* -------------------------------------------------------- privacy block */
.privacy-block {
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  padding: 22px 24px 20px;
}

.privacy-block h2 {
  border-bottom-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

.checks {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: grid;
  gap: 12px;
}

.checks li {
  position: relative;
  padding-left: 30px;
  font-size: 0.93rem;
  color: var(--ink-soft);
  max-width: 84ch;
}

.checks li::before {
  content: "→";
  position: absolute;
  left: 4px;
  top: 0;
  color: var(--accent);
  font-weight: 700;
}

.checks strong {
  color: var(--ink);
}

.privacy-why {
  margin: 0;
  padding-top: 14px;
  border-top: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  font-size: 0.92rem;
  color: var(--ink-soft);
  max-width: 84ch;
}

.cols.three {
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}

.cols.three .card p {
  margin: 0;
  font-size: 0.91rem;
  color: var(--ink-soft);
}

/* ------------------------------------------------------------------- faq */
.faq {
  display: grid;
  gap: 8px;
}

.faq details {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 0 14px;
}

.faq summary {
  padding: 12px 0;
  font-weight: 600;
  font-size: 0.95rem;
}

.faq details[open] summary {
  border-bottom: 1px solid var(--line);
}

.faq p {
  margin: 12px 0;
  font-size: 0.92rem;
  color: var(--ink-soft);
  max-width: 82ch;
}

/* ------------------------------------------------------- footer + strip */
.strip {
  margin-top: 38px;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--bg);
  text-align: center;
  font-size: 0.85rem;
  letter-spacing: 0.01em;
}

.strip .lock,
.hero-badge .lock {
  margin-right: 4px;
}

.footer {
  padding: 20px 20px 34px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  justify-content: space-between;
  align-items: baseline;
  color: var(--ink-soft);
  font-size: 0.85rem;
  border-top: none;
}

.footer-meta {
  display: flex;
  gap: 14px;
  margin: 0;
}

/* --------------------------------------------------------- release notes */
.releases {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 16px;
}

.release {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 18px 18px;
}

.rel-head {
  display: flex;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
  border-bottom: 1px solid var(--line);
  padding-bottom: 8px;
  margin-bottom: 10px;
}

.rel-ver {
  margin: 0;
  font-size: 1.15rem;
  font-family: var(--mono);
  border: none;
  padding: 0;
}

.rel-date {
  color: var(--ink-soft);
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
}

.rel-summary {
  margin: 0 0 14px;
  font-size: 0.95rem;
  color: var(--ink-soft);
  max-width: 80ch;
}

.rel-group {
  margin-bottom: 12px;
}

.rel-group ul {
  margin: 8px 0 0;
  padding-left: 22px;
  font-size: 0.92rem;
  color: var(--ink-soft);
  max-width: 84ch;
}

.rel-group li {
  margin-bottom: 5px;
}

.tag {
  display: inline-block;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 700;
  padding: 2px 9px;
  border-radius: 20px;
}

.tag-added {
  background: var(--accent-soft);
  color: var(--accent);
}

.tag-changed {
  background: var(--warn-soft);
  color: var(--warn);
}

.tag-fixed {
  background: var(--bad-soft);
  color: var(--bad);
}

.backlink {
  margin: 24px 0 0;
  font-size: 0.9rem;
}

@media (max-width: 620px) {
  .navlinks {
    gap: 12px;
    font-size: 0.85rem;
  }
  .hero {
    padding: 34px 0 26px;
  }
  .privacy-block {
    padding: 18px 16px 16px;
  }
}

/*
 * The public tally. Understated on purpose: it is context, not a boast, and it
 * sits beneath a claim about privacy that it must not appear to contradict.
 */
.hero-counter {
  margin: 16px 0 0;
  font-size: 0.86rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/*
 * The nav is sticky, so anything scrolled to by script or by a #fragment would
 * otherwise come to rest underneath it. Reserving the nav's height plus a little
 * air puts the heading where a reader expects to find it.
 */
#notice,
#calc,
#how,
#privacy,
#faq,
#about {
  scroll-margin-top: 74px;
}

/* The drop zone is the nav's Calculator target, so it needs the same clearance
   plus a little more: it reads as a control and looks truncated if the nav
   overlaps its top edge. */
#dropzone {
  scroll-margin-top: 90px;
}

/* The heading receives focus when the detail is revealed, so that assistive
   technology follows the jump. It is not interactive, so the focus ring would
   read as a control; the surrounding motion already signals the move. */
#notice-h:focus {
  outline: none;
}

/* The sentence that reconciles the two dropdowns. Tinted when the year has been
   changed, so a what-if is visibly distinct from a straight verification. */
.basis-line {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-left: 3px solid var(--line);
  background: var(--card);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 0.9rem;
  color: var(--ink-soft);
  max-width: 78ch;
}

.basis-line.basis-whatif {
  border-left-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
}

/*
 * A figure that just moved.
 *
 * Changing the year of assessment alters the allowances, the net chargeable
 * income and the tax, but leaves the notice's own figures alone — so without a
 * cue the screen looks inert. Bold accent plus a fading tint marks what actually
 * changed, and fades so the colour never becomes permanent decoration.
 */
.value-changed {
  color: var(--accent);
  font-weight: 700;
  animation: value-flash 2.2s ease-out;
  border-radius: 4px;
}

.value-changed strong {
  color: var(--accent);
}

@keyframes value-flash {
  0% {
    background: var(--accent);
    color: var(--card);
    box-shadow: 0 0 0 3px var(--accent);
  }
  18% {
    background: var(--accent-soft);
    color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
  }
  100% {
    background: transparent;
    color: var(--accent);
    box-shadow: 0 0 0 3px transparent;
  }
}

/* Movement is the cue for most readers, but it must not be the only one, and it
   must not move at all for anyone who has asked it not to. The colour and weight
   carry the meaning on their own. */
@media (prefers-reduced-motion: reduce) {
  .value-changed {
    animation: none;
    background: var(--accent-soft);
  }
}

/*
 * A difference the user asked for, as opposed to one that means something is
 * wrong. Red is reserved for a reading that disagrees with the notice; an edit
 * or a deliberate change of year is amber, because it is information rather than
 * a fault.
 */
.expected-diff {
  color: var(--warn);
  font-weight: 600;
}

.hint-edited {
  padding: 8px 12px;
  border-left: 3px solid var(--warn);
  background: var(--warn-soft);
  color: var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* Says what just happened when selecting another column of the notice reset the
   form. Transient: it reports an event, not a state. */
.calc-note {
  margin: 0 0 12px;
  padding: 8px 12px;
  border-left: 3px solid var(--warn);
  background: var(--warn-soft);
  color: var(--warn);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 0.9rem;
  max-width: 78ch;
}

/* ====================================================== section jumper */

/*
 * Fixed to the right edge, vertically centred. It sits outside the 1040px
 * content column, so it needs enough window to live in: below 1200px there is no
 * such gutter and it would cover the tables, hence the media query at the end.
 */
.section-nav {
  position: fixed;
  right: 18px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 15;
}

.section-nav ul {
  list-style: none;
  margin: 0;
  padding: 8px 10px;
  display: grid;
  gap: 2px;
  background: color-mix(in srgb, var(--card) 86%, transparent);
  backdrop-filter: saturate(140%) blur(10px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: 0 10px 30px -22px rgb(0 0 0 / 45%);
}

.section-nav a {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 6px;
  border-radius: 7px;
  text-decoration: none;
  color: var(--ink-soft);
  font-size: 0.82rem;
  line-height: 1.25;
  white-space: nowrap;
  transition: color 0.15s, background 0.15s;
}

.section-nav a:hover {
  color: var(--accent);
  background: var(--accent-soft);
}

.sn-dot {
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  opacity: 0.55;
  transition: opacity 0.15s, background 0.15s;
}

/*
 * The section the reader is in. Weight and a filled dot carry it as well as
 * colour, so it survives a colour-blind reader and a greyscale print.
 */
.section-nav a.is-current {
  color: var(--accent);
  font-weight: 650;
}

.section-nav a.is-current .sn-dot {
  background: var(--accent);
  opacity: 1;
}

/* Chinese labels are shorter but taller; give the rows a little more air. */
html[lang^='zh'] .section-nav a {
  padding: 6px 6px;
}

/*
 * No gutter to sit in on a narrow window, and on a touch screen a fixed rail
 * competes with the content for both space and taps. The top nav already covers
 * the same ground.
 */
@media (max-width: 1200px) {
  .section-nav {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .section-nav a,
  .sn-dot {
    transition: none;
  }
}
