/* Reviewers - base layer. Everything reads from theme tokens, never raw hex, so a geo
   swap is one attribute on <html> and nothing else moves.

   Three things here are load-bearing for this network specifically:
   1. Logical properties everywhere (padding-inline, margin-inline-start, border-inline-start).
      Seven of the twenty geos are Arabic RTL; physical left/right would need a second
      stylesheet and would drift from it.
   2. `.rv-empty` is a real, styled state. The methodology says a missing value is left
      blank and never filled with an estimate, so "no data" has to look deliberate rather
      than broken - otherwise an author fills it in to make the page look finished.
   3. Semantic colours are fixed across all six characters. A verified licence and a
      regulator warning must read identically on every site, or the signal stops working. */

*{box-sizing:border-box}
body.rv{margin:0;background:var(--rv-bg);color:var(--rv-ink);font-family:var(--rv-ff);
  font-size:16px;line-height:1.5;-webkit-font-smoothing:antialiased}
.rv-wrap{max-width:var(--rv-wrap);margin:0 auto;padding-inline:var(--rv-gutter)}
/* Measured 02.10 across eight review sites: the readable ones hold their text in a column of
   725-998px and let only tables use the full width. A single 1240px column at a small size put
   us past 110 characters a line - denser to count, harder to read. Prose gets the column;
   tables, grids and fact tiles keep .rv-wrap.
   🚨 The class is .rv-readable, not .rv-col: .rv-col is the bar-chart column and capping its
   width silently flattened every chart in the kit. */
.rv-readable,.rv-sect>p,.rv-sect>ul,.rv-sect>ol,.rv-prose{max-width:min(var(--rv-colw),74ch)}
.rv-full{max-width:none;width:100%}
.rv h1,.rv h2,.rv h3,.rv h4{font-family:var(--rv-ff-d);font-weight:700;letter-spacing:-.02em;
  line-height:1.12;margin:0;color:var(--rv-ink)}
.rv h1{font-size:clamp(1.9rem,4vw,2.7rem)}
.rv h2{font-size:clamp(1.35rem,2.4vw,1.75rem)}
.rv h3{font-size:1.12rem}
.rv h4{font-size:.98rem}
.rv p{margin:0 0 9px}
.rv a{color:var(--rv-accent-deep);text-decoration-thickness:1px;text-underline-offset:2px}
.rv-lead{font-size:1.0rem;color:var(--rv-ink2);max-width:62ch}
.rv-dim{color:var(--rv-dim)}
.rv-sm{font-size:.94rem}
/* Numbers are tabular everywhere - columns of figures must line up on every site.
   The MONOSPACED face, though, is the typography axis: if `.rv-num` were mono in all four
   settings, "mono in numbers" would differ from the others in nothing and the axis would
   be decorative. Only `data-type="mono"` gets the mono face (see the axis block below). */
.rv-num,.rv-mono{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;
  font-weight:600;letter-spacing:.005em}
.rv-mono{font-family:var(--rv-ff-m);font-weight:inherit}

/* ---------- typography axis: one of four per site, set on <html data-type> ---------- */
/* `grotesk` is the default and needs no overrides to look right. It is still written
   out, because an axis whose first value is "the absence of rules" cannot be checked:
   conventions_check.py asks the stylesheet whether every promised value exists. */
[data-type="grotesk"] .rv h1,[data-type="grotesk"] .rv h2,
[data-type="grotesk"] .rv h3,[data-type="grotesk"] .rv h4{font-family:var(--rv-ff-d)}
[data-type="serif"] .rv h1,[data-type="serif"] .rv h2,[data-type="serif"] .rv h3{
  font-family:"Source Serif 4",Georgia,serif;letter-spacing:-.012em;font-weight:600}
[data-type="mono"] .rv .rv-num,[data-type="mono"] .rv td,[data-type="mono"] .rv .rv-stat-v,
[data-type="mono"] .rv .rv-bar-v,[data-type="mono"] .rv .rv-c-num{
  font-family:var(--rv-ff-m);font-variant-numeric:tabular-nums;letter-spacing:-.01em;
  font-weight:450}
[data-type="contrast"] .rv h1{font-size:clamp(2.4rem,6vw,4rem);letter-spacing:-.035em}
[data-type="contrast"] .rv h2{font-size:clamp(1.6rem,3.2vw,2.3rem);letter-spacing:-.03em}
/* The contrast setting pairs oversized display type with SMALLER body copy. Base is
   15px since the density contract, so this has to drop below it - at 15px the axis
   would differ in nothing. */
[data-type="contrast"] body.rv{font-size:15px}

/* ---------- RTL: seven of twenty geos. Fonts swap, direction is handled by logicals ---------- */
[dir="rtl"] body.rv{font-family:var(--rv-ff-ar)}
[dir="rtl"] .rv h1,[dir="rtl"] .rv h2,[dir="rtl"] .rv h3,[dir="rtl"] .rv h4{
  font-family:var(--rv-ff-ar-d);letter-spacing:0}
[dir="rtl"] .rv-num,[dir="rtl"] .rv-mono{direction:ltr;unicode-bidi:embed}

/* ---------- surfaces ---------- */
.rv-card{background:var(--rv-surface);border:1px solid var(--rv-line);
  border-radius:var(--rv-radius);box-shadow:var(--rv-shadow-sm)}
.rv-pad{padding:13px 15px}
.rv-sunk{background:var(--rv-sunk);border-radius:var(--rv-radius-sm)}
.rv-sect{padding-block:16px}
.rv-rule{height:1px;background:var(--rv-line);border:0;margin-block:12px}

.rv-eyebrow{display:inline-flex;align-items:center;gap:7px;font-family:var(--rv-ff-m);
  font-size:.68rem;letter-spacing:.15em;text-transform:uppercase;color:var(--rv-dim)}
.rv-eyebrow::before{content:"";width:5px;height:5px;border-radius:50%;
  background:var(--rv-accent);flex:none}

/* Specificity guard: `.rv a` (0,1,1) outranks a bare `.rv-btn-*` (0,1,0). Without this a
   button rendered as a link inherits the link colour and loses its contrast. */
.rv-btn{display:inline-flex;align-items:center;gap:7px;font-family:var(--rv-ff-d);
  font-weight:700;font-size:.89rem;padding:8px 14px;border-radius:var(--rv-radius-sm);
  border:1px solid transparent;cursor:pointer;text-decoration:none}
.rv .rv-btn-primary,.rv a.rv-btn-primary{background:var(--rv-accent);color:#fff;text-decoration:none}
.rv .rv-btn-ghost,.rv a.rv-btn-ghost{background:var(--rv-surface);border-color:var(--rv-line2);
  color:var(--rv-ink);text-decoration:none}

/* ---------- status pills: fixed meaning across every character ---------- */
.rv-pill{display:inline-flex;align-items:center;gap:6px;font-size:.78rem;font-weight:600;
  padding:3px 10px;border-radius:var(--rv-radius-pill);border:1px solid transparent;
  line-height:1.5;white-space:nowrap}
.rv-pill::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.rv-pill-ok{background:var(--rv-ok-soft);color:var(--rv-ok-ink);border-color:var(--rv-ok)}
.rv-pill-warn{background:var(--rv-warn-soft);color:var(--rv-warn-ink);border-color:var(--rv-warn)}
.rv-pill-offshore{background:var(--rv-offshore-soft);color:var(--rv-offshore-ink);
  border-color:var(--rv-offshore)}
.rv-pill-none{background:var(--rv-sunk);color:var(--rv-dim);border-color:var(--rv-line2)}
.rv-pill-none::before{background:var(--rv-none)}

/* ---------- the no-data state: deliberate, not broken ---------- */
.rv-empty{display:inline-flex;align-items:center;gap:6px;color:var(--rv-dim);
  font-size:.9rem;font-style:italic}
.rv-empty::before{content:"—";font-style:normal;color:var(--rv-none);font-weight:700}

/* ---------- scope marker: whose number is this ---------- */
.rv-scope{display:inline-block;font-family:var(--rv-ff-m);font-size:.62rem;letter-spacing:.1em;
  text-transform:uppercase;padding:1px 6px;border-radius:4px;vertical-align:middle;
  margin-inline-start:6px;border:1px solid var(--rv-line2);color:var(--rv-dim);
  background:var(--rv-surface)}
.rv-scope-global{border-color:var(--rv-offshore);color:var(--rv-offshore-ink);
  background:var(--rv-offshore-soft)}

/* ---------- tables, with the density axis ---------- */
.rv-tablewrap{overflow-x:auto;border:1px solid var(--rv-line);border-radius:var(--rv-radius);
  background:var(--rv-surface)}
.rv-table{width:100%;border-collapse:collapse;font-size:.9rem;min-width:620px}
.rv-table th{text-align:start;font-family:var(--rv-ff-d);font-size:.76rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--rv-dim);font-weight:700;
  padding:9px 12px;border-bottom:1px solid var(--rv-line2);background:var(--rv-sunk);
  position:sticky;top:0}
.rv-table td{padding:9px 12px;border-bottom:1px solid var(--rv-line);vertical-align:middle}
.rv-table tbody tr:last-child td{border-bottom:0}
.rv-table .rv-c-num{text-align:end;font-family:var(--rv-ff-m);font-variant-numeric:tabular-nums}
[data-density="compact"] .rv-table{font-size:.875rem}
[data-density="compact"] .rv-table th,[data-density="compact"] .rv-table td{padding:8px 11px}
[data-density="airy"] .rv-table th,[data-density="airy"] .rv-table td{padding:16px 18px}
[data-density="zebra"] .rv-table tbody tr:nth-child(odd){background:var(--rv-sunk)}
[data-density="zebra"] .rv-table td{border-bottom:0}

/* Card-rows density: the table becomes stacked cards below the breakpoint. The header is
   hidden and each cell carries its own label from data-label. */
@media (max-width:720px){
  [data-density="cards"] .rv-table{min-width:0}
  [data-density="cards"] .rv-table thead{display:none}
  [data-density="cards"] .rv-table tr{display:block;border:1px solid var(--rv-line);
    border-radius:var(--rv-radius-sm);margin-bottom:10px;background:var(--rv-surface)}
  [data-density="cards"] .rv-table td{display:flex;justify-content:space-between;gap:14px;
    border-bottom:1px solid var(--rv-line);text-align:start}
  [data-density="cards"] .rv-table td::before{content:attr(data-label);color:var(--rv-dim);
    font-size:.76rem;text-transform:uppercase;letter-spacing:.06em;flex:none}
  [data-density="cards"] .rv-table .rv-c-num{text-align:end}
}

/* ---------- fact plate ---------- */
.rv-plate{display:grid;grid-template-columns:repeat(auto-fit,minmax(132px,1fr));gap:1px;
  background:var(--rv-line);border:1px solid var(--rv-line);border-radius:var(--rv-radius);
  overflow:hidden}
.rv-plate>div{background:var(--rv-surface);padding:9px 12px}
.rv-plate dt{font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;color:var(--rv-dim);
  margin:0 0 3px;font-family:var(--rv-ff-m)}
.rv-plate dd{margin:0;font-weight:600;font-size:.92rem;color:var(--rv-ink)}

/* ---------- rating displays, the five of the rating axis ---------- */
.rv-badge-score{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;
  width:84px;height:84px;border-radius:var(--rv-radius);background:var(--rv-accent);color:#fff;
  font-family:var(--rv-ff-d);line-height:1;flex:none}
.rv-badge-score b{font-size:1.9rem;font-variant-numeric:tabular-nums}
.rv-badge-score span{font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;
  opacity:.85;margin-top:5px}
.rv-bars{display:grid;gap:6px}
.rv-bar{display:grid;grid-template-columns:minmax(110px,22%) 1fr auto;gap:10px;align-items:center;
  font-size:.85rem}
/* 🚨 `display:block` is load-bearing, not tidiness: a height on an INLINE box is ignored,
   so a track written as <span> renders as a hairline and the fill disappears entirely -
   the chart still measures fine (width > 0) and still looks "ok" to the gate. Forcing the
   display here means the bar cannot be broken by choosing the wrong element. */
.rv-bar-track{display:block;height:8px;border-radius:999px;background:var(--rv-sunk);
  overflow:hidden}
.rv-bar-fill{display:block;height:100%;border-radius:999px;background:var(--rv-accent)}
.rv-bar-v{font-family:var(--rv-ff-m);font-variant-numeric:tabular-nums;color:var(--rv-ink2);
  min-width:3.2em;text-align:end}
/* 🚨 Two separate traps live in this little chart, and both of them LOOK fine in metrics.
   1. `align-items:flex-end` on the row sizes each column to its content instead of
      stretching it; the bar's percentage height then has nothing definite to resolve
      against and the chart renders as flat lines.
   2. A flex column (bar + caption stacked) is just as wrong, and more insidious: the
      percentage resolves against the WHOLE column, so bar + caption overflow it and flex
      shrinks the bar back. Tall values get squashed toward the ceiling - 88 and 70 come
      out nearly the same height, which is a lying chart, not a styling nit.
   The column is therefore a GRID of `1fr auto`: the bar's percentage resolves against the
   1fr area (definite after layout, caption excluded), so 88% is really 88% of 55%. */
.rv-cols{display:flex;align-items:stretch;gap:9px;height:122px}
.rv-col{flex:1;display:grid;grid-template-rows:1fr auto;gap:5px;justify-items:center;height:100%}
.rv-col-bar{display:block;align-self:end;width:100%;background:var(--rv-accent);border-radius:5px 5px 0 0;
  min-height:3px}
.rv-col-l{font-size:.64rem;color:var(--rv-dim);text-align:center;line-height:1.25}
.rv-weights{display:flex;flex-wrap:wrap;gap:6px}
.rv-weight{font-size:.72rem;color:var(--rv-dim);background:var(--rv-sunk);
  padding:2px 8px;border-radius:var(--rv-radius-pill);font-family:var(--rv-ff-m)}

/* ---------- key-figure strip ---------- */
.rv-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(126px,1fr));gap:9px}
.rv-stat{background:var(--rv-surface);border:1px solid var(--rv-line);
  border-radius:var(--rv-radius-sm);padding:10px 12px}
.rv-stat-k{font-size:.68rem;letter-spacing:.09em;text-transform:uppercase;color:var(--rv-dim);
  margin-bottom:3px}
.rv-stat-v{font-size:1.42rem;font-weight:700;font-family:var(--rv-ff-d);
  font-variant-numeric:tabular-nums;line-height:1.1}

/* ---------- provenance strip: date, what changed, sources ---------- */
.rv-src{border-inline-start:3px solid var(--rv-accent);background:var(--rv-sunk);
  padding:9px 13px;border-radius:0 var(--rv-radius-sm) var(--rv-radius-sm) 0;font-size:.85rem}
[dir="rtl"] .rv-src{border-radius:var(--rv-radius-sm) 0 0 var(--rv-radius-sm)}
.rv-src ul{margin:6px 0 0;padding-inline-start:18px}
.rv-src a{word-break:break-word}

.rv-byline{display:flex;flex-wrap:wrap;gap:6px 16px;align-items:center;font-size:.84rem;
  color:var(--rv-dim)}
.rv-byline b{color:var(--rv-ink2);font-weight:600}

.rv-note{font-size:.9rem;color:var(--rv-dim);background:var(--rv-sunk);
  padding:8px 11px;border-radius:var(--rv-radius-sm)}

/* ---------- card-level demo chrome (preview only, not shipped to designs) ---------- */
.rv-demo{padding:18px 0 28px}
.rv-demo-h{margin-bottom:6px}
.rv-demo-s{color:var(--rv-dim);font-size:.9rem;margin-bottom:15px;max-width:76ch}
.rv-variant{margin-bottom:18px}
.rv-variant-l{font-family:var(--rv-ff-m);font-size:.66rem;letter-spacing:.13em;
  text-transform:uppercase;color:var(--rv-faint);margin-bottom:7px}
.rv-grid2{display:grid;grid-template-columns:repeat(auto-fit,minmax(286px,1fr));gap:14px}

/* ---- patterns adopted from the 02.10 study of eight review sites ------------------------ */

/* Evidence strip: the "why believe us" row. The count is the loudest thing in it on purpose -
   it is the only part a reader can check against the tables further down. */
.rv-evid{border:1px solid var(--rv-line2);border-radius:var(--rv-radius);
  background:var(--rv-surface);padding:13px 15px;display:grid;gap:8px}
.rv-evid-count{display:flex;align-items:baseline;gap:9px}
.rv-evid-count .rv-num{font-size:1.9rem;font-weight:800;letter-spacing:-.02em}
.rv-evid-label{font-family:var(--rv-ff-d);font-size:.95rem;color:var(--rv-ink2)}
.rv-evid-meta,.rv-evid-dates{display:flex;flex-wrap:wrap;gap:6px 18px}
.rv-evid-dates{border-top:1px solid var(--rv-line);padding-top:8px}

/* Table contract: the rules of the table, above the table. */
.rv-tcontract{border-inline-start:3px solid var(--rv-accent);background:var(--rv-sunk);
  border-radius:0 var(--rv-radius-sm) var(--rv-radius-sm) 0;padding:10px 14px;display:grid;gap:7px}
.rv-tcontract-line{display:grid;grid-template-columns:148px 1fr;gap:12px;align-items:baseline}
.rv-tcontract-line>span:last-child{font-size:.92rem;color:var(--rv-ink2)}
@media (max-width:720px){.rv-tcontract-line{grid-template-columns:1fr;gap:3px}}
/* A paid row sits inside the table and outside the ranking: tinted, never numbered. */
.rv-row-promo td{background:var(--rv-offshore-soft)}

/* Sub-scores by slice: the general score answers "how good", these answer "good for what". */
.rv-subscores{display:grid;gap:5px;border:1px solid var(--rv-line);border-radius:var(--rv-radius);
  padding:11px 13px;background:var(--rv-surface)}
.rv-subscore{display:flex;align-items:center;gap:11px;font-size:.95rem;
  padding-block:4px;border-bottom:1px solid var(--rv-line)}
.rv-subscore:last-child{border-bottom:0}
.rv-subscore-v{font-family:var(--rv-ff-m);font-weight:700;font-size:1.05rem;min-width:46px;
  text-align:end;color:var(--rv-accent-deep)}
.rv-subscore-off{color:var(--rv-dim)}
.rv-subscore-off .rv-subscore-v{color:var(--rv-none)}

/* Question chips: navigation in the reader's own words. */
.rv-chips{display:flex;gap:8px;overflow-x:auto;padding-bottom:4px;scrollbar-width:thin}
.rv-chip{flex:none;border:1px solid var(--rv-line2);border-radius:var(--rv-radius-pill);
  padding:7px 14px;font-size:.9rem;color:var(--rv-ink2);text-decoration:none;
  background:var(--rv-surface);white-space:nowrap}
.rv .rv-chip-on{background:var(--rv-accent-deep);border-color:var(--rv-accent-deep);color:#fff;
  font-weight:600}
/* 🚨 .rv a sets the link colour at specificity 0,1,1 and beat a bare .rv-chip-on: the active
   chip rendered as a solid block with its label the same colour as its background. Any rule
   that recolours a link needs the .rv prefix to win. */
