/* Modernist — design-system tokens and component classes. This file is the source of truth for the system's look; retune it here and see DOC_AkOOre/DOC_DESIGN_UI_KIT.md. */

:root {
  --color-bg: #f3f2f2;
  --color-surface: #eae9e9;
  --color-text: #201e1d;
  --color-accent: #ec3013;
  --color-accent-2: #e15b47;
  --color-divider: color-mix(in srgb, #201e1d 40%, transparent);

  /* Tonal ramps — generated in OKLCH on one shared lightness scale, so the
     same step of any role matches the others in visual value. */
  --color-neutral-100: #f8f4f4;
  --color-neutral-200: #eae7e7;
  --color-neutral-300: #d7d3d3;
  --color-neutral-400: #bab6b6;
  --color-neutral-500: #9b9797;
  --color-neutral-600: #7d7979;
  --color-neutral-700: #605d5d;
  --color-neutral-800: #444141;
  --color-neutral-900: #2d2b2b;

  --color-accent-100: #fff2ef;
  --color-accent-200: #ffe0d9;
  --color-accent-300: #ffc4b8;
  --color-accent-400: #ff9783;
  --color-accent-500: #ff563c;
  --color-accent-600: #dd2b0f;
  --color-accent-700: #ae1800;
  --color-accent-800: #7c1405;
  --color-accent-900: #4d170e;

  --color-accent-2-100: #fff2ef;
  --color-accent-2-200: #ffe0da;
  --color-accent-2-300: #ffc4b9;
  --color-accent-2-400: #ff9784;
  --color-accent-2-500: #ef6853;
  --color-accent-2-600: #c94b39;
  --color-accent-2-700: #9e3526;
  --color-accent-2-800: #71261b;
  --color-accent-2-900: #471d16;

  --font-heading: "Archivo", system-ui, sans-serif;
  --font-heading-weight: 800;
  --font-body: "Archivo", system-ui, sans-serif;

  --space-1: 4.0px;
  --space-2: 8.0px;
  --space-3: 12.0px;
  --space-4: 16.0px;
  --space-6: 24.0px;
  --space-8: 32.0px;

  --radius-sm: 0px;
  --radius-md: 0px;
  --radius-lg: 0px;

  /* Elevation — derived from the ground: soft ink-tinted shadows on a
     light theme, a hairline edge + ambient darkness on a dark one. */
  --shadow-sm: 0 1px 2px color-mix(in srgb, #2d2b2b 14%, transparent);
  --shadow-md: 0 3px 10px color-mix(in srgb, #2d2b2b 16%, transparent);
  --shadow-lg: 0 12px 32px color-mix(in srgb, #2d2b2b 22%, transparent);
}

body {
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
}
h1, h2, h3, h4 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); }

.grayscale{filter:grayscale(1) contrast(1.08)}

/* ══════════════════════════════════════════════════════════════════════════
   Components — built with the tokens above. Plain CSS
   on plain HTML: no JavaScript, no build step. Each class is documented in
   DOC_AkOOre/DOC_DESIGN_UI_KIT.md.
   ══════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }
body { margin: 0; font-size: 15px; line-height: 1.55; font-weight: 400; }
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  line-height: 1.12; letter-spacing: -0.015em; margin: 0 0 var(--space-2);
}
h1 { font-size: 42px; }
h2 { font-size: 32px; }
h3 { font-size: 25px; }
h4 { font-size: 20px; }
h5 { font-size: 16px; }
h6 { font-size: 13px; }
h6 { letter-spacing: 0.08em; text-transform: uppercase; }
p { margin: 0 0 var(--space-3); }
a { color: var(--color-accent); text-underline-offset: 3px; }
img { display: block; max-width: 100%; }
figure { margin: 0; }
figcaption {
  font-size: 11px; margin-top: var(--space-1);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.text-muted { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
:focus { outline: none; }
:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--color-accent) 30%, transparent); }

/* — rules — */
.hr {
  height: 2px; border: 0; margin: var(--space-4) 0;
  background: var(--color-divider);
}

/* — buttons — */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; text-decoration: none;
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 13px; line-height: 1.2; color: var(--color-text);
  background: transparent; border: 1px solid transparent;
  padding: calc(var(--space-2) * 0.85) var(--space-3);
  border-radius: var(--radius-md);
}
a.btn { text-decoration: none; }
.btn svg { display: block; }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn-primary { background: var(--color-accent); color: var(--color-bg); }
.btn-primary:hover { background: var(--color-accent-600); }
.btn-primary:active { background: var(--color-accent-700); }
.btn-secondary { border-color: var(--color-divider); }
.btn-secondary:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.btn-secondary:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.btn-ghost { color: var(--color-accent); padding-inline: var(--space-1); }
.btn-ghost:hover { background: color-mix(in srgb, var(--color-accent) 10%, transparent); }
.btn-ghost:active { background: color-mix(in srgb, var(--color-accent) 18%, transparent); }
.btn-icon { width: 34px; height: 34px; padding: 0; }
.btn-block { width: 100%; margin-top: var(--space-2); justify-content: flex-start; text-align: left; }

/* — page menu — */
/* The row of link buttons every page shows under the header (between the
   breadcrumbs and the h1): the sibling pages of the current section plus
   its primary actions. The current page's button is .btn-primary with
   aria-current="page", the others .btn-secondary. No "back" links — the
   breadcrumbs above already walk back up. See DOC_DESIGN_UI_KIT.md §4.3. */
.page-menu {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  margin: 0 0 var(--space-4);
}
/* Page-level actions (Edit, Add …) sit at the right edge, visually apart
   from the navigation links; they come last in the markup. */
.page-menu .page-menu-action { margin-left: auto; }
.page-menu .page-menu-action ~ .page-menu-action { margin-left: 0; }
/* Attention dot on a menu button (the Setup button while the website's
   setup checklist is incomplete). */
.page-menu .menu-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 999px;
  background: var(--color-accent); margin-left: var(--space-1);
  vertical-align: middle;
}

/* — page menu drop-downs — */
/* The websites section groups its twenty pages into <details> drop-downs
   (websites/menu.py builds them). <details>/<summary> rather than a
   hand-rolled widget: keyboard, Escape and the open/closed state come from
   the browser, and the menu still works with no JavaScript at all —
   static/js/page_menu.js only adds "opening one closes the others" and
   "clicking outside closes". See DOC_DESIGN_UI_KIT.md §4.3. */
/* Reset first: the generic `details {}` rule further down (the FAQ-style
   collapsibles' 2px border, background and padding) matches this <details>
   too — left alone, it drew its own border around the same box the
   .btn-secondary summary already borders, which is the "double border"
   this undoes. */
.page-menu .menu-group {
  position: relative;
  border: 0; background: none; padding: 0; margin: 0;
}
.page-menu .menu-group > summary {
  list-style: none; user-select: none;
}
.page-menu .menu-group > summary::-webkit-details-marker { display: none; }
.page-menu .menu-summary-label { white-space: nowrap; }
/* The caret rotates with the open state — the one visual cue that these
   buttons hold something rather than navigate. */
.page-menu .menu-caret {
  width: 0; height: 0; flex: none; margin-left: 2px;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform 120ms ease;
}
.page-menu .menu-group[open] > summary .menu-caret { transform: rotate(180deg); }
/* A group whose every destination is still empty: same greying as its
   items, and it still opens — the reasons inside are the point. */
.page-menu .menu-group.is-empty > summary { opacity: 0.45; }

.page-menu .menu-panel {
  position: absolute; z-index: 30; top: calc(100% + 4px); left: 0;
  min-width: 220px; max-width: min(92vw, 380px);
  display: flex; flex-direction: column; padding: var(--space-1);
  background: var(--color-surface);
  border-radius: var(--radius-md);
  box-shadow: 0 8px 24px rgb(0 0 0 / 18%);
}
/* A panel that would open past the right edge is nudged back inside by
   static/js/page_menu.js (a margin-left it sets on open). Deliberately not
   a CSS rule keyed on position in the row: this menu WRAPS, so "the last
   groups are on the right" is false the moment the row breaks — and the
   rule that assumed it pushed them off the LEFT edge instead. */
.page-menu .menu-item {
  display: block; padding: 7px 10px; border-radius: var(--radius-md);
  font-size: 13px; line-height: 1.3; color: var(--color-text);
  text-decoration: none;
}
a.menu-item:hover { background: color-mix(in srgb, var(--color-text) 8%, transparent); }
.page-menu .menu-item.is-current {
  background: var(--color-accent); color: var(--color-bg);
}
/* No data behind it yet: a <span>, not a link — nothing to click, and the
   title attribute says what is missing and who fills it in. */
.page-menu .menu-item.is-disabled {
  color: color-mix(in srgb, var(--color-text) 40%, transparent);
  cursor: not-allowed;
}
.page-menu .menu-sep {
  height: 1px; border: 0; margin: var(--space-1) 0;
  background: var(--color-divider);
}

/* — report contents plate — */
/* The navigation of every report that has several sections: one full-width
   bar in ink naming the section you are reading, which opens into the whole
   table of contents. It replaced the 240px sticky rail these reports used to
   carry on their left — the rail cost the tables a quarter of the page on
   every view, and the tables are what a report is for.
   <details>/<summary> again, for the same reasons as the page menu: the
   open state, Escape and the keyboard come from the browser, and the plate
   works with no JavaScript at all. See DOC_DESIGN_UI_KIT.md §4.8. */
.report-contents { margin: 0 0 var(--space-4); border: 0; padding: 0;
  background: none; }
/* The bar is deep brand red, NOT the ink the rest of the app reverses out
   with — the market demand hero, the poster closes and the doc's own callouts
   are all `--color-text`, and a reader who meets a fourth black band stops
   being able to tell which one is the navigation. Two steps darker than
   `--color-accent` so it never competes with a .btn-primary for the eye,
   and 6.4:1 under `--color-bg` text. */
.report-contents > summary {
  list-style: none; user-select: none; cursor: pointer;
  display: flex; align-items: center; gap: var(--space-3);
  background: var(--color-accent-700); color: var(--color-bg);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 14px;
}
.report-contents > summary::-webkit-details-marker { display: none; }
.report-contents > summary:hover { background: var(--color-accent-800); }
/* Where you are, in three parts: the rank, the title, its mark. */
.rc-kicker { font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0.65; white-space: nowrap; }
.rc-now { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* On the bar the good/warn/bad ramp has no contrast left — the mark up here
   is tinted, and the colour-coded ones live in the panel below. */
.rc-now-score { color: var(--color-accent-200); white-space: nowrap; }
.rc-hint { font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  opacity: 0.65; white-space: nowrap; }
.rc-caret { width: 0; height: 0; flex: none;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 6px solid currentColor; transition: transform 120ms ease; }
.report-contents[open] > summary .rc-caret { transform: rotate(180deg); }
@media (max-width: 700px) { .rc-hint { display: none; } }

/* Multi-column rather than a grid: a table of contents has to read down a
   column and then across, which is what columns do and grid does not. */
.rc-panel {
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-top: 0;
  padding: var(--space-4);
  columns: 250px 4; column-gap: var(--space-6);
}
.rc-panel a {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-3); break-inside: avoid;
  padding: 5px 8px; margin: 0 0 1px;
  font-size: 13px; line-height: 1.3;
  color: var(--color-text); text-decoration: none;
}
.rc-panel a:hover { background: var(--color-neutral-300); }
.rc-panel a[aria-current] {
  background: var(--color-accent); color: var(--color-bg); font-weight: 600;
}
.rc-panel a[aria-current] .rc-score { color: var(--color-bg); }
/* On a one-page view every entry is an anchor, so nothing is "the current
   page" — a small script marks the section you have scrolled to instead, and
   it gets a rule rather than the filled accent, which stays the answer to
   "which URL am I on". */
.rc-panel a.rc-here { font-weight: 600;
  box-shadow: inset 2px 0 0 var(--color-accent); }
/* The entries that are not sections — the overview, the action plan, the
   whole-report view — are set apart by a rule rather than a column of their
   own, so the sections keep flowing evenly across the columns. */
.rc-panel .rc-aside { border-top: 1px solid var(--color-divider);
  margin-top: var(--space-2); padding-top: var(--space-2); }
.rc-panel .rc-aside + .rc-aside { border-top: 0; margin-top: 0;
  padding-top: 5px; }
.rc-folio { font-family: var(--font-heading); font-size: 10px;
  letter-spacing: 0.06em; opacity: 0.5; flex: none; }
.rc-panel a[aria-current] .rc-folio { opacity: 0.75; }
.rc-label { flex: 1; min-width: 0; }
.rc-score { font-weight: 600; white-space: nowrap; }
.rc-good { color: #1f9d4d; }
.rc-warn { color: #e39a1b; }
.rc-bad  { color: #dc2f18; }

/* — social login (allauth provider buttons) — */
.social-divider {
  display: flex; align-items: center; gap: var(--space-3);
  margin: var(--space-4) 0;
  font-size: 12px; letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.social-divider::before, .social-divider::after {
  content: ""; flex: 1; height: 1px; background: var(--color-divider);
}
.social-list { display: flex; flex-direction: column; gap: var(--space-2); }
.social-provider { margin: 0; }
.btn-social {
  width: 100%; gap: 10px; font-size: 14px;
  background: var(--color-surface); border-color: var(--color-divider);
}
.btn-social:hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.btn-social:active { background: color-mix(in srgb, var(--color-text) 14%, transparent); }
.social-icon { width: 18px; height: 18px; flex: none; }

/* — forms — */
.field > label {
  display: block; font-size: 12px; margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}
.input {
  width: 100%; min-height: 36px; padding: 6px 10px; font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.input:hover { border-color: color-mix(in srgb, var(--color-text) 45%, transparent); }
.input:focus-visible { border-color: var(--color-accent); outline-offset: 0; }
textarea.input { min-height: 90px; resize: vertical; }
.radio { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; font-size: 14px; }
.radio input, .seg-opt input {
  position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none;
}
.radio .dot {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 1.5px solid var(--color-divider);
}
.radio:hover .dot { border-color: var(--color-accent); }
.radio input:checked + .dot {
  border-color: var(--color-accent); background: var(--color-accent);
  box-shadow: inset 0 0 0 4px var(--color-bg);
}
.radio input:focus-visible + .dot { outline: 2px solid var(--color-accent); outline-offset: 2px; }
.seg {
  display: inline-flex; overflow: hidden;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
}
.seg-opt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; font-size: 13px; cursor: pointer;
}
.seg-opt + .seg-opt { border-left: 1px solid var(--color-divider); }
.seg-opt:has(input:checked) { background: var(--color-accent); color: var(--color-bg); }
.seg-opt:not(:has(input:checked)):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.seg-opt:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }
/* The same control built from links instead of radios — for the choices a
   page carries in its querystring (which view, which order) rather than in
   a form. State is aria-current, like every other navigation control here. */
a.seg-opt { color: inherit; text-decoration: none; }
a.seg-opt[aria-current] { background: var(--color-accent); color: var(--color-bg); }
a.seg-opt:not([aria-current]):hover { background: color-mix(in srgb, var(--color-text) 7%, transparent); }

/* — cards — */
.card {
  display: flex; flex-direction: column; gap: var(--space-2);
  padding: var(--space-3); border-radius: var(--radius-md); background: var(--color-surface);
}
.card-kicker { font-size: 10px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--color-accent); }
.card-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 17px; line-height: 1.2;
}
.card-body { margin: 0; font-size: 13px; opacity: 0.8; flex: 1; }
.card-meta {
  display: flex; align-items: center; gap: 6px; font-size: 11px;
  color: color-mix(in srgb, var(--color-text) 50%, transparent);
}
.elev-sm { box-shadow: var(--shadow-sm); }
.elev-md { box-shadow: var(--shadow-md); }
.elev-lg { box-shadow: var(--shadow-lg); }

/* — tags — */
.tag {
  display: inline-flex; align-items: center; font-size: 11px;
  letter-spacing: 0.02em; padding: 3px 10px;
  border-radius: calc(var(--radius-md) * 0.75);
}
.tag-accent { background: var(--color-accent-100); color: var(--color-accent-800); }
.tag-accent-2 { background: var(--color-accent-2-100); color: var(--color-accent-2-800); }
/* A step DOWN the same ramp rather than a third colour family — and the only
   one of the three you can actually tell apart, since --color-accent-100 and
   --color-accent-2-100 are the same hex (#fff2ef). Worth fixing accent-2
   separately; not this change. */
.tag-accent-3 { background: var(--color-accent-200); color: var(--color-accent-900); }
.tag-neutral { background: var(--color-neutral-100); color: var(--color-neutral-800); }
.tag-outline { border: 1px solid var(--color-accent); color: var(--color-accent); }

/* — navigation — */
.nav {
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-bottom: 2px solid var(--color-divider);
}
.nav-brand {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 18px; margin-right: auto;
}
.nav a { color: inherit; text-decoration: none; font-size: 14px; }
.nav a:hover, .nav a[aria-current='page'] { color: var(--color-accent); }

/* — tables — */
/* border-collapse stays separate (not collapse) because collapsed borders
   do not travel with the sticky heading cells below; with only bottom
   borders in play the two models render identically. */
.table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.table th {
  text-align: left; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent);
  padding: var(--space-2); border-bottom: 2px solid var(--color-divider);
}
/* Sticky heading row: the labels stay readable while a long table scrolls —
   against the page for bare tables, inside the scrollport for tables in a
   capped .seo-table-wrap (the full-table pages). The th paints its own
   surface so the rows do not show through it. */
.table thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--color-surface);
}
@media print { .table thead th { position: static; } }
.table td {
  padding: var(--space-2);
  border-bottom: 1px solid var(--color-divider);
}
.table tbody tr:hover { background: color-mix(in srgb, var(--color-text) 4%, transparent); }
/* Click-to-sort heading (static/js/table_sort.js injects the <button>; on
   the server-sorted full-table pages the same class sits on an <a>). */
.seo-sort-th { display: inline-flex; align-items: baseline; gap: 4px;
  background: none; border: 0; padding: 0; font: inherit; color: inherit;
  cursor: pointer; text-align: inherit; text-decoration: none; }
.seo-sort-th:hover { text-decoration: underline; }
.seo-sort-arrow { font-size: 9px; opacity: 0.45; }
.seo-sort-th[aria-current] .seo-sort-arrow { opacity: 1; }
.table th[aria-sort] { color: var(--color-text); }
/* Right-aligned numeric columns read better with the arrow on the left. */
.num .seo-sort-th { flex-direction: row-reverse; }

/* — ranked list — */
/* The list rendering of a ranked table: one card per row, the rank spelled
   out, the two scores that decide something given room, and the rest as
   labelled facts. It exists because a fourteen-column table does not fit a
   screen — it pushed 583 px off the side of its scrollport and took the row's
   name with it — and because these lists are ORDERED ("closest business
   first"), which a grid never says out loud. The table stays one click away
   for reading a single figure down the whole list; see
   DOC_TEMPLATES_LISTS_TABLES_EMBEDED.md.

   The tier colours are the status palette of _seo_report_styles.html
   (good #1f9d4d, to improve #e39a1b, critical #dc2f18), repeated here as
   that file repeats them — the badges inside a card come from it. */
.rank-list { list-style: none; margin: 0; padding: 0;
  display: flex; flex-direction: column; gap: var(--space-2); }
.rank-item {
  display: grid; align-items: start;
  grid-template-columns: 2.4rem minmax(150px, 1.7fr) 11.5rem 11.5rem;
  grid-template-areas: "num id score-a score-b" ". facts facts facts";
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3);
  background: var(--color-neutral-100);
  border: 1px solid var(--color-divider);
  border-left: 4px solid var(--color-neutral-400);
  border-radius: var(--radius-md);
}
.rank-item:hover { background: var(--color-surface); }
/* The left edge carries the verdict, so the shape of the list is readable
   before a single figure is. */
.rank-item--good { border-left-color: #1f9d4d; }
.rank-item--warn { border-left-color: #e39a1b; }
.rank-item--bad { border-left-color: #dc2f18; }
.rank-num { grid-area: num; font-size: 17px; font-weight: 700; text-align: right;
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
  font-variant-numeric: tabular-nums; }
.rank-id { grid-area: id; min-width: 0; }
.rank-title { font-weight: 600; overflow-wrap: anywhere; }
.rank-visit { margin-left: var(--space-1); text-decoration: none; }
.rank-score--a { grid-area: score-a; }
.rank-score--b { grid-area: score-b; }
.rank-label { display: block; font-size: 10px; letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 60%, transparent); }
.rank-value { font-size: 17px; font-weight: 700; line-height: 1.2;
  font-variant-numeric: tabular-nums; }
.rank-score .seo-meter { width: 100%; margin: 3px 0 2px; }
/* Everything that did not earn a column of its own: still labelled, still
   in the words the table headings and the CSV use. */
.rank-facts { grid-area: facts; display: flex; flex-wrap: wrap; gap: var(--space-1); }
.rank-fact { display: inline-flex; align-items: center; gap: var(--space-1);
  font-size: 12px; padding: 2px 8px;
  border: 1px solid var(--color-divider); border-radius: var(--radius-md);
  background: var(--color-bg); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.rank-fact-label { color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.rank-fact b { font-weight: 700; }
/* A figure whose table cell pairs a meter with the number keeps the pair
   here, inline — the report's .seo-check-score is a block flex row, which
   would break a chip in two. */
.rank-fact .seo-check-score { display: inline-flex; vertical-align: middle; gap: var(--space-1); }
.rank-fact .seo-meter { width: 38px; height: 6px; }
.rank-fact--dim { background: var(--color-neutral-200); }
.rank-fact--empty { opacity: 0.6; }
/* A chip carrying a percentage draws the percentage: a black rule along the
   bottom of the box, as wide as the figure — so a column of chips is
   comparable at a glance without reading four numbers. The chip clips it, so
   the rule stops inside the rounded corners and reads as the bottom border
   filled in up to the score. --pct is set inline, per chip. */
.rank-fact--pct { position: relative; overflow: hidden; }
.rank-fact--pct::after { content: ""; position: absolute; left: 0; bottom: 0;
  height: 2px; width: var(--pct, 0%); background: var(--color-text); }
/* Not compared yet: kept in the list at the bottom, greyed rather than hidden
   — "no score stored" is a state the reader needs to see. */
.rank-item--unscored { opacity: 0.75; }
/* A card that carries the row's actions (a button, a form) rather than only
   its identity link: they take a column of their own down the right edge,
   spanning both rows, so the facts still get the full width under the
   identity. */
.rank-item--actions {
  grid-template-columns: 2.4rem minmax(150px, 1.7fr) 11.5rem 11.5rem auto;
  grid-template-areas: "num id score-a score-b act" ". facts facts facts act";
}
.rank-act { grid-area: act; display: flex; flex-direction: column;
  gap: var(--space-2); align-items: stretch; }
.rank-act form { margin: 0; }
.rank-act .btn { width: 100%; justify-content: center; }
/* The row of view / sort controls above a ranked list. Sits where the table
   headings would be, because it does the job they do. */
.list-controls { display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2); margin-bottom: var(--space-2); }
.list-controls-label { font-size: 12px;
  color: color-mix(in srgb, var(--color-text) 55%, transparent); }
@media (max-width: 720px) {
  .rank-item { grid-template-columns: 2.2rem 1fr;
    grid-template-areas: "num id" ". score-a" ". score-b" ". facts"; }
  .rank-item--actions { grid-template-columns: 2.2rem 1fr;
    grid-template-areas: "num id" ". score-a" ". score-b" ". facts" ". act"; }
}
@media print {
  .list-controls, .rank-act { display: none !important; }
  .rank-item { break-inside: avoid; page-break-inside: avoid; }
  /* Navigation, not content: the printed report carries its own contents
     page and nothing on paper is clickable. */
  .report-contents { display: none !important; }
}

/* — editable sheet — */
/* A .table whose cells ARE the inputs: the grid lines come from the table and
   the controls inside are borderless, so a row reads as one row instead of a
   stack of boxes. Rows are added, removed and reordered by
   static/js/sheet_table.js; without it the table still works — the blank row
   at the bottom is a new item and clearing a row deletes it.

   Selectors are doubled up (.sheet-table .sheet-input, not .sheet-input) to
   outrank the generic `form input[type=text]` block further down this file,
   which is more specific than a lone class. */
.sheet-table td { padding: 0; vertical-align: top; }
.sheet-table tbody tr:hover { background: none; }
.sheet-table .sheet-input {
  width: 100%; min-height: 0; padding: var(--space-2); font: inherit;
  font-size: 14px; color: var(--color-text); caret-color: var(--color-accent);
  background: transparent; border: 0; border-radius: 0;
}
.sheet-table .sheet-input:focus-visible {
  background: var(--color-surface);
  outline: 2px solid var(--color-accent); outline-offset: -2px;
}
.sheet-table textarea.sheet-input { display: block; resize: vertical; min-height: 38px; }
/* Numbers right-aligned like every other numeric column in the kit, and
   without the spinner arrows — they steal a third of a narrow cell. */
.sheet-table .sheet-input--num { text-align: right; -moz-appearance: textfield; }
.sheet-table .sheet-input--num::-webkit-outer-spin-button,
.sheet-table .sheet-input--num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Column widths: the name and the description carry the text, the numbers
   stay as narrow as their heading. */
.sheet-cell--label { width: 26%; }
.sheet-cell--description { width: auto; }
.sheet-cell--number { width: 8.5rem; }
.sheet-table th.sheet-cell--number { text-align: right; }
.sheet-actions { width: 1%; white-space: nowrap; text-align: right; padding: var(--space-1); }
.sheet-btn {
  background: none; border: 0; cursor: pointer; font: inherit; font-size: 13px;
  line-height: 1; padding: 5px 6px; border-radius: var(--radius-md);
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.sheet-btn:hover { color: var(--color-accent); background: color-mix(in srgb, var(--color-text) 7%, transparent); }
.sheet-btn--danger:hover { color: #931b09; }
.sheet-foot { display: flex; align-items: baseline; gap: var(--space-3); margin-top: var(--space-2); }
/* Add, remove and move do nothing without static/js/sheet_table.js, so they
   are hidden until it has run and marked the sheet live — the table itself
   still edits, adds and deletes without them (see that file's header). Hiding
   only in the not-live state leaves each button its own display value once it
   works. */
[data-sheet]:not(.sheet--live) [data-sheet-add],
[data-sheet]:not(.sheet--live) [data-sheet-remove],
[data-sheet]:not(.sheet--live) [data-sheet-move] { display: none; }
/* The per-row errors sit inside a cell, so they must not keep the list
   indent they get in a .field. */
.sheet-table .errorlist { padding: 0 var(--space-2); list-style: none; font-size: 12px; }

/* — pagination — */
/* Numbered nav under a long list or table. The current page is a
   .btn.btn-secondary <span>, the others .btn.btn-ghost links, so the
   control inherits the button sizing instead of inventing its own. */
.pagination {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  margin-top: var(--space-4);
}
.pagination .pagination-gap {
  padding: 0 var(--space-1);
  color: color-mix(in srgb, var(--color-text) 45%, transparent);
}

/* — dialog — */
.dialog-backdrop {
  position: fixed; inset: 0; display: grid; place-items: center;
  padding: var(--space-4); z-index: 100;
  background: color-mix(in srgb, var(--color-neutral-900) 50%, transparent);
}
.dialog-backdrop[hidden] { display: none; }
.dialog {
  width: min(440px, 100%); display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-4); border-radius: var(--radius-lg);
  background: var(--color-surface); box-shadow: var(--shadow-lg);
}
.dialog-title {
  font-family: var(--font-heading); font-weight: var(--font-heading-weight);
  font-size: 20px;
}
.dialog-body { font-size: 14px; opacity: 0.85; }
.dialog-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-2); }

/* Google Fonts loaded in base.html — Archivo 400/600/800 */

/* — layout — */
.page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-size: 16px;
  line-height: 26px;
}
.site-header {
  display: flex;
  align-items: center;
  gap: 32px;
  flex-wrap: wrap;
  padding: 16px clamp(20px, 5vw, 72px);
  border-bottom: 2px solid var(--color-divider);
  background: var(--color-bg);
}
.site-nav {
  display: flex;
  align-items: center;
  gap: 28px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.site-nav a {
  color: var(--color-text);
  text-decoration: none;
}
.site-nav a:hover,
.site-nav a[aria-current='page'] {
  color: var(--color-accent-700);
}
.site-main {
  flex: 1;
  width: 100%;
  max-width: 960px;
  margin: 0 auto;
  padding: 48px clamp(20px, 5vw, 72px) 64px;
}
.site-main--wide { max-width: 1400px; }
.site-main--xwide { max-width: 1520px; }
.site-main--flush {
  max-width: none;
  padding: 0;
}
.site-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  justify-content: space-between;
  padding: 40px clamp(20px, 5vw, 72px);
  font-size: 13px;
  line-height: 28px;
  color: var(--color-neutral-700);
}
.site-footer a {
  color: inherit;
  text-decoration: none;
}
.site-footer a:hover { color: var(--color-accent-700); }
.site-footer-links { display: flex; gap: 24px; flex-wrap: wrap; }

/* — logo lockup — */
.logo {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 22px;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  gap: 1px;
  color: var(--color-text);
  text-decoration: none;
}
.logo svg { display: block; flex: none; }
.logo--lg { font-size: clamp(42px, 8vw, 72px); gap: 2px; }
.logo--lg svg { width: 0.82em; height: 0.82em; }

/* — page chrome helpers — */
.breadcrumbs {
  font-size: 13px;
  line-height: 1.4;
  margin: 0 0 var(--space-4);
  color: var(--color-neutral-700);
}
.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}
.breadcrumbs li {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
}
.breadcrumbs li + li::before {
  content: "›";
  color: var(--color-neutral-500);
}
.breadcrumbs a {
  color: inherit;
  text-decoration: none;
}
.breadcrumbs a:hover { color: var(--color-accent-700); text-decoration: underline; }
.breadcrumbs [aria-current="page"] {
  color: var(--color-text);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 44ch;
}
.kicker {
  font-size: 13px;
  line-height: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-700);
  margin: 0 0 var(--space-6);
}
.lead {
  color: var(--color-neutral-800);
  margin: 0 0 var(--space-6);
  font-size: 16px;
  line-height: 26px;
  max-width: 58ch;
}
.help {
  background: var(--color-surface);
  border: 2px solid var(--color-divider);
  padding: var(--space-4) var(--space-6);
  margin-bottom: var(--space-6);
}
.help h2 { font-size: 16px; margin-top: 0; }
.help ol { margin: var(--space-2) 0 0; padding-left: 1.25rem; }
.note {
  border-left: 3px solid var(--color-accent);
  background: var(--color-surface);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-4) 0;
  font-size: 0.95rem;
  color: var(--color-neutral-800);
}
.note.warn {
  border-left-color: var(--color-neutral-800);
  background: var(--color-neutral-100);
}
.messages { list-style: none; padding: 0; margin: 0 0 var(--space-6); }
.messages li {
  background: var(--color-surface);
  border: 2px solid var(--color-divider);
  border-left-width: 6px;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-3);
  font-weight: 600;
}
/* One colour per django.contrib.messages level, on the palette the reports
   already use for good/warn/bad — the result of an action must be readable
   as good or bad news before the sentence is read. */
.messages-success { border-color: #1f9d4d; background: #dcf5e4; color: #14652f; }
.messages-warning { border-color: #e39a1b; background: #fdeed4; color: #8a5a0a; }
.messages-error { border-color: #dc2f18; background: #fadfdb; color: #931b09; }
.messages-info,
.messages-debug { border-color: var(--color-neutral-600); }
.helptext {
  display: block;
  color: var(--color-neutral-700);
  font-size: 0.85rem;
  margin-top: var(--space-1);
}
.errorlist {
  color: var(--color-accent-800);
  margin: var(--space-1) 0 0;
  padding-left: 1.25rem;
}
code {
  background: var(--color-surface);
  padding: 0.1rem 0.3rem;
  font-size: 0.9em;
}

/* badges → tags */
.badge,
.tag {
  display: inline-flex;
  align-items: center;
  font-size: 11px;
  letter-spacing: 0.02em;
  padding: 3px 10px;
  border-radius: 0;
}
.badge.ok { background: var(--color-neutral-100); color: var(--color-neutral-800); }
.badge.todo { border: 1px solid var(--color-accent); color: var(--color-accent); }

ul.providers { list-style: none; padding: 0; margin: 0; }
ul.providers li {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-divider);
}
ul.providers a { color: var(--color-text); font-weight: 600; text-decoration: none; }
ul.providers a:hover { color: var(--color-accent-700); }
ul.providers a.btn { color: var(--color-bg); font-weight: var(--font-heading-weight); }
.provider-name { display: inline-flex; align-items: baseline; gap: var(--space-2); }
.provider-status {
  font-size: 11px;
  letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}

details {
  border: 2px solid var(--color-divider);
  background: var(--color-bg);
  padding: var(--space-3) var(--space-4);
  margin-top: var(--space-3);
}
details + details { margin-top: var(--space-2); }
details summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.9rem;
  font-family: var(--font-heading);
}
details p, details ul, details ol { font-size: 0.9rem; color: var(--color-neutral-800); }
details ul, details ol { padding-left: 1.15rem; }
dl.what { margin: var(--space-2) 0 0; font-size: 0.9rem; }
dl.what dt { font-weight: 600; margin-top: var(--space-3); }
dl.what dd { margin: var(--space-1) 0 0; color: var(--color-neutral-800); }

/* forms — Django as_div + allauth */
form .field,
form > div:has(> input),
form > div:has(> textarea),
form > div:has(> select),
form p:has(> input),
form p:has(> textarea),
form p:has(> select) {
  margin: 0 0 var(--space-4);
}
form label {
  display: block;
  font-size: 12px;
  margin-bottom: 5px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
  letter-spacing: 0.02em;
}
form input[type=text],
form input[type=password],
form input[type=email],
form input[type=url],
form input[type=number],
form textarea,
form select {
  width: 100%;
  min-height: 36px;
  padding: 6px 10px;
  font: inherit;
  font-size: 14px;
  color: var(--color-text);
  caret-color: var(--color-accent);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  border-radius: 0;
}
form textarea { min-height: 90px; resize: vertical; }
form input:hover,
form textarea:hover,
form select:hover {
  border-color: color-mix(in srgb, var(--color-text) 45%, transparent);
}
form input:focus-visible,
form textarea:focus-visible,
form select:focus-visible {
  border-color: var(--color-accent);
  outline: 2px solid var(--color-accent);
  outline-offset: 0;
}
form button[type=submit]:not([class]),
form button:not([class]),
.actions button:not([class]) {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  cursor: pointer;
  text-decoration: none;
  font-family: var(--font-heading);
  font-weight: var(--font-heading-weight);
  font-size: 13px;
  line-height: 1.2;
  color: var(--color-bg);
  background: var(--color-accent);
  border: 1px solid transparent;
  padding: calc(var(--space-2) * 0.85) var(--space-3);
  border-radius: 0;
  margin-top: var(--space-4);
}
form button[type=submit]:not([class]):hover,
form button:not([class]):hover { background: var(--color-accent-600); }
/* Checkbox/radio rows (allauth "Remember Me", Django as_p checkboxes): the
   generic `form label { display: block }` above stacks the caption on its own
   line and leaves a bare box under it. Lay the row out inline instead, and
   pull the control in front of its label — Django renders <label> first. */
form .field:has(> input[type=checkbox]),
form .field:has(> input[type=radio]),
form p:has(> input[type=checkbox]),
form p:has(> input[type=radio]),
form > div:has(> input[type=checkbox]),
form > div:has(> input[type=radio]) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}
form input[type=checkbox],
form input[type=radio] {
  order: -1;
  flex: none;
  width: 16px;
  height: 16px;
  min-height: 0;
  margin: 0;
  accent-color: var(--color-accent);
}
form p:has(> input[type=checkbox]) > label,
form p:has(> input[type=radio]) > label,
form .field:has(> input[type=checkbox]) > label,
form .field:has(> input[type=radio]) > label,
form > div:has(> input[type=checkbox]) > label,
form > div:has(> input[type=radio]) > label {
  display: inline;
  margin: 0;
  font-size: 14px;
  color: var(--color-text);
  letter-spacing: 0;
  cursor: pointer;
}
form p:has(> input[type=checkbox]) > .helptext,
form .field:has(> input[type=checkbox]) > .helptext { flex-basis: 100%; }
.keyword-checks ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.keyword-checks li {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.keyword-checks label {
  display: inline;
  margin: 0;
  font-size: 14px;
  color: var(--color-text);
  letter-spacing: 0;
}
.keyword-checks input[type=checkbox] {
  width: auto;
  min-height: 0;
}
.form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
  margin-top: var(--space-4);
}
.form-actions .btn { margin-top: 0; }

/* Multi-column field layout for dense edit screens */
.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}
.form-grid .field { margin-bottom: 0; }
.form-grid .field-span-2 { grid-column: 1 / -1; }
@media (max-width: 720px) {
  .form-grid { grid-template-columns: 1fr; }
  .form-grid .field-span-2 { grid-column: auto; }
}
.summary-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  font-size: 14px;
}
.summary-bar > div { min-width: 140px; }
.summary-bar dt {
  font-size: 11px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--color-text) 55%, transparent);
}
.summary-bar dd { margin: 2px 0 0; }
.readonly-value {
  font-family: ui-monospace, monospace;
  font-size: 13px;
  color: color-mix(in srgb, var(--color-text) 70%, transparent);
}

.card { margin-bottom: var(--space-6); padding: var(--space-4); }

/* — home / marketing — */
.hero {
  padding: 84px clamp(20px, 5vw, 72px) 64px;
  max-width: 1200px;
  margin: 0 auto;
}
.hero h1 {
  font-size: clamp(38px, 5vw, 64px);
  line-height: 1.06;
  letter-spacing: -0.02em;
  margin: var(--space-6) 0 0 -0.058em;
}
.hero .lead { margin-top: var(--space-8); }
.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-8);
}
.poster-close {
  background: var(--color-accent);
  color: var(--color-bg);
  padding: 56px clamp(20px, 5vw, 72px);
}
.poster-close .display {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: clamp(28px, 3.4vw, 44px);
  line-height: 1.06;
  letter-spacing: -0.015em;
  margin-left: -0.058em;
}
.poster-close .display span { display: block; }
.poster-close .btn-ghost {
  color: var(--color-bg);
  border: 1px solid var(--color-bg);
  margin-top: 36px;
}
.poster-close .btn-ghost:hover {
  background: color-mix(in srgb, var(--color-bg) 12%, transparent);
}

/* ============================================================
   Article system (ported from AAS) — search bar, cards, prose
   ============================================================ */

/* Header search bar — sits on the left, immediately after the logo, and
   grows into every pixel the rest of the header does not need. Growing is
   also what pins the nav, the reader controls, the language picker and the
   primary button to the right edge, so no auto margin here: an auto margin
   would swallow the free space before flex-grow ever saw it and the box
   would stay at its basis. */
.header-search { flex: 1 1 180px; min-width: 140px; }
.header-search .input { width: 100%; }

/* Header language selector — swaps the /xx/ URL prefix (script in base.html). */
.lang-select { flex: 0 0 auto; width: auto; max-width: 150px; }

/* Reader controls — the width and text-size cycles in the header. The
   choice is kept in a cookie (akoore_width / akoore_font) that an inline
   script in base.html replays onto <html> before the first paint.

   The width rules hang off html[data-width] so they outrank whatever a page
   picked in its {% block main_class %} (.site-main--wide / --xwide); without
   that the report pages would keep their 1520px cap and the button would do
   nothing. .site-main--flush is left alone — home.html wants edge-to-edge.

   Text size is a zoom rather than a font-size because the stylesheet sizes
   almost everything in px, which a root font-size would not touch. Zoom also
   scales the px caps above, so each width divides its target by the zoom to
   land on the same rendered width whatever the text size. */
.reader-controls { display: flex; align-items: center; gap: var(--space-1); flex: 0 0 auto; }
:root { --content-zoom: 1; }
html[data-font='s'] { --content-zoom: 0.88; }
html[data-font='l'] { --content-zoom: 1.15; }
html[data-font] .site-main { zoom: var(--content-zoom); }
html[data-width='full'] .site-main:not(.site-main--flush) { max-width: none; }
html[data-width='xwide'] .site-main:not(.site-main--flush) { max-width: calc(1520px / var(--content-zoom)); }
html[data-width='wide'] .site-main:not(.site-main--flush) { max-width: calc(1280px / var(--content-zoom)); }
html[data-width='narrow'] .site-main:not(.site-main--flush) { max-width: calc(960px / var(--content-zoom)); }
/* The "A" glyph mirrors the level it will leave you on. */
html[data-font='s'] #font-cycle { font-size: 11px; }
html[data-font='l'] #font-cycle { font-size: 19px; }

/* Responsive card grid for article listings and search results. */
.article-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-6);
}
.article-card {
  background: var(--color-surface);
  border: 1px solid var(--color-divider);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.article-card:hover { box-shadow: var(--shadow-md); }
.article-card a { color: inherit; text-decoration: none; }
.article-card-image {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  display: block;
  background: var(--color-neutral-200, #e8e6e5);
}
.article-card .card-title { font-size: 17px; line-height: 1.25; }
.article-card .card-body { flex: 1; }

/* Search results page. */
.search-results { margin-top: var(--space-6); }
.search-results .search-count { color: var(--color-text); opacity: .65; margin-top: var(--space-2); }

/* Article body typography (CKEditor5 HTML rendered with |safe). */
.article-prose { line-height: 1.65; }
.article-prose h2 {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 26px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: var(--space-8) 0 var(--space-4);
}
.article-prose h3 { font-weight: 600; font-size: 20px; margin: var(--space-6) 0 var(--space-3); }
.article-prose h3.faq-question {
  border-left: 3px solid var(--color-accent);
  padding-left: var(--space-3);
}
.article-prose p { margin: 0 0 var(--space-4); }
.article-prose p.faq-answer { margin-bottom: var(--space-6); }
.article-prose a { color: var(--color-accent); }
.article-prose img { max-width: 100%; height: auto; }
.article-prose ul, .article-prose ol { margin: 0 0 var(--space-4); padding-left: 1.4em; }
.article-prose blockquote {
  border-left: 3px solid var(--color-divider);
  margin: var(--space-4) 0;
  padding: var(--space-2) var(--space-4);
  color: var(--color-text);
  opacity: .8;
}
.article-prose .HTMLSectionBlock { max-width: 280px; margin: 0 var(--space-4) var(--space-3) 0; }
.article-prose .HTMLSectionBlock img { display: block; margin-bottom: var(--space-2); }

/* Article detail chrome. */
.article-hero-image { width: 100%; height: auto; display: block; margin: var(--space-6) 0; }
.article-toc {
  border: 1px solid var(--color-divider);
  background: var(--color-surface);
  padding: var(--space-4);
  margin: var(--space-6) 0;
}
.article-toc ol { margin: var(--space-2) 0 0; padding-left: 1.3em; }
.article-toc a { color: inherit; }
.related-articles { margin-top: var(--space-8); }

@media (max-width: 720px) {
  .header-search { flex-basis: 100%; order: 9; }
}

/* ============================================================
   Embedded tables — §4.5 of DOC_DESIGN_UI_KIT.md and
   DOC_AkOOre/DOC_TEMPLATES_LISTS_TABLES_EMBEDED.md.
   .table-tools is the CSV / XLSX / Expand / Full toolbar rendered by
   websites/_table_tools.html directly ABOVE every embedded table;
   .table-expanded is what its Expand button (table_tools.js) toggles on
   the table container; .table-help is the collapsed "What each column
   means" block (_table_columns_help.html) directly UNDER the table.
   ============================================================ */
.table-tools {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1);
  margin: var(--space-2) 0;
}
.table-tools-count { font-weight: 400; opacity: 0.7; }

/* The keyword search box of a list table (_table_search.html). It sits at
   the left of the toolbar and GROWS to eat every pixel the download
   buttons do not need, so long queries stay readable; the buttons keep the
   right edge they have on the tables that have no search. min-width: 0 on
   both the form and the input is what lets them shrink below the input's
   intrinsic size instead of overflowing the toolbar. */
.table-search {
  display: inline-flex; align-items: center; gap: var(--space-1);
  flex: 1 1 auto; min-width: 0; margin-right: auto;
}
.table-search .input {
  flex: 1 1 auto; width: auto; min-width: 0;
  padding: 2px 8px; font-size: 13px;
}
.table-search .btn { flex: 0 0 auto; }
.table-search-count { font-size: 13px; white-space: nowrap; }
@media (max-width: 720px) {
  .table-search { flex-basis: 100%; margin-right: 0; }
  .table-search .input { flex: 1; width: auto; }
}
@media print { .table-search { display: none !important; } }

/* Full-browser-width breakout. The container stays in the flow (so the
   page below does not jump) and slides left to the viewport edge; its own
   overflow-x keeps the page from scrolling sideways. The surface + shadow
   lift it above whatever sits in the escaped columns (e.g. the report's
   sticky TOC). */
.table-expanded {
  position: relative;
  z-index: 5;
  /* Breaks out of the content column to the full viewport. vw units ignore
     the text-size zoom on .site-main but the result is still scaled by it,
     so both terms divide by the zoom to stay pinned to the viewport edges. */
  width: calc((100vw - 2 * var(--space-4)) / var(--content-zoom));
  margin-left: calc(50% - (50vw - var(--space-4)) / var(--content-zoom));
  padding: var(--space-3);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  overflow-x: auto;
}

.table-help { margin-top: var(--space-2); font-size: 0.9rem; }
.table-help > summary {
  cursor: pointer;
  color: var(--color-accent);
  font-family: var(--font-heading);
}
.table-help ul { margin: var(--space-2) 0 0; padding-left: 1.4em; }
.table-help li { margin-bottom: var(--space-2); }
.table-help li:last-child { margin-bottom: 0; }

/* ============================================================
   Rich text (CKEditor 5) — §4.4 of DOC_DESIGN_UI_KIT.md
   One compact type scale for stored CKEditor HTML, shared by both
   modes so a field reads the same before and after Save:
   - read mode: wrap the `|safe` output in `.rich-text`
   - edit mode: `.ck-content` is the editable area of every
     CKEditor5Widget on pages that load this stylesheet
   Without this, the page-level h1-h6 scale (42/32/25px…) applies
   inside description fields, where headings are only section labels.
   ============================================================ */
.rich-text,
.ck.ck-content { font-size: 0.95rem; line-height: 1.55; }
.rich-text h1, .rich-text h2, .rich-text h3,
.rich-text h4, .rich-text h5, .rich-text h6,
.ck.ck-content h1, .ck.ck-content h2, .ck.ck-content h3,
.ck.ck-content h4, .ck.ck-content h5, .ck.ck-content h6 {
  font-size: 1rem; line-height: 1.3; margin: 0.8em 0 0.3em;
}
.rich-text p, .ck.ck-content p { margin: 0 0 0.6em; }
.rich-text ul, .rich-text ol,
.ck.ck-content ul, .ck.ck-content ol { margin: 0.3em 0 0.6em; padding-left: 1.3em; }
.rich-text > :first-child, .ck.ck-content > :first-child { margin-top: 0; }
.rich-text > :last-child, .ck.ck-content > :last-child { margin-bottom: 0; }

/* ============================================================
   Profile review (website infos) — §4.9 of DOC_DESIGN_UI_KIT.md
   A page that is read and signed rather than filled in: the stake
   first, the four parts one at a time, the signature last. The
   step rail and the panels degrade to jump links over a page with
   everything on screen when static/js/profile_steps.js is off.
   ============================================================ */
.profile-gate {
  background: var(--color-accent-800); color: var(--color-neutral-100);
  padding: var(--space-4) var(--space-6); margin: 0 0 var(--space-4);
}
.profile-gate-title {
  font-size: 20px; margin: 0 0 var(--space-1); color: inherit;
}
.profile-gate p { margin: 0; font-size: 13.5px; opacity: 0.88; max-width: 88ch; }
/* Validated: the same block, said quietly. Nothing is being withheld, so it
   states the fact rather than shouting a consequence. */
.profile-gate--ok {
  background: var(--color-surface); color: var(--color-neutral-800);
  border-left: 3px solid var(--color-accent);
}
.profile-gate--ok p { opacity: 1; }

.profile-steps {
  display: flex; flex-wrap: wrap;
  background: var(--color-text); color: var(--color-bg);
  margin: 0 0 var(--space-6);
}
/* flex-basis 0, not a width: four steps stay one row down to the phone
   breakpoint below, where they stack instead of wrapping 3 + 1. */
.profile-step {
  flex: 1 1 0; min-width: 0; padding: var(--space-2) var(--space-4);
  color: inherit; text-decoration: none;
  border-right: 1px solid color-mix(in srgb, var(--color-bg) 18%, transparent);
}
.profile-step:last-child { border-right: 0; }
.profile-step b {
  display: block; font-family: var(--font-heading);
  font-weight: var(--font-heading-weight); font-size: 13px;
}
.profile-step small { font-size: 11px; opacity: 0.6; }
.profile-step:hover { background: color-mix(in srgb, var(--color-bg) 12%, transparent); }
.profile-step[aria-current] { background: var(--color-accent); }
.profile-step[aria-current] small { opacity: 0.85; }
.profile-step.is-done b::before { content: "\2713\00a0"; }
/* A step whose panel holds a rejected field. Marked in the rail because the
   panel itself may be the hidden one — see profile_steps.js. */
.profile-step.has-errors b::after { content: "\00a0\26a0"; }
.profile-step.has-errors { background: var(--color-accent-700); }

/* One panel at a time — but only once the script has said so. Without it
   every panel stays on screen and the rail is four jump links. */
.profile-review--stepped .profile-panel { display: none; }
.profile-review--stepped .profile-panel.is-on { display: block; }
.profile-panel { outline: none; }
.profile-panel + .profile-panel { margin-top: var(--space-8); }
.profile-question { font-size: 26px; margin: 0 0 var(--space-2); }
.profile-lead { margin: 0 0 var(--space-4); font-size: 15px; max-width: 80ch; }
.profile-body {
  margin: 0 0 var(--space-3); font-size: 13px; max-width: 80ch;
  color: var(--color-neutral-800);
}
.profile-panel > details { margin-top: var(--space-4); }

.profile-nav {
  display: flex; align-items: center; gap: var(--space-2);
  margin-top: var(--space-6); padding-top: var(--space-4);
  border-top: 1px solid var(--color-divider);
}
.profile-nav-spacer { flex: 1; }

/* The signature: the one decision on this page that is not an edit. */
.profile-sign {
  display: flex; align-items: center; gap: var(--space-6); flex-wrap: wrap;
  background: var(--color-text); color: var(--color-bg);
  padding: var(--space-4) var(--space-6); margin-top: var(--space-6);
}
.profile-sign p { margin: 0; flex: 1 1 32ch; font-size: 13px; opacity: 0.85; max-width: 70ch; }
.profile-sign .btn { flex: none; }
.profile-sign--ok { background: var(--color-surface); color: var(--color-neutral-800); }
.profile-sign--ok p { opacity: 1; }
.profile-hidden-form { display: contents; }

@media (max-width: 640px) {
  .profile-step { flex: 1 1 100%; border-right: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--color-bg) 18%, transparent); }
  .profile-step:last-child { border-bottom: 0; }
}
