/* Generated by tools/brand/fetch-fonts.mjs. Do not edit by hand.
   Regenerate with: node tools/brand/fetch-fonts.mjs */

@font-face {
  font-family: 'Playfair';
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url('/fonts/playfair-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Playfair';
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url('/fonts/playfair-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Playfair';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/playfair-latin-ext-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Playfair';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/playfair-latin-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: italic;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-latin-ext-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Source Serif 4';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/source-serif-4-latin-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/inter-latin-ext-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/inter-latin-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Literata';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/literata-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Literata';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/literata-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/literata-latin-ext-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Literata';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/literata-latin-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'EB Garamond';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/eb-garamond-latin-ext-italic.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'EB Garamond';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/eb-garamond-latin-italic.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'EB Garamond';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/eb-garamond-latin-ext-normal.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'EB Garamond';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/fonts/eb-garamond-latin-normal.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Scheherazade New';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/scheherazade-new-arabic-normal-400.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

@font-face {
  font-family: 'Noto Nastaliq Urdu';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/noto-nastaliq-urdu-arabic-normal-400.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E, U+10EC2-10EC4, U+10EFC-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22, U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49, U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F, U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E, U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}

@font-face {
  font-family: 'Honorifics';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/honorifics.woff2') format('woff2');
}

@font-face {
  font-family: 'OpenDyslexic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/opendyslexic-normal.woff2') format('woff2');
}

@font-face {
  font-family: 'OpenDyslexic';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/opendyslexic-italic.woff2') format('woff2');
}

@font-face {
  font-family: 'OpenDyslexic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/opendyslexic-bold.woff2') format('woff2');
}

/* ==========================================================================
   admin.css - the administrator's side of The Muslim Page.
   ==========================================================================

   NOT PART OF THE PUBLIC STYLESHEET, and never joined to it. assets.js serves
   this on its own, to the panel only. Everything below is fetched by one
   person; site.css is fetched by every reader on every first paint, and putting
   a dashboard's tables and charts in front of them to save one request for
   Aamir would be the wrong way round.

   THE PALETTE IS THE SITE'S, EXACTLY. The same midnight ground, the same warm
   ivory, the same one amber accent, the same Inter. DESIGN-CONSISTENCY.md
   section 5.1 defines every one of these values and this file restates them
   rather than importing them, because the two stylesheets are served
   separately and a token defined in one is not available in the other. If that
   table ever changes, this block changes with it: they are the same design.

   WHAT IS DIFFERENT FROM THE PUBLIC SIDE, and why:

     - NOTHING ARRIVES. No reveal on scroll, no splash cover, no header that
       resolves as you scroll past a hero. Motion is an introduction, and this
       screen is opened twenty times a day by somebody who has already met it.
       The only transitions here are on hover and focus.
     - THE MEASURE IS WIDER. 82rem against the site's 78, because a table of
       nine books with six columns wants the room and there is no prose here to
       keep to a readable line length.
     - TWO MORE COLOURS EXIST, and only inside a change indicator. Section 3.

   THE CHART MARKS ARE FIXED SPECIFICATIONS AND NOT PREFERENCES, and they are
   in section 8. Two pixel lines, area washes at a tenth, markers no smaller
   than eight pixels with a ring in the surface colour, bars capped at 24px with
   a rounded far end and a square baseline end, hairline solid gridlines. They
   are what make six charts read as one system.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */

:root {
  --ink: #0e1424;
  --ink-raised: #151d31;
  --ink-hover: #1f2942;
  --ink-sunk: #0a0f1c;

  --bone: #f2efe6;
  --bone-dim: #a3aab6;
  --bone-faint: rgba(242, 239, 230, 0.45);

  --warm: #e0a878;
  --warm-soft: rgba(224, 168, 120, 0.14);
  --warm-wash: rgba(224, 168, 120, 0.1);

  /* THE TWO DIRECTION COLOURS, and they exist nowhere else in this file.
     DESIGN-CONSISTENCY.md section 5.1 says a strong colour does not go back
     into the shell, and allows the contact form's refused field as the one
     exception. A change indicator is the second, and for the same reason: a
     figure that has halved has to be findable among eight that have not.

     THEY SAY WHICH WAY, NOT WHETHER IT IS GOOD. A rise in single-page visits is
     not an improvement and a fall in them is not a failure, so the colour is
     never asked to carry a judgement it cannot make. Every one of them is
     accompanied by an arrow and by a word, because about one man in twelve
     cannot tell these two hues apart and the colour must never be the only
     thing saying it. */
  --rise: #9ec7a4;
  --fall: #eda9a2;

  --line: rgba(242, 239, 230, 0.14);
  --line-soft: rgba(242, 239, 230, 0.07);

  --ui: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  --wrap: 82rem;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --head: 3.75rem;
  --radius: 10px;
  --ease-soft: cubic-bezier(0.4, 0, 0.2, 1);
}

/* --------------------------------------------------------------------------
   2. Reset and base
   -------------------------------------------------------------------------- */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body.a-body {
  margin: 0;
  min-height: 100vh;
  background: var(--ink);
  color: var(--bone);
  font-family: var(--ui);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

h1,
h2,
h3,
p,
ul,
ol,
dl,
figure {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
  text-decoration-color: var(--line);
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-color: var(--warm);
}

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

/* --------------------------------------------------------------------------
   3. The bar across the top
   -------------------------------------------------------------------------- */

.a-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--ink-sunk);
  border-bottom: 1px solid var(--line);
}

.a-header-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 var(--gutter);
  min-height: var(--head);
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.a-brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  text-decoration: none;
  flex: none;
}

.a-brand-mark {
  width: 1.35rem;
  height: 1.35rem;
  display: block;
  color: var(--warm);
}

.a-brand-name {
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: -0.012em;
}

/* The one word that says which side of the site you are on. Set apart rather
   than merely appended, because the panel and the public site share a name and
   a mark, and the difference between them is worth a glance rather than a
   reading. */
.a-brand-tag {
  font-size: 0.6rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--warm);
  border: 1px solid var(--warm-soft);
  border-radius: 999px;
  padding: 0.15rem 0.45rem;
}

/* The sections. A row that scrolls sideways on a narrow screen rather than a
   menu button: five short words is not a menu, and hiding them behind a press
   is a worse answer than letting a thumb push them along. */
.a-nav {
  display: flex;
  gap: 0.25rem;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
}

.a-nav::-webkit-scrollbar {
  display: none;
}

.a-nav a {
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--bone-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s var(--ease-soft), background-color 0.15s var(--ease-soft);
}

.a-nav a:hover {
  color: var(--bone);
  background: var(--ink-hover);
}

.a-nav a[aria-current='page'] {
  color: var(--ink);
  background: var(--bone);
}

.a-signout {
  flex: none;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--bone-dim);
  text-decoration: none;
  white-space: nowrap;
}

.a-signout:hover {
  color: var(--bone);
}

@media (max-width: 52rem) {
  .a-header-inner {
    flex-wrap: wrap;
    gap: 0.75rem;
    padding-top: 0.7rem;
    padding-bottom: 0.7rem;
  }

  .a-nav {
    order: 3;
    width: 100%;
    margin-left: 0;
  }

  .a-signout {
    margin-left: auto;
  }
}

/* --------------------------------------------------------------------------
   4. The page
   -------------------------------------------------------------------------- */

.a-main {
  flex: 1;
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 2rem var(--gutter) 4rem;
}

.a-page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem 2rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 1.75rem;
}

.a-page-head h1 {
  font-size: clamp(1.6rem, 4vw, 2.1rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.a-lede {
  margin-top: 0.35rem;
  max-width: 44rem;
  color: var(--bone-dim);
  font-size: 0.9rem;
}

/* The range switch. Every setting is a real address, because the server is what
   applies it: the whole panel works with no script and any view of it can be
   bookmarked or sent to somebody. */
.a-ranges {
  display: flex;
  gap: 0.2rem;
  padding: 0.2rem;
  background: var(--ink-raised);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  overflow-x: auto;
  scrollbar-width: none;
}

.a-ranges::-webkit-scrollbar {
  display: none;
}

.a-ranges a {
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--bone-dim);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s var(--ease-soft), background-color 0.15s var(--ease-soft);
}

.a-ranges a:hover {
  color: var(--bone);
}

.a-ranges a[aria-current='true'] {
  color: var(--ink);
  background: var(--warm);
}

/* --------------------------------------------------------------------------
   5. Stat tiles
   -------------------------------------------------------------------------- */

/* The `min()` is what keeps a narrow screen honest. `minmax(11rem, 1fr)` on its
   own cannot go below 11rem, so on a phone narrower than that the row overflows
   the page rather than folding; `min(11rem, 100%)` lets the track shrink to
   whatever is actually there. */
.a-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.a-stat {
  overflow: hidden;
  padding: 0.95rem 1.05rem 1.05rem;
  background: var(--ink-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

/* TWO LINES OF ROOM WHETHER OR NOT TWO ARE USED, so that every value in a row
   of tiles sits on the same baseline. One label in six is long enough to wrap
   ('chapters read to the end'), and without this its number drops a line below
   the five beside it, which reads as a mistake rather than as a long label. */
.a-stat-label {
  display: block;
  /* Two lines exactly: 2 x the line-height below. Anything less and the label
     that does wrap still pushes its own number down past the five beside it,
     which is the whole thing this is here to prevent. */
  min-height: 2.7em;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.35;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--bone-dim);
}

/* THE FONT'S ORDINARY FIGURES, NOT TABULAR ONES, and it is a real difference at
   this size. Tabular gives every digit the width of a nought so that columns
   line up, which is exactly right in the tables further down and makes a lone
   large number look gappy and loose. */
.a-stat-value {
  font-size: 1.85rem;
  font-weight: 700;
  letter-spacing: -0.025em;
  line-height: 1.1;
  font-variant-numeric: proportional-nums;
}

.a-stat.is-big .a-stat-value {
  font-size: clamp(2.6rem, 7vw, 3.4rem);
}

.a-stat-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin-top: 0.15rem;
  font-size: 0.75rem;
  color: var(--bone-dim);
}

.a-stat-note {
  color: var(--bone-faint);
}

.a-change {
  font-weight: 600;
  white-space: nowrap;
}

.a-change.is-up {
  color: var(--rise);
}

.a-change.is-down {
  color: var(--fall);
}

.a-change.is-level {
  color: var(--bone-faint);
}

/* IN THE FLOW AND NOT FLOATED OVER THE CORNER. Absolutely positioned in the
   bottom right it looked neat until a tile's note ran long, at which point the
   words passed underneath the line and both became hard to read. Sitting at the
   foot of the tile it cannot collide with anything, and the tiles in a row are
   stretched to a common height anyway, so it costs no extra space. */
.a-spark {
  display: block;
  width: 100%;
  max-width: 7.5rem;
  height: auto;
  margin-top: auto;
  padding-top: 0.6rem;
  opacity: 0.8;
  pointer-events: none;
}

.a-spark-line {
  fill: none;
  stroke: var(--warm);
  stroke-width: 1.5;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.a-spark-wash {
  fill: var(--warm);
  opacity: 0.1;
  stroke: none;
}

.a-spark-dot {
  fill: var(--warm);
}

/* --------------------------------------------------------------------------
   6. Panels
   -------------------------------------------------------------------------- */

/* RENAMED FROM `.a-grid` ON 20 AUGUST 2026, AND IT WAS A REAL BUG rather than
   tidying. The SVG gridlines inside a chart used the same class name, and
   `stroke` is an INHERITED property that cascades from an HTML ancestor into
   the SVG children below it. So this rule's `stroke: var(--line-soft)` was
   inherited by every element of every chart inside a panel: the invisible hit
   areas gained visible edges and drew a full-height vertical line at every data
   point, and every bar gained an outline. It rendered perfectly and looked like
   a design decision.

   Two things stop it recurring: the names no longer collide, and `.a-chart`
   below resets `stroke` explicitly so nothing an ancestor sets can reach a mark
   that has not asked for it. */
.a-panels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  gap: 0.75rem;
  align-items: start;
}

.a-panel {
  background: var(--ink-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 1.1rem 1.15rem 1.25rem;
  min-width: 0;
}

.a-panel.is-wide {
  grid-column: 1 / -1;
}

.a-panel-head {
  margin-bottom: 1rem;
}

.a-panel-head h2 {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.008em;
}

/* The sentence under a panel heading, and it is not decoration. Half these
   figures are ones nobody has had before, and two words over a chart is a
   puzzle rather than an answer. */
.a-panel-note {
  margin-top: 0.25rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--bone-dim);
  max-width: 46rem;
}

/* Several small breakdowns inside ONE panel, side by side. Three separate
   panels of four rows each leave the third stranded on a row of its own,
   because a grid of panels cannot pack a short one under a short one. */
.a-split {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: 1.5rem;
}

.a-split h3 {
  margin-bottom: 0.7rem;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--bone-dim);
}

.a-empty {
  padding: 1.5rem 0;
  color: var(--bone-faint);
  font-size: 0.85rem;
  text-align: center;
}

.a-footer {
  max-width: var(--wrap);
  width: 100%;
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 2.5rem;
  border-top: 1px solid var(--line-soft);
  color: var(--bone-faint);
  font-size: 0.75rem;
}

/* --------------------------------------------------------------------------
   7. Rows, tables and meters
   -------------------------------------------------------------------------- */

.a-rows {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.a-row-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.3rem;
}

.a-row-name {
  font-size: 0.83rem;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* THE NOTE IS ITS OWN LINE and not a continuation of the name. Set inline it
   reads fine for 'Google' and badly for 'Khuṭbāt-e-Ḥakīm al-Ummat, Volume 1',
   which wraps and leaves its own reader count stranded at the start of a second
   line with the value floating away from both. A book title is the normal case
   here, so the layout is built for the long name rather than the short one. */
.a-row-note {
  display: block;
  margin-top: 0.1rem;
  color: var(--bone-faint);
  font-size: 0.75rem;
}

.a-row-value {
  flex: none;
  font-size: 0.83rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.a-row-unit {
  margin-left: 0.2rem;
  font-weight: 400;
  color: var(--bone-faint);
}

/* The unfilled part of a bar is a lighter step of the same amber rather than a
   grey, so the value reads across the whole track instead of only where the
   fill stops. */
.a-row-track {
  height: 6px;
  border-radius: 3px;
  background: var(--warm-wash);
  overflow: hidden;
}

.a-row-bar {
  height: 100%;
  border-radius: 3px;
  background: var(--warm);
}


/* A table wider than its panel scrolls inside the panel. The page itself never
   scrolls sideways: a horizontal scrollbar on the document is how a dashboard
   loses its first column on a phone. */
.a-scroll {
  overflow-x: auto;
  margin: 0 -0.3rem;
  padding: 0 0.3rem;
}

.a-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}

.a-table th,
.a-table td {
  padding: 0.5rem 0.6rem;
  text-align: left;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}

.a-table thead th {
  position: sticky;
  top: 0;
  background: var(--ink-raised);
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--bone-dim);
  white-space: nowrap;
  border-bottom-color: var(--line);
}

.a-table tbody th {
  font-weight: 500;
  min-width: 11rem;
  overflow-wrap: anywhere;
}

.a-table tbody tr:last-child th,
.a-table tbody tr:last-child td {
  border-bottom: 0;
}

.a-table tbody tr:hover {
  background: rgba(242, 239, 230, 0.03);
}

.a-table .is-right {
  text-align: right;
  white-space: nowrap;
}

.a-table a {
  text-decoration: none;
}

.a-table a:hover {
  text-decoration: underline;
  text-decoration-color: var(--warm);
}

.a-quiet {
  color: var(--bone-faint);
}

.a-tag {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  background: var(--ink-hover);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--bone-dim);
  white-space: nowrap;
}

/* A bar drawn behind a number inside a table cell. The number is the value; the
   bar is only there so a column can be scanned for its shape. */
.a-cell-bar {
  display: inline-block;
  width: 3.5rem;
  height: 5px;
  margin-right: 0.5rem;
  border-radius: 3px;
  background: var(--warm-wash);
  overflow: hidden;
  vertical-align: middle;
}

.a-cell-bar span {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--warm);
}

.a-cell-number {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   8. Charts
   -------------------------------------------------------------------------- */

.a-chart {
  display: block;
  width: 100%;
  height: auto;
  /* Below this the axis figures would be too small to read. The container
     scrolls instead of shrinking them: a chart somebody has to push sideways is
     usable, and one whose numbers are five pixels tall is not. */
  min-width: 30rem;
  /* THE RESET THAT MATTERS. `stroke` and `fill` are inherited properties and
     they cascade out of the HTML above into every mark below, so any rule that
     happens to set a stroke on an ancestor draws outlines on marks that never
     asked for one. Stated here, every mark starts from nothing and only the
     rules below put a line on anything. */
  stroke: none;
}

.a-gridline {
  stroke: var(--line-soft);
  stroke-width: 1;
  shape-rendering: crispEdges;
}

.a-axis {
  fill: var(--bone-faint);
  font-family: var(--ui);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

/* Values ride the marks, and there are never more than two of them on a chart:
   the peak and the latest. A number on every point is chaos and goes unread. */
.a-value {
  fill: var(--bone);
  font-family: var(--ui);
  font-size: 11.5px;
  font-weight: 700;
}

.a-line {
  fill: none;
  stroke: var(--warm);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* The second series, where there is one. A recessive grey and not a second hue:
   it is context for the first rather than its equal, and two accents would make
   the reader choose which one the chart is about. */
.a-line-context {
  fill: none;
  stroke: var(--bone-dim);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
  opacity: 0.55;
}

.a-wash {
  fill: var(--warm);
  opacity: 0.1;
  stroke: none;
}

/* A ring in the surface colour, so a marker stays legible where it crosses its
   own line. The ring is part of the mark, not spacing around it. */
.a-dot {
  fill: var(--warm);
  stroke: var(--ink-raised);
  stroke-width: 2;
}

.a-bar {
  fill: var(--warm);
  opacity: 0.55;
  transition: opacity 0.12s var(--ease-soft);
}

.a-column.is-busiest .a-bar {
  opacity: 1;
}

.a-column:hover .a-bar {
  opacity: 1;
}

/* The hit areas: a full-height strip per column, so the target is the whole
   band rather than a four pixel dot. */
.a-hit {
  fill: transparent;
}

.a-column:hover .a-hit,
.a-hit:hover {
  fill: rgba(242, 239, 230, 0.04);
}

.a-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
  margin-bottom: 0.5rem;
  font-size: 0.75rem;
  color: var(--bone-dim);
}

.a-key {
  display: inline-block;
  width: 0.85rem;
  height: 3px;
  margin-right: 0.35rem;
  border-radius: 2px;
  vertical-align: middle;
}

.a-key-main {
  background: var(--warm);
}

.a-key-context {
  background: var(--bone-dim);
  opacity: 0.55;
}

/* Every chart carries its own figures, folded away: the accessible version, the
   exact numbers rather than an estimate off an axis, and what makes the hover
   tooltip an enhancement rather than the only way to read a value. */
.a-figures {
  margin-top: 0.9rem;
  border-top: 1px solid var(--line-soft);
  padding-top: 0.6rem;
}

.a-figures summary {
  cursor: pointer;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--bone-dim);
  list-style: none;
}

.a-figures summary::-webkit-details-marker {
  display: none;
}

.a-figures summary::before {
  content: '+ ';
  color: var(--warm);
}

.a-figures[open] summary::before {
  content: '- ';
}

.a-figures summary:hover {
  color: var(--bone);
}

.a-figures .a-table {
  margin-top: 0.6rem;
}

.a-figures .a-chart,
.a-figures .a-table {
  min-width: 0;
}

/* --------------------------------------------------------------------------
   9. Live now
   -------------------------------------------------------------------------- */

.a-live-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.a-live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--warm);
  flex: none;
}

/* The pulse is the one moving thing in the whole panel, and it earns its place:
   it is what distinguishes a live figure from a stale one at a glance. It stops
   entirely for anybody who has asked their system for less motion, and it rests
   fully visible, so switching it off loses nothing but the movement. */
@media (prefers-reduced-motion: no-preference) {
  .a-live-dot.is-live {
    animation: a-pulse 2.4s ease-in-out infinite;
  }
}

@keyframes a-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.a-live-dot.is-quiet {
  background: var(--bone-faint);
}

/* --------------------------------------------------------------------------
   10. The sign-in screen
   -------------------------------------------------------------------------- */

.a-signin {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 2rem var(--gutter);
}

.a-signin-card {
  width: 100%;
  max-width: 23rem;
  background: var(--ink-raised);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 2rem 1.75rem 1.75rem;
}

.a-signin-mark {
  width: 2.1rem;
  height: 2.1rem;
  color: var(--warm);
  margin-bottom: 1.1rem;
}

.a-signin h1 {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.015em;
}

.a-signin p {
  margin-top: 0.4rem;
  font-size: 0.85rem;
  color: var(--bone-dim);
}

.a-field {
  margin-top: 1.1rem;
}

.a-field label {
  display: block;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--bone-dim);
  margin-bottom: 0.35rem;
}

.a-field input {
  width: 100%;
  padding: 0.6rem 0.7rem;
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: 6px;
  color: var(--bone);
  font-family: var(--ui);
  font-size: 0.95rem;
}

.a-field input:focus-visible {
  outline: 2px solid var(--bone);
  outline-offset: 1px;
  border-color: transparent;
}

.a-button {
  margin-top: 1.2rem;
  width: 100%;
  padding: 0.65rem 1rem;
  background: var(--bone);
  color: var(--ink);
  border: 1px solid var(--bone);
  border-radius: 6px;
  font-family: var(--ui);
  font-size: 0.9rem;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.15s var(--ease-soft), color 0.15s var(--ease-soft);
}

.a-button:hover {
  background: transparent;
  color: var(--bone);
}

.a-button.is-quiet {
  width: auto;
  margin-top: 0;
  background: transparent;
  color: var(--bone);
  border-color: var(--line);
}

.a-button.is-quiet:hover {
  border-color: var(--bone);
}

/* The refusal. THE SENTENCE IS WHAT SAYS WHAT IS WRONG and the colour only
   confirms it, which is the same rule the contact form follows. */
.a-alert {
  margin-top: 1rem;
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--fall);
  border-radius: 6px;
  color: var(--fall);
  font-size: 0.82rem;
}

.a-alert.is-ok {
  border-color: var(--rise);
  color: var(--rise);
}

/* --------------------------------------------------------------------------
   11. Settings
   -------------------------------------------------------------------------- */

.a-setting {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--line-soft);
}

.a-setting:last-child {
  border-bottom: 0;
  padding-bottom: 0;
}

.a-setting h3 {
  font-size: 0.88rem;
  font-weight: 700;
}

.a-setting p {
  margin-top: 0.25rem;
  max-width: 34rem;
  font-size: 0.8rem;
  color: var(--bone-dim);
}

.a-setting form {
  flex: none;
}

.a-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: 0.75rem;
}

.a-fact {
  padding: 0.7rem 0.8rem;
  background: var(--ink);
  border: 1px solid var(--line-soft);
  border-radius: 6px;
}

.a-fact dt {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--bone-dim);
}

.a-fact dd {
  margin: 0.2rem 0 0;
  font-size: 1.05rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   12. Print
   -------------------------------------------------------------------------- */

@media print {
  .a-header,
  .a-ranges,
  .a-footer,
  .a-signout {
    display: none;
  }

  body.a-body {
    background: #fff;
    color: #111;
  }

  .a-panel,
  .a-stat {
    background: #fff;
    border-color: #ccc;
    break-inside: avoid;
  }
}
