/* ==========================================================================
   All-in-One Calculator Hub — core stylesheet
   Shell, tokens, layout and components shared by every page.
   Category accents live in themes.css.
   ========================================================================== */

/* ---------- Self-hosted fonts (rule 11 — no Google CDN) ------------------ */
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-400.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/inter-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('../fonts/outfit-500.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('../fonts/outfit-600.woff2') format('woff2');
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Outfit';
  src: url('../fonts/outfit-700.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ---------- Tokens ------------------------------------------------------- */
:root {
  /* Shell — light. Every value below verified >= 4.5:1 where it carries text. */
  --bg:          #FAF9F7;
  --surface:     #FFFFFF;
  --surface-2:   #F2F0EC;
  --border:      #E3DFD8;
  --border-firm: #CFC9BF;
  --text:        #1A1A1B;
  --text-muted:  #5C5952;
  --accent:      #2B50AA;   /* hub ink blue — overridden per category */
  --accent-soft: #EEF1FA;
  --accent-on:   #FFFFFF;
  --shadow:      0 1px 2px rgba(26,26,27,.05), 0 4px 16px rgba(26,26,27,.05);
  --shadow-lift: 0 2px 4px rgba(26,26,27,.06), 0 12px 28px rgba(26,26,27,.10);

  /* Type */
  --font-display: 'Outfit', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-body:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --step--1: clamp(.8125rem, .79rem + .11vw, .875rem);
  --step-0:  clamp(1rem, .97rem + .14vw, 1.0625rem);
  --step-1:  clamp(1.15rem, 1.09rem + .3vw, 1.35rem);
  --step-2:  clamp(1.4rem, 1.28rem + .6vw, 1.8rem);
  --step-3:  clamp(1.75rem, 1.5rem + 1.2vw, 2.5rem);
  --step-4:  clamp(2.1rem, 1.6rem + 2.4vw, 3.4rem);

  /* Space */
  --sp-1: .25rem; --sp-2: .5rem;  --sp-3: .75rem; --sp-4: 1rem;
  --sp-5: 1.5rem; --sp-6: 2rem;   --sp-7: 3rem;   --sp-8: 4rem;
  --radius:    10px;
  --radius-lg: 16px;
  --wrap: 72rem;

  /* ── Motion tokens — transitions.dev shared scale ───────────────── */
  --duration-stagger: 40ms;
  --duration-micro: 80ms;
  --duration-quick: 150ms;
  --duration-fast: 250ms;
  --duration-medium: 350ms;
  --duration-slow: 400ms;
  --duration-very-slow: 500ms;
  --ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: ease-in-out;
  --ease-out: ease-out;
  --ease-linear: linear;
  --ease-bounce: cubic-bezier(0.34, 1.36, 0.64, 1);
  --distance-micro: 4px;
  --distance-base: 8px;
  --distance-medium: 12px;
  --scale-medium: 0.97;
  --blur-small: 2px;
  --blur-medium: 3px;
  /* Number pop-in */
  --digit-dur: 500ms;
  --digit-distance: 8px;
  --digit-stagger: 70ms;
  --digit-blur: 2px;
  --digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
  --digit-dir-x: 0;
  --digit-dir-y: 1;
  /* Texts reveal */
  --stagger-dur: 500ms;
  --stagger-distance: 12px;
  --stagger-stagger: 40ms;
  --stagger-blur: 3px;
  --stagger-ease: cubic-bezier(0.22, 1, 0.36, 1);
  /* Accordion expand */
  --acc-expand: 250ms;
  --acc-collapse: 250ms;
  --acc-chevron: 250ms;
  --acc-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

html[data-theme='dark'] {
  --bg:          #141412;
  --surface:     #1D1C1A;
  --surface-2:   #262421;
  --border:      #33302B;
  --border-firm: #47433C;
  --text:        #F5F3EF;
  --text-muted:  #A8A29A;
  --accent:      #8FA9E8;
  --accent-soft: #22293C;
  --accent-on:   #141412;
  --shadow:      0 1px 2px rgba(0,0,0,.4), 0 4px 16px rgba(0,0,0,.3);
  --shadow-lift: 0 2px 4px rgba(0,0,0,.45), 0 12px 28px rgba(0,0,0,.45);
  color-scheme: dark;
}

/* ---------- Reset -------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
img, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: .18em; }
h1, h2, h3, h4 { font-family: var(--font-display); line-height: 1.18; font-weight: 600; letter-spacing: -.015em; }
h1 { font-size: var(--step-4); font-weight: 700; letter-spacing: -.025em; }
h2 { font-size: var(--step-3); }
h3 { font-size: var(--step-1); }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ---------- Layout ------------------------------------------------------- */
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--sp-4); }
@media (min-width: 48rem) { .wrap { padding-inline: var(--sp-5); } }
main { flex: 1 0 auto; }
.section { padding-block: var(--sp-7); }
.section-head { margin-bottom: var(--sp-5); }
.section-head p { color: var(--text-muted); max-width: 58ch; margin-top: var(--sp-2); }
.eyebrow {
  font-family: var(--font-display);
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent);
}
.skip-link {
  position: absolute; left: var(--sp-4); top: -4rem; z-index: 100;
  background: var(--accent); color: var(--accent-on);
  padding: var(--sp-2) var(--sp-4); border-radius: var(--radius);
  transition: top var(--duration-quick) var(--ease-smooth-out);
}
.skip-link:focus { top: var(--sp-4); }

/* ---------- Header ------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(10px);
  border-bottom: 1px solid var(--border);
}
@supports not (backdrop-filter: blur(1px)) { .site-header { background: var(--bg); } }
.header-bar {
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 3.75rem;
}
.logo {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--font-display); font-weight: 700; font-size: 1.25rem;
  letter-spacing: -.02em; color: var(--text); text-decoration: none;
  white-space: nowrap; flex-shrink: 0;
}
.logo-mark { width: 2.1rem; height: 2.1rem; flex-shrink: 0; }
.logo-mark rect { fill: var(--accent); }
.logo-mark path { stroke: var(--accent-on); }
.logo b { color: var(--accent); font-weight: 700; }

.nav-toggle, .theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem; flex-shrink: 0;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  color: var(--text-muted); cursor: pointer;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.nav-toggle:hover, .theme-toggle:hover { background: var(--surface-2); color: var(--text); }
.theme-toggle { margin-left: auto; }
.theme-toggle .icon-sun { display: none; }
html[data-theme='dark'] .theme-toggle .icon-sun { display: block; }
html[data-theme='dark'] .theme-toggle .icon-moon { display: none; }

.main-nav ul { list-style: none; padding: 0; display: flex; gap: var(--sp-1); flex-wrap: wrap; }
.main-nav a {
  display: block; padding: var(--sp-2) var(--sp-3);
  font-size: var(--step--1); font-weight: 500;
  color: var(--text-muted); text-decoration: none; border-radius: var(--radius);
  position: relative;
  transition: color var(--duration-quick) var(--ease-smooth-out),
              background var(--duration-quick) var(--ease-smooth-out);
}
.main-nav a:hover, .main-nav a[aria-current='page'] { color: var(--text); background: var(--surface-2); }

/* Mobile: nav collapses behind a button */
@media (max-width: 63.99rem) {
  .main-nav {
    display: none; width: 100%;
    padding-bottom: var(--sp-3); border-top: 1px solid var(--border); padding-top: var(--sp-3);
  }
  .main-nav.is-open { display: block; }
  .main-nav ul { flex-direction: column; gap: 0; }
  .main-nav a { padding: var(--sp-3); }
  .header-bar { flex-wrap: wrap; }
}
@media (min-width: 64rem) {
  .nav-toggle { display: none; }
  .main-nav { order: 3; }
  /* Tighter side padding so all eight nav items (incl. Blog) fit in two rows */
  .main-nav .nav-trigger, .main-nav > ul > li > a { padding-left: .55rem; padding-right: .55rem; }
}

/* ---------- Search ------------------------------------------------------- */
.search {
  position: relative; flex: 1 1 auto; min-width: 0; max-width: 26rem;
}
.search-input {
  width: 100%; padding: .6rem .75rem .6rem 2.25rem;
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border-firm); border-radius: var(--radius);
  font-size: var(--step--1);
  transition: border-color var(--duration-quick) var(--ease-smooth-out),
              box-shadow var(--duration-quick) var(--ease-smooth-out);
}
.search-input::placeholder { color: var(--text-muted); }
.search-input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.search-icon {
  position: absolute; left: .7rem; top: 50%; transform: translateY(-50%);
  width: 1rem; height: 1rem; color: var(--text-muted); pointer-events: none;
}
.search-results {
  position: absolute; top: calc(100% + .4rem); left: 0; right: 0; z-index: 60;
  background: var(--surface); border: 1px solid var(--border-firm);
  border-radius: var(--radius); box-shadow: var(--shadow-lift);
  max-height: min(24rem, 60vh); overflow-y: auto;
  list-style: none; padding: var(--sp-1); margin: 0;
}
.search-results:empty, .search-results[hidden] { display: none; }
.search-results a {
  display: flex; justify-content: space-between; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: 6px;
  color: var(--text); text-decoration: none; font-size: var(--step--1);
}
.search-results a:hover, .search-results a:focus-visible,
.search-results li.is-active a { background: var(--surface-2); }
.search-results .r-cat {
  font-size: .75rem; color: var(--text-muted); white-space: nowrap; flex-shrink: 0;
}
.search-empty { padding: var(--sp-3); color: var(--text-muted); font-size: var(--step--1); }

/* ---------- Breadcrumb --------------------------------------------------- */
.breadcrumb { padding-top: var(--sp-4); font-size: var(--step--1); }
.breadcrumb ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; }
.breadcrumb li { display: flex; align-items: center; gap: .35rem; color: var(--text-muted); }
.breadcrumb li + li::before { content: '/'; color: var(--border-firm); }
.breadcrumb a { color: var(--text-muted); text-decoration: none; }
.breadcrumb a:hover { color: var(--accent); text-decoration: underline; }
.breadcrumb [aria-current='page'] { color: var(--text); }

/* ---------- Hero --------------------------------------------------------- */
.hero { padding-block: var(--sp-7) var(--sp-6); position: relative; overflow: hidden; }
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(60rem 24rem at 12% -12%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 62%),
    radial-gradient(44rem 22rem at 92% 6%, color-mix(in srgb, var(--accent) 8%, transparent), transparent 60%);
}
/* No max-width here: .hero-inner is a .wrap, and giving it a narrower cap
   than every other .wrap makes its auto margins centre it independently, so
   the hero stops aligning with the sections below. The text column is capped
   on the children instead (see the hero-float block). */
.hero h1 { margin-block: var(--sp-3) var(--sp-4); }
.hero-tagline { font-size: var(--step-1); color: var(--text-muted); max-width: 44ch; }
.hero .search { max-width: 34rem; margin-top: var(--sp-5); }
.hero .search-input { padding-block: .8rem; font-size: var(--step-0); }

/* ---------- Cards -------------------------------------------------------- */
.grid { display: grid; gap: var(--sp-4); }
.grid-cards { grid-template-columns: 1fr; }
@media (min-width: 34rem) { .grid-cards { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 60rem) { .grid-cards { grid-template-columns: repeat(3, 1fr); } }

.card {
  position: relative; display: flex; flex-direction: column; gap: var(--sp-2);
  padding: var(--sp-4); background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  text-decoration: none; color: inherit;
  transition: transform var(--duration-fast) var(--ease-smooth-out),
              box-shadow var(--duration-fast) var(--ease-smooth-out),
              border-color var(--duration-fast) var(--ease-smooth-out);
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}
.card h3 { font-size: var(--step-1); }
.card p { color: var(--text-muted); font-size: var(--step--1); }
.card-icon { width: 1.75rem; height: 1.75rem; color: var(--accent); }
/* Accent edge — the visual thread tying a card to its category */
.card--cat { padding-left: calc(var(--sp-4) + 4px); }
.card--cat::before {
  content: ''; position: absolute; left: 0; top: var(--sp-4); bottom: var(--sp-4);
  width: 4px; border-radius: 0 4px 4px 0; background: var(--accent);
  transition: top var(--duration-fast) var(--ease-smooth-out),
              bottom var(--duration-fast) var(--ease-smooth-out);
}
.card--cat:hover::before { top: var(--sp-2); bottom: var(--sp-2); }
.card-count { font-size: var(--step--1); color: var(--text-muted); margin-top: auto; padding-top: var(--sp-2); }

/* Compact tool list */
.tool-list { list-style: none; padding: 0; display: grid; gap: var(--sp-2); }
@media (min-width: 40rem) { .tool-list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .tool-list { grid-template-columns: repeat(3, 1fr); } }
.tool-list a {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3); border: 1px solid var(--border); border-radius: var(--radius);
  background: var(--surface); color: var(--text); text-decoration: none;
  font-size: var(--step--1); font-weight: 500;
  transition: border-color var(--duration-fast) var(--ease-smooth-out),
              background var(--duration-fast) var(--ease-smooth-out),
              transform var(--duration-fast) var(--ease-smooth-out);
}
.tool-list a:hover {
  border-color: color-mix(in srgb, var(--accent) 50%, var(--border));
  background: var(--accent-soft);
  transform: translateX(2px);
}
.tool-list svg { width: 1.1rem; height: 1.1rem; color: var(--accent); flex-shrink: 0; }

/* Blog index: the same cards with a short description under each title */
.post-list a { align-items: flex-start; height: 100%; }
.post-list svg { margin-top: .2rem; }
.post-card { display: flex; flex-direction: column; gap: .35rem; }
.post-title { font-weight: 600; color: var(--text); line-height: 1.35; }
.post-desc { font-weight: 400; color: var(--text-muted); line-height: 1.5; }

/* ---------- Buttons ------------------------------------------------------ */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  min-height: 2.75rem; padding: .65rem 1.25rem;
  font-family: var(--font-display); font-size: var(--step-0); font-weight: 600;
  border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer; text-decoration: none;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              transform var(--duration-quick) var(--ease-smooth-out),
              box-shadow var(--duration-quick) var(--ease-smooth-out);
}
.btn-primary { background: var(--accent); color: var(--accent-on); }
.btn-primary:hover { transform: translateY(-1px); box-shadow: var(--shadow-lift); }
.btn-primary:active { transform: translateY(0); }
.btn-ghost { background: var(--surface); color: var(--text); border-color: var(--border-firm); }
.btn-ghost:hover { background: var(--surface-2); }
.btn-block { width: 100%; }

/* ---------- Forms / calculator ------------------------------------------- */
.calc {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--sp-5); box-shadow: var(--shadow);
}
.field { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.field > label { font-size: var(--step--1); font-weight: 600; }
.field .hint { font-size: .8125rem; color: var(--text-muted); }
.field input[type='text'], .field input[type='number'], .field input[type='date'],
.field input[type='time'], .field select, .field textarea {
  width: 100%; min-height: 2.75rem; padding: .6rem .75rem;
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border-firm); border-radius: var(--radius);
  transition: border-color var(--duration-quick) var(--ease-smooth-out),
              box-shadow var(--duration-quick) var(--ease-smooth-out);
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
.field-row { display: grid; gap: var(--sp-4); }
@media (min-width: 40rem) { .field-row { grid-template-columns: 1fr 1fr; } }
.input-group { display: flex; }
.input-group input { border-radius: var(--radius) 0 0 var(--radius); }
.input-group select, .input-group .addon {
  border: 1px solid var(--border-firm); border-left: none;
  border-radius: 0 var(--radius) var(--radius) 0;
  background: var(--surface-2); padding-inline: .75rem;
  display: flex; align-items: center; font-size: var(--step--1); white-space: nowrap;
}
.field-error {
  display: none; color: #B3261E; font-size: .8125rem; font-weight: 500;
}
html[data-theme='dark'] .field-error { color: #F2B8B5; }
.field.is-invalid .field-error { display: block; }
.field.is-invalid input, .field.is-invalid select { border-color: #B3261E; }

/* ---------- Result slab — the site's signature moment --------------------- */
.result {
  margin-top: var(--sp-5); padding: var(--sp-5);
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--radius-lg); border-top: 3px solid var(--accent);
}
.result[hidden] { display: none; }
.result-label {
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--accent);
}
.result-value {
  font-family: var(--font-display); font-size: var(--step-4); font-weight: 700;
  line-height: 1.05; letter-spacing: -.03em; margin-top: var(--sp-2);
  font-variant-numeric: tabular-nums; word-break: break-word;
}
.result-note { color: var(--text-muted); font-size: var(--step--1); margin-top: var(--sp-2); }
.result-grid {
  display: grid; gap: var(--sp-3); margin-top: var(--sp-4);
  padding-top: var(--sp-4); border-top: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
}
@media (min-width: 34rem) { .result-grid { grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); } }
.result-grid div { display: flex; flex-direction: column; gap: .15rem; }
.result-grid dt, .result-grid .k { font-size: .8125rem; color: var(--text-muted); }
.result-grid dd, .result-grid .v {
  margin: 0; font-family: var(--font-display); font-weight: 600; font-size: var(--step-1);
  font-variant-numeric: tabular-nums;
}

/* Data tables (amortisation, comparisons) */
.table-scroll { overflow-x: auto; margin-top: var(--sp-4); }
table.data { width: 100%; border-collapse: collapse; font-size: var(--step--1); font-variant-numeric: tabular-nums; }
table.data th, table.data td { padding: .55rem .7rem; text-align: right; border-bottom: 1px solid var(--border); white-space: nowrap; }
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data thead th { color: var(--text-muted); font-weight: 600; border-bottom-color: var(--border-firm); }

/* ---------- Prose / content sections ------------------------------------- */
.prose { max-width: 68ch; }
.prose h2 { font-size: var(--step-2); margin-top: var(--sp-6); margin-bottom: var(--sp-3); }
.prose h3 { margin-top: var(--sp-5); margin-bottom: var(--sp-2); }
.prose p, .prose li { color: var(--text); }
.prose p + p { margin-top: var(--sp-3); }
.prose ul, .prose ol { margin-top: var(--sp-3); padding-left: 1.25rem; display: grid; gap: var(--sp-2); }
.todo {
  border-left: 3px solid var(--border-firm); padding: var(--sp-2) var(--sp-4);
  color: var(--text-muted); font-style: italic; background: var(--surface-2);
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* ---------- FAQ accordion (transitions.dev 21) --------------------------- */
.faq { display: grid; gap: var(--sp-2); max-width: 68ch; }
.t-acc { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.t-acc-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  width: 100%; padding: var(--sp-3) var(--sp-4); min-height: 2.75rem;
  background: none; border: none; cursor: pointer; text-align: left;
  font-family: var(--font-display); font-size: var(--step-0); font-weight: 600;
}
.t-acc-chevron svg { width: 1rem; height: 1rem; fill: none; stroke: var(--accent); stroke-width: 1.75; }
.t-acc-panel-inner { padding: 0 var(--sp-4) var(--sp-4); color: var(--text-muted); }


/* ---------- Related tools ------------------------------------------------ */
.related { border-top: 1px solid var(--border); margin-top: var(--sp-7); padding-top: var(--sp-6); }

/* ---------- Footer ------------------------------------------------------- */
.site-footer {
  margin-top: var(--sp-8); padding-block: var(--sp-6) var(--sp-5);
  background: var(--surface); border-top: 1px solid var(--border);
  font-size: var(--step--1);
}
.footer-grid { display: grid; gap: var(--sp-5); }
@media (min-width: 40rem) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
@media (min-width: 64rem) { .footer-grid { grid-template-columns: 1.6fr 1fr 1fr 1fr; } }
.site-footer h2 {
  font-size: var(--step--1); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--text-muted); margin-bottom: var(--sp-3);
}
.site-footer ul { list-style: none; padding: 0; display: grid; gap: var(--sp-2); }
.site-footer a { color: var(--text-muted); text-decoration: none; }
.site-footer a:hover { color: var(--accent); text-decoration: underline; }
.footer-blurb { color: var(--text-muted); max-width: 34ch; margin-top: var(--sp-3); }
.footer-base {
  margin-top: var(--sp-5); padding-top: var(--sp-4); border-top: 1px solid var(--border);
  display: flex; flex-wrap: wrap; gap: var(--sp-3); justify-content: space-between;
  color: var(--text-muted);
}

/* ==========================================================================
   Motion — snippets from transitions.dev, kept verbatim.
   ========================================================================== */

/* Texts reveal (18) — hero page-load.
   The hidden start state is gated behind html[data-js='on'], which the inline
   head script sets synchronously. Without JS the hero text renders normally —
   motion must never be what makes an <h1> visible. */
.t-stagger-line { display: block; }
html[data-js='on'] .t-stagger-line {
  opacity: 0;
  transform: translateY(var(--stagger-distance));
  filter: blur(var(--stagger-blur));
  transition:
    opacity   var(--stagger-dur) var(--stagger-ease),
    transform var(--stagger-dur) var(--stagger-ease),
    filter    var(--stagger-dur) var(--stagger-ease);
  will-change: transform, opacity, filter;
}
.t-stagger-line--2 { transition-delay: var(--stagger-stagger); }
.t-stagger-line--3 { transition-delay: calc(var(--stagger-stagger) * 2); }
.t-stagger.is-shown .t-stagger-line {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}
.t-stagger.is-hiding .t-stagger-line {
  opacity: 0;
  transform: translateY(0);
  filter: blur(0);
  transition:
    opacity 200ms ease,
    transform 0s linear,
    filter 0s linear;
  transition-delay: 0s;
}
@media (prefers-reduced-motion: reduce) {
  .t-stagger-line { transition: none !important; opacity: 1; transform: none; filter: none; }
}

/* Number pop-in (02) — calculator result reveal */
@keyframes t-digit-pop-in {
  0%   {
    transform: translate(
      calc(var(--digit-distance) * var(--digit-dir-x)),
      calc(var(--digit-distance) * var(--digit-dir-y))
    );
    opacity: 0;
    filter: blur(var(--digit-blur));
  }
  100% { transform: translate(0, 0); opacity: 1; filter: blur(0); }
}
.t-digit-group { display: inline-flex; align-items: baseline; }
.t-digit { display: inline-block; will-change: transform, opacity, filter; }
.t-digit-group.is-animating .t-digit {
  animation: t-digit-pop-in var(--digit-dur) var(--digit-ease) both;
}
.t-digit-group.is-animating .t-digit[data-stagger="1"] { animation-delay: var(--digit-stagger); }
.t-digit-group.is-animating .t-digit[data-stagger="2"] { animation-delay: calc(var(--digit-stagger) * 2); }
@media (prefers-reduced-motion: reduce) {
  .t-digit-group .t-digit { animation: none !important; }
}

/* Accordion expand (21) — FAQ */
.t-acc-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--acc-collapse) var(--acc-ease);
}
.t-acc[data-open="true"] .t-acc-panel {
  grid-template-rows: 1fr;
  transition: grid-template-rows var(--acc-expand) var(--acc-ease);
}
.t-acc-panel-inner {
  overflow: hidden;
  opacity: 0;
  filter: blur(2px);
  transition:
    opacity var(--acc-collapse) var(--acc-ease),
    filter var(--acc-collapse) var(--acc-ease);
}
.t-acc[data-open="true"] .t-acc-panel-inner {
  opacity: 1;
  filter: blur(0);
  transition:
    opacity var(--acc-expand) var(--acc-ease),
    filter var(--acc-expand) var(--acc-ease);
}
.t-acc-chevron {
  display: inline-flex;
  transform: scaleY(1);
  transform-origin: center;
  transition: transform var(--acc-chevron) var(--acc-ease);
}
.t-acc-chevron path { vector-effect: non-scaling-stroke; }
.t-acc[data-open="true"] .t-acc-chevron { transform: scaleY(-1); }
@media (prefers-reduced-motion: reduce) {
  .t-acc-panel, .t-acc-panel-inner, .t-acc-chevron { transition: none !important; }
}

/* Global reduced-motion backstop */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- Print -------------------------------------------------------- */
@media print {
  .site-header, .site-footer,   body { background: #fff; color: #000; }
}

/* ==========================================================================
   Header category dropdown
   Tap/click triggered — NOT hover-only. Hover is a desktop-only enhancement,
   because touch devices never fire it and mobile is the majority of traffic
   on a calculator site.
   ========================================================================== */
.nav-item { position: relative; }

.nav-trigger {
  display: flex; align-items: center; gap: .3rem;
  width: 100%; padding: var(--sp-2) var(--sp-3);
  font: inherit; font-size: var(--step--1); font-weight: 500;
  color: var(--text-muted); background: none; border: none;
  border-radius: var(--radius); cursor: pointer; text-align: left;
  transition: color var(--duration-quick) var(--ease-smooth-out),
              background var(--duration-quick) var(--ease-smooth-out);
}
.nav-trigger:hover,
.nav-item[data-open="true"] .nav-trigger { color: var(--text); background: var(--surface-2); }
.nav-caret {
  width: .7rem; height: .7rem; flex-shrink: 0;
  transition: transform var(--duration-fast) var(--ease-smooth-out);
}
.nav-item[data-open="true"] .nav-caret { transform: rotate(180deg); }

.nav-panel {
  padding: var(--sp-2);
  background: var(--surface);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
}
.nav-panel ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 1px; }
.nav-panel a {
  display: block; padding: .5rem var(--sp-3); border-radius: 6px;
  color: var(--text); text-decoration: none; font-size: var(--step--1);
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.nav-panel a:hover, .nav-panel a:focus-visible { background: var(--accent-soft); color: var(--accent); }
.nav-panel-all {
  display: flex !important; align-items: center; gap: .35rem;
  margin-top: var(--sp-2); padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
  font-weight: 600; color: var(--accent) !important;
}
.nav-panel-all svg { width: .8rem; height: .8rem; transition: transform var(--duration-quick) var(--ease-smooth-out); }
.nav-panel-all:hover svg { transform: translateX(3px); }

/* Desktop: floating panel anchored under its trigger. */
@media (min-width: 64rem) {
  .nav-panel {
    position: absolute; top: calc(100% + .4rem); left: 0; z-index: 60;
    min-width: 21rem;
    transform-origin: top left;
    opacity: 0; transform: scale(var(--scale-medium)) translateY(-4px);
    pointer-events: none; visibility: hidden;
    transition: opacity var(--duration-quick) var(--ease-smooth-out),
                transform var(--duration-quick) var(--ease-smooth-out),
                visibility 0s linear var(--duration-quick);
  }
  .nav-item[data-open="true"] .nav-panel {
    opacity: 1; transform: scale(1) translateY(0);
    pointer-events: auto; visibility: visible;
    transition: opacity var(--duration-fast) var(--ease-smooth-out),
                transform var(--duration-fast) var(--ease-smooth-out),
                visibility 0s;
  }
  .nav-panel ul { grid-template-columns: 1fr 1fr; gap: 1px var(--sp-2); }
  .nav-panel-all { grid-column: 1 / -1; }
  /* Keep the right-hand panels from running off the edge. */
  .main-nav li:nth-child(n+3) .nav-panel { left: auto; right: 0; transform-origin: top right; }
}

/* Mobile: the panel expands inline inside the stacked nav — no overlay. */
@media (max-width: 63.99rem) {
  .nav-panel {
    display: none; margin: var(--sp-1) 0 var(--sp-2);
    border-radius: var(--radius); box-shadow: none; background: var(--bg);
  }
  .nav-item[data-open="true"] .nav-panel { display: block; }
  .nav-panel ul { gap: 2px; }
  .nav-panel a { padding: .65rem var(--sp-3); }
}

@media (prefers-reduced-motion: reduce) {
  .nav-panel, .nav-caret { transition: none !important; }
}

/* ==========================================================================
   Hero — floating maths glyphs
   Pure CSS and inline SVG, no image files. Decorative only: aria-hidden, and
   it never sits under the headline or the search field.
   ========================================================================== */
.hero-float {
  position: absolute; inset-block: 0; right: 0; width: 42%;
  pointer-events: none; z-index: 0; overflow: hidden;
  display: none;
}
@media (min-width: 64rem) { .hero-float { display: block; } }

/* .hero-inner IS the .wrap, so it must keep .wrap's own centering — setting
   margin-inline here would drag the hero to the viewport edge and break
   alignment with every section below it. Constrain the children instead, so
   the text column stops short of the glyph zone without moving the container. */
.hero-inner { position: relative; z-index: 1; text-align: left; }
@media (min-width: 64rem) {
  .hero-inner > * { max-width: 54%; }
}

.float-glyph {
  position: absolute;
  display: grid; place-items: center;
  color: var(--accent);
  background: color-mix(in srgb, var(--surface) 82%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
  border-radius: 18px;
  box-shadow: var(--shadow);
  animation: float-drift var(--dur, 9s) ease-in-out var(--delay, 0s) infinite;
  will-change: transform;
}
.float-glyph svg { width: 55%; height: 55%; }

@keyframes float-drift {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(var(--rot, 0deg)); }
  50%      { transform: translate3d(0, -18px, 0) rotate(calc(var(--rot, 0deg) * -1)); }
}

/* Six glyphs, deliberately uneven so it reads as drift rather than a grid. */
.float-glyph:nth-child(1) { top: 6%;  left: 12%; width: 74px; height: 74px; --dur: 5.4s; --delay: 0s;   --rot: 4deg; }
.float-glyph:nth-child(2) { top: 30%; left: 46%; width: 92px; height: 92px; --dur: 6.6s; --delay: .5s;  --rot: -5deg; }
.float-glyph:nth-child(3) { top: 62%; left: 18%; width: 66px; height: 66px; --dur: 4.8s; --delay: 1s;   --rot: 6deg; }
.float-glyph:nth-child(4) { top: 12%; left: 72%; width: 58px; height: 58px; --dur: 6s;   --delay: .25s; --rot: -7deg; }
.float-glyph:nth-child(5) { top: 74%; left: 62%; width: 80px; height: 80px; --dur: 7.2s; --delay: 1.3s; --rot: 3deg; }
.float-glyph:nth-child(6) { top: 44%; left: 2%;  width: 52px; height: 52px; --dur: 5.7s; --delay: .75s; --rot: -4deg; }

@media (prefers-reduced-motion: reduce) {
  .float-glyph { animation: none !important; }
}

/* ==========================================================================
   Tool page layout — main column plus sticky sidebar
   Related tools and an ad slot stay in view while the calculator is used,
   instead of being buried below the FAQ.
   ========================================================================== */
.tool-layout { display: grid; gap: var(--sp-6); align-items: start; }
@media (min-width: 64rem) {
  .tool-layout { grid-template-columns: minmax(0, 1fr) 19rem; gap: var(--sp-7); }
}
.tool-main { min-width: 0; }

.tool-side { display: grid; gap: var(--sp-5); }
@media (min-width: 64rem) {
  .tool-side { position: sticky; top: 4.75rem; }
}
.side-box {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--sp-4);
}
.side-box h2 {
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.side-list { list-style: none; padding: 0; display: grid; gap: 2px; }
.side-list a {
  display: flex; align-items: center; gap: .55rem;
  padding: .55rem .6rem; border-radius: 8px;
  color: var(--text); text-decoration: none; font-size: var(--step--1);
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out),
              transform var(--duration-quick) var(--ease-smooth-out);
}
.side-list a:hover { background: var(--accent-soft); color: var(--accent); transform: translateX(3px); }
.side-list svg { width: .95rem; height: .95rem; color: var(--accent); flex-shrink: 0; }
.side-all {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: var(--sp-3); font-size: var(--step--1); font-weight: 600;
  color: var(--accent); text-decoration: none;
}
.side-all:hover { text-decoration: underline; }

/* ==========================================================================
   Homepage category cards — now carrying their top tools
   ========================================================================== */
.cat-tools { list-style: none; padding: 0; margin-top: var(--sp-3); display: grid; gap: 1px; }
.cat-tools a {
  display: block; padding: .35rem .5rem; margin-inline: -.5rem; border-radius: 6px;
  font-size: var(--step--1); color: var(--text-muted); text-decoration: none;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.cat-tools a:hover { background: var(--accent-soft); color: var(--accent); }
.cat-card-foot {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--border);
}
.cat-card-foot .card-count { margin: 0; padding: 0; }
.cat-see-all {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: var(--step--1); font-weight: 600; color: var(--accent); text-decoration: none;
}
.cat-see-all svg { width: .8rem; height: .8rem; transition: transform var(--duration-quick) var(--ease-smooth-out); }
.cat-see-all:hover svg { transform: translateX(3px); }
/* The card is no longer a single link, so the whole-card lift moves here. */
.card--catbox {
  position: relative; display: flex; flex-direction: column;
  padding: var(--sp-4) var(--sp-4) var(--sp-4) calc(var(--sp-4) + 4px);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  transition: transform var(--duration-fast) var(--ease-smooth-out),
              box-shadow var(--duration-fast) var(--ease-smooth-out),
              border-color var(--duration-fast) var(--ease-smooth-out);
}
.card--catbox::before {
  content: ''; position: absolute; left: 0; top: var(--sp-4); bottom: var(--sp-4);
  width: 4px; border-radius: 0 4px 4px 0; background: var(--accent);
  transition: top var(--duration-fast) var(--ease-smooth-out),
              bottom var(--duration-fast) var(--ease-smooth-out);
}
.card--catbox:hover {
  transform: translateY(-3px); box-shadow: var(--shadow-lift);
  border-color: color-mix(in srgb, var(--accent) 45%, var(--border));
}
.card--catbox:hover::before { top: var(--sp-2); bottom: var(--sp-2); }
.card--catbox h3 a { color: inherit; text-decoration: none; }
.card--catbox h3 a:hover { color: var(--accent); }

/* ==========================================================================
   Category page — staggered reveal and a self-drawing accent rule
   One deliberate moment on load; nothing animates on scroll.
   ========================================================================== */
/* Transition-driven, not animation-driven, and flipped by a JS class rather
   than by the animation itself. site.js adds .is-revealed on the next frame
   with a timeout fallback, exactly like the hero — so content can never be
   left stranded at opacity 0 if animations don't run. The hidden start is
   gated behind html[data-js="on"], so with JS off it is visible immediately. */
html[data-js="on"] .reveal-list > * {
  opacity: 0;
  transform: translateY(var(--distance-medium));
  transition:
    opacity   var(--duration-very-slow) var(--ease-smooth-out),
    transform var(--duration-very-slow) var(--ease-smooth-out);
  transition-delay: calc(var(--i, 0) * var(--duration-stagger));
}
html[data-js="on"] .reveal-list.is-revealed > * {
  opacity: 1;
  transform: translateY(0);
}

.cat-rule {
  height: 3px; width: min(11rem, 40%); border-radius: 3px; margin-top: var(--sp-4);
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 20%, transparent));
}
html[data-js="on"] .cat-rule {
  width: 0;
  transition: width var(--duration-very-slow) var(--ease-smooth-out) .15s;
}
html[data-js="on"] .cat-rule.is-revealed { width: min(11rem, 40%); }

@media (prefers-reduced-motion: reduce) {
  html[data-js="on"] .reveal-list > * { transition: none !important; opacity: 1; transform: none; }
  html[data-js="on"] .cat-rule { transition: none !important; width: min(11rem, 40%); }
}

/* ==========================================================================
   Saved calculators (favourites)
   Stored in localStorage — no account, nothing leaves the browser. The heart
   is a real toggle button with aria-pressed, not a decorative icon.
   ========================================================================== */
:root {
  --fav:      #C0355C;   /* 5.62:1 on --bg, 5.92:1 on --surface */
  --fav-soft: #FBEBF0;
}
html[data-theme="dark"] {
  --fav:      #F49BB2;   /* 9.34:1 on --bg, 8.62:1 on --surface */
  --fav-soft: #35202A;
}

.fav-btn {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 2.5rem; padding: .45rem .85rem;
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 500;
  color: var(--text-muted);
  background: var(--surface);
  border: 1px solid var(--border-firm); border-radius: 999px;
  cursor: pointer;
  transition: color var(--duration-quick) var(--ease-smooth-out),
              border-color var(--duration-quick) var(--ease-smooth-out),
              background var(--duration-quick) var(--ease-smooth-out);
}
.fav-btn:hover { color: var(--fav); border-color: var(--fav); }
.fav-btn[aria-pressed="true"] {
  color: var(--fav); border-color: var(--fav); background: var(--fav-soft);
}

.fav-heart {
  width: 1.05rem; height: 1.05rem; flex-shrink: 0;
  fill: none; stroke: currentColor; stroke-width: 1.8;
  transition: fill var(--duration-quick) var(--ease-smooth-out);
}
.fav-btn[aria-pressed="true"] .fav-heart { fill: currentColor; }
/* Pop only on the moment of saving, never on load or on un-saving. */
.fav-btn.is-popping .fav-heart { animation: fav-pop var(--duration-medium) var(--ease-bounce); }
@keyframes fav-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.32); }
  100% { transform: scale(1); }
}

/* Small heart used inside lists, where the label would be noise. */
.fav-mini {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2rem; height: 2rem; flex-shrink: 0; margin-left: auto;
  background: none; border: none; border-radius: 50%;
  color: var(--text-muted); cursor: pointer;
  transition: color var(--duration-quick) var(--ease-smooth-out),
              background var(--duration-quick) var(--ease-smooth-out);
}
.fav-mini:hover { color: var(--fav); background: var(--fav-soft); }
.fav-mini[aria-pressed="true"] { color: var(--fav); }
.fav-mini svg { width: 1rem; height: 1rem; fill: none; stroke: currentColor; stroke-width: 1.8; }
.fav-mini[aria-pressed="true"] svg { fill: currentColor; }

/* Tool page: heart sits beside the H1 without pushing it around. */
.tool-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: var(--sp-4); flex-wrap: wrap;
}
.tool-head h1 { flex: 1 1 18rem; }
.tool-head .fav-btn { margin-top: .35rem; }

/* Homepage / sidebar saved list */
.fav-empty { color: var(--text-muted); font-size: var(--step--1); }
.fav-empty strong { color: var(--text); font-weight: 600; }
#fav-section[hidden], .side-box[hidden] { display: none; }
.fav-count {
  display: inline-block; margin-left: .5rem; padding: .1rem .5rem;
  font-size: .75rem; font-weight: 600; border-radius: 999px;
  color: var(--fav); background: var(--fav-soft);
}
.fav-clear {
  background: none; border: none; padding: 0; cursor: pointer;
  font: inherit; font-size: var(--step--1); color: var(--text-muted);
  text-decoration: underline; text-underline-offset: .2em;
}
.fav-clear:hover { color: var(--fav); }

@media (prefers-reduced-motion: reduce) {
  .fav-btn.is-popping .fav-heart { animation: none !important; }
}

/* ==========================================================================
   Header saved-calculators menu
   Sits beside the day/night toggle. Click opens the list; hover shows a
   tooltip. Click is the real trigger — hover alone would be unreachable on
   touch, same reasoning as the category dropdowns.
   ========================================================================== */
.fav-menu { position: relative; margin-left: auto; flex-shrink: 0; }
/* The heart now owns the right-push, so the theme toggle sits next to it. */
.fav-menu ~ .theme-toggle { margin-left: 0; }

.fav-toggle {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  color: var(--text-muted); cursor: pointer;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.fav-toggle:hover { background: var(--surface-2); color: var(--fav); }
.fav-toggle[aria-expanded="true"] { background: var(--surface-2); color: var(--fav); }
.fav-toggle svg {
  width: 1.2rem; height: 1.2rem;
  fill: none; stroke: currentColor; stroke-width: 1.7;
  transition: fill var(--duration-quick) var(--ease-smooth-out);
}
/* Filled whenever anything is saved, so the header shows state at a glance. */
.fav-menu[data-has-saved="true"] .fav-toggle { color: var(--fav); }
.fav-menu[data-has-saved="true"] .fav-toggle svg { fill: currentColor; }

.fav-badge {
  position: absolute; top: .3rem; right: .28rem;
  min-width: 1.05rem; height: 1.05rem; padding: 0 .2rem;
  display: grid; place-items: center;
  font-size: .68rem; font-weight: 700; line-height: 1;
  color: #fff; background: var(--fav);
  border: 2px solid var(--bg); border-radius: 999px;
  animation: fav-badge-pop var(--duration-fast) var(--ease-bounce);
}
.fav-badge[hidden] { display: none; }
@keyframes fav-badge-pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }

/* ---- Tooltip: "Saved calculators" ---- */
.fav-tip {
  position: absolute; top: calc(100% + .35rem); left: 50%;
  transform: translateX(-50%) scale(var(--scale-small, .98));
  padding: .3rem .55rem;
  font-size: .75rem; font-weight: 500; white-space: nowrap;
  color: var(--bg); background: var(--text);
  border-radius: 6px; pointer-events: none;
  opacity: 0; z-index: 70;
  transition: opacity var(--duration-quick) var(--ease-out),
              transform var(--duration-quick) var(--ease-out);
}
.fav-toggle:hover + .fav-tip,
.fav-toggle:focus-visible + .fav-tip {
  opacity: 1; transform: translateX(-50%) scale(1);
  transition-delay: var(--duration-micro);
}
/* Hide the tooltip once the panel is open — it would only cover the list. */
.fav-toggle[aria-expanded="true"] + .fav-tip { opacity: 0 !important; }

/* ---- Panel ---- */
.fav-menu-panel {
  position: absolute; top: calc(100% + .45rem); right: 0; z-index: 65;
  width: min(20rem, calc(100vw - 2rem));
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--border-firm); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  transform-origin: top right;
  opacity: 0; transform: scale(var(--scale-medium)) translateY(-4px);
  pointer-events: none; visibility: hidden;
  transition: opacity var(--duration-quick) var(--ease-smooth-out),
              transform var(--duration-quick) var(--ease-smooth-out),
              visibility 0s linear var(--duration-quick);
}
.fav-menu[data-open="true"] .fav-menu-panel {
  opacity: 1; transform: scale(1) translateY(0);
  pointer-events: auto; visibility: visible;
  transition: opacity var(--duration-fast) var(--ease-smooth-out),
              transform var(--duration-fast) var(--ease-smooth-out),
              visibility 0s;
}
.fav-menu-panel h2 {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.fav-menu-panel .fav-empty { margin: 0; }
.fav-menu-panel .side-list { max-height: min(24rem, 55vh); overflow-y: auto; }
.fav-menu-foot {
  margin-top: var(--sp-3); padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  display: flex; justify-content: flex-end;
}

@media (prefers-reduced-motion: reduce) {
  .fav-menu-panel, .fav-tip, .fav-toggle svg { transition: none !important; }
  .fav-badge { animation: none !important; }
}

/* ---------- Editorial / E-E-A-T components ------------------------------- */

/* Informational callout. Replaces the .todo styling that real notes were
   temporarily borrowing while the copy was being written. */
.note {
  border-left: 3px solid var(--accent); padding: var(--sp-3) var(--sp-4);
  background: var(--surface-2); border-radius: 0 var(--radius) var(--radius) 0;
  color: var(--text-muted); font-size: var(--step--1); margin-top: var(--sp-4);
}
.note strong { color: var(--text); }
.note a { color: inherit; }

/* Byline strip under the H1: who maintains the page and when it changed. */
.page-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-3); font-size: var(--step--1); color: var(--text-muted);
}
.page-meta > span { display: inline-flex; align-items: center; gap: .4rem; }
.page-meta svg { width: 15px; height: 15px; flex: none; opacity: .75; }
.page-meta a { color: inherit; text-underline-offset: 2px; }
.page-meta a:hover { color: var(--text); }

/* A named formula, set apart from the prose around it. */
.formula {
  margin-top: var(--sp-4); padding: var(--sp-4);
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius);
}
.formula p { margin: 0; }
.formula .formula-line {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: var(--step-0); color: var(--text); font-variant-numeric: tabular-nums;
  overflow-x: auto; padding-bottom: .15rem;
}
.formula .formula-where {
  margin-top: var(--sp-2); font-size: var(--step--1); color: var(--text-muted);
}

/* Worked example: the numbers behind a claim. */
.worked {
  margin-top: var(--sp-4); padding: var(--sp-4);
  border: 1px dashed var(--border-firm); border-radius: var(--radius);
}
.worked h3 {
  margin: 0 0 var(--sp-2); font-family: var(--font-display);
  font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
}
.worked p { margin: 0; }
.worked p + p { margin-top: var(--sp-2); }
.worked .worked-answer { margin-top: var(--sp-3); font-weight: 600; color: var(--text); }

/* Reference list at the foot of the article. */
.sources {
  margin-top: var(--sp-6); padding-top: var(--sp-4);
  border-top: 1px solid var(--border); max-width: 68ch;
}
.sources h2 {
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.sources ol { margin: 0; padding-left: 1.15rem; display: grid; gap: var(--sp-2); }
.sources li { font-size: var(--step--1); color: var(--text-muted); }
.sources a { color: var(--text); text-underline-offset: 2px; }

/* Highlight the row matching the reader's own grade in a reference table. */
table.data tr.is-current { background: var(--accent-soft); }
table.data tr.is-current td { font-weight: 600; color: var(--text); }

/* ---------- Language menu ------------------------------------------------
   Machine translation via Google Translate, opened in a new tab. The site
   itself is written in English only — this is a convenience for readers, not
   a localisation layer, and the panel says so. Styling deliberately mirrors
   .fav-menu so the header reads as one set of controls. */
.lang-menu { position: relative; flex-shrink: 0; }

.lang-toggle {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.75rem; height: 2.75rem;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  color: var(--text-muted); cursor: pointer;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.lang-toggle:hover { background: var(--surface-2); color: var(--text); }
.lang-toggle[aria-expanded="true"] { background: var(--surface-2); color: var(--text); }
.lang-toggle svg {
  width: 1.2rem; height: 1.2rem;
  fill: none; stroke: currentColor; stroke-width: 1.7;
}

/* Tooltip, matching .fav-tip */
.lang-tip {
  position: absolute; top: calc(100% + .35rem); left: 50%;
  transform: translateX(-50%) scale(.98);
  padding: .3rem .55rem;
  font-size: .75rem; font-weight: 500; white-space: nowrap;
  color: var(--bg); background: var(--text);
  border-radius: 6px; pointer-events: none;
  opacity: 0; z-index: 70;
  transition: opacity var(--duration-quick) var(--ease-smooth-out),
              transform var(--duration-quick) var(--ease-smooth-out);
}
.lang-toggle:hover + .lang-tip,
.lang-toggle:focus-visible + .lang-tip {
  opacity: 1; transform: translateX(-50%) scale(1);
}
.lang-menu[data-open="true"] .lang-tip { opacity: 0; }

.lang-panel {
  position: absolute; top: calc(100% + .45rem); right: 0; z-index: 65;
  width: min(19rem, calc(100vw - 2rem));
  padding: var(--sp-3);
  background: var(--surface);
  border: 1px solid var(--border-firm); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lift);
  transform-origin: top right;
  opacity: 0; transform: scale(var(--scale-medium)) translateY(-4px);
  pointer-events: none; visibility: hidden;
  transition: opacity var(--duration-quick) var(--ease-smooth-out),
              transform var(--duration-quick) var(--ease-smooth-out),
              visibility 0s linear var(--duration-quick);
}
.lang-menu[data-open="true"] .lang-panel {
  opacity: 1; transform: scale(1) translateY(0);
  pointer-events: auto; visibility: visible;
  transition: opacity var(--duration-fast) var(--ease-smooth-out),
              transform var(--duration-fast) var(--ease-smooth-out),
              visibility 0s;
}
.lang-panel h2 {
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
  margin-bottom: var(--sp-3);
}
.lang-list {
  list-style: none; padding: 0; margin: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 2px;
  max-height: min(22rem, 55vh); overflow-y: auto;
}
.lang-list button {
  display: block; width: 100%; text-align: left;
  padding: .45rem .55rem;
  font: inherit; font-size: var(--step--1); line-height: 1.3;
  color: var(--text); background: none; border: 0; border-radius: 6px;
  cursor: pointer;
  transition: background var(--duration-quick) var(--ease-smooth-out);
}
.lang-list button:hover, .lang-list button:focus-visible { background: var(--surface-2); }
.lang-list .lang-native { display: block; }
.lang-list .lang-en { display: block; font-size: .72rem; color: var(--text-muted); }

.lang-note {
  margin: var(--sp-3) 0 0; padding-top: var(--sp-3);
  border-top: 1px solid var(--border);
  font-size: .72rem; line-height: 1.45; color: var(--text-muted);
}

/* Below 64rem the header bar wraps, and where the globe button lands depends
   on the exact width — so anchoring the panel to the button overflows one edge
   or the other. Anchor it to the sticky header instead, which always spans the
   full width, and inset it to match .wrap padding. */
@media (max-width: 63.99rem) {
  .lang-menu { position: static; }
  .lang-panel {
    top: 100%;
    left: var(--sp-4); right: var(--sp-4);
    width: auto;
    transform-origin: top right;
  }
}
@media (min-width: 48rem) and (max-width: 63.99rem) {
  .lang-panel { left: var(--sp-5); right: var(--sp-5); }
}

/* Currently-selected language, shown as a small tag on the globe button. */
.lang-current {
  position: absolute; bottom: .35rem; right: .3rem;
  font-size: .58rem; font-weight: 700; line-height: 1;
  letter-spacing: .02em; text-transform: uppercase;
  color: var(--accent);
}
.lang-current:empty { display: none; }
.lang-list button[aria-current="true"] { background: var(--accent-soft); }
.lang-list button[aria-current="true"] .lang-native { font-weight: 600; }

/* ---- Google Website Translator: keep it invisible and stop it moving the
   page. The widget injects a 40px banner iframe and pushes <body> down, which
   would otherwise cost us a chunk of CLS on every translated page. Attribution
   is kept in the panel instead of relying on Google's own bar. ---- */
#google_translate_element { display: none !important; }
.goog-te-banner-frame,
.goog-te-banner-frame.skiptranslate,
iframe.skiptranslate { display: none !important; visibility: hidden !important; }
body { top: 0 !important; position: static !important; }
.goog-tooltip, .goog-tooltip:hover, .goog-text-highlight {
  display: none !important; background: none !important; box-shadow: none !important;
}
/* The widget marks translated runs with a background; strip it. */
font[style] { background: none !important; box-shadow: none !important; }

@media (prefers-reduced-motion: reduce) {
  .lang-panel, .lang-tip { transition: none !important; }
}

/* ---------- Charts -------------------------------------------------------
   Drawn as inline SVG by js/chart.js, so everything here themes through the
   same custom properties as the rest of the site and prints as vector. */
.ac-chart {
  margin-top: var(--sp-5);
  padding: var(--sp-4);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.ac-chart[hidden] { display: none; }
.ac-chart-heading {
  margin: 0 0 var(--sp-3);
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .07em; text-transform: uppercase; color: var(--text-muted);
}
.ac-chart-svg { display: block; width: 100%; height: auto; overflow: visible; }

.ac-chart-svg .ac-grid  { stroke: var(--border); stroke-width: 1; }
.ac-chart-svg .ac-axis  { stroke: var(--border-firm); stroke-width: 1; }
.ac-chart-svg .ac-tick  { font-size: 11px; fill: var(--text-muted); }
.ac-chart-svg .ac-marker      { stroke: var(--text); stroke-width: 2; }
.ac-chart-svg .ac-marker-head { fill: var(--text); }
.ac-chart-svg .ac-centre-value { font-size: 20px; font-weight: 700; fill: var(--text); }
.ac-chart-svg .ac-centre-label { font-size: 11px; fill: var(--text-muted); }
.ac-chart-svg .ac-legend-text  { font-size: 13px; fill: var(--text); }
.ac-chart-svg .ac-legend-value { font-size: 13px; fill: var(--text-muted); font-variant-numeric: tabular-nums; }
.ac-chart-svg .ac-caption      { font-size: 12px; fill: var(--text-muted); }

.ac-legend {
  list-style: none; padding: 0;
  margin: var(--sp-3) 0 0;
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  font-size: var(--step--1); color: var(--text-muted);
}
.ac-legend li { display: inline-flex; align-items: center; gap: .45rem; }
.ac-swatch { width: .7rem; height: .7rem; border-radius: 3px; flex: none; }

/* ---------- Export bar ---------------------------------------------------
   Sits inside the result panel, so it only ever appears once there is
   something worth saving. */
.export-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2) var(--sp-3);
  margin-top: var(--sp-4); padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
}
.export-label {
  font-family: var(--font-display); font-size: var(--step--1); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--text-muted);
}
.export-actions { display: flex; flex-wrap: wrap; gap: .4rem; }
.export-btn {
  font: inherit; font-size: var(--step--1); font-weight: 500;
  padding: .38rem .8rem;
  color: var(--text); background: var(--surface);
  border: 1px solid var(--border-firm); border-radius: 999px;
  cursor: pointer;
  transition: background var(--duration-quick) var(--ease-smooth-out),
              border-color var(--duration-quick) var(--ease-smooth-out),
              color var(--duration-quick) var(--ease-smooth-out);
}
.export-btn:hover {
  background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
}
.export-btn:active { transform: translateY(1px); }
.export-btn[hidden] { display: none; }
.export-status {
  font-size: var(--step--1); color: var(--accent);
  min-height: 1em;
}

@media (max-width: 30rem) {
  .export-bar { gap: var(--sp-2); }
  .export-label { width: 100%; }
}

/* ---------- Printing a calculator page ----------------------------------
   The PDF export builds its own document, but a reader may also just hit
   Ctrl+P on the page itself — so make that produce something sensible. */
@media print {
  .site-header, .site-footer, .breadcrumb, .tool-side,
  .export-bar, .fav-btn, .faq, .sources, .lang-menu { display: none !important; }
  .wrap { max-width: none; padding: 0; }
  .tool-layout { display: block; }
  body { background: #fff; color: #000; }
  .result, .ac-chart { break-inside: avoid; border-color: #ccc; }
  .prose { max-width: none; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .85em; word-break: break-all; }
}

@media (prefers-reduced-motion: reduce) {
  .export-btn { transition: none !important; }
}
