/* =========================================================================
   TEGO design system · v5 "Brick" — official brand palette
   Light, type-led insurtech. Navy-purple ink on white/lavender-white surfaces,
   vivid purple for actions and headings, periwinkle for rules/borders/bullets,
   lilac for sub-labels, brick yellow reserved for "best price". Bricolage
   Grotesque for display, Geist for body and data. Mobile-first, no build.
   ========================================================================= */

/* ---- Tokens ------------------------------------------------------------ */
:root {
  --ink: #1a1440;
  --ink-2: #241a5c;
  --ink-3: #33268a;
  --brand: #7b39ec;
  --brand-hover: #6528cc;
  --brand-soft: #ede9ff;
  --brand-tint: #f5f3ff;
  --periwinkle: #938eff; /* brand accent: rule lines, borders, bullets, markers */
  --lilac: #c084fc; /* secondary accent: sub-labels and tertiary callouts */
  --lime: #ffd83d; /* highlight: brick yellow, reserved for "best price" */
  --lime-ink: #2b1d00;
  --bg: #faf9ff;
  --surface: #ffffff;
  --mist: #f0edfb;
  --muted: #635a8a;
  --muted-2: #9d8ec4;
  --border: #e6e1f7;
  --border-strong: #cdc4ee;
  --ok: #0e7a50;
  --error: #c2372b;
  --error-bg: #fbeeec;
  --warn-bg: #fff6e0;
  --warn-border: #f0d48a;

  --shadow-sm: 0 1px 2px rgba(26, 20, 64, 0.06), 0 1px 1px rgba(26, 20, 64, 0.03);
  --shadow-md: 0 2px 6px rgba(26, 20, 64, 0.05), 0 14px 36px rgba(26, 20, 64, 0.09);
  --shadow-lg: 0 6px 12px rgba(26, 20, 64, 0.06), 0 32px 80px rgba(26, 20, 64, 0.16);

  --radius-sm: 8px;
  --radius: 12px;
  --radius-lg: 20px;
  --radius-xl: 28px;

  --font-display: "Bricolage Grotesque", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --nav-h: 68px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-spring: cubic-bezier(0.34, 1.4, 0.64, 1);

  --accent: var(--brand);
  --accent-ink: #fff;
}

/* ---- Reset --------------------------------------------------------------*/
*,
*::before,
*::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  font-feature-settings: "ss01", "cv11";
}

::selection { background: var(--lime); color: var(--lime-ink); }

img, svg, video { display: block; max-width: 100%; height: auto; }

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  color: var(--ink);
  margin: 0 0 0.45em;
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-wrap: balance;
  font-variation-settings: "opsz" 96;
}

h1 {
  font-size: clamp(2.6rem, 6.4vw, 4.6rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 0.98;
}

h2 {
  font-size: clamp(1.9rem, 4vw, 2.9rem);
  font-weight: 700;
  letter-spacing: -0.035em;
}

h3 {
  font-size: clamp(1.1rem, 2.2vw, 1.3rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  font-variation-settings: "opsz" 48;
}

p { margin: 0 0 1em; }
a { color: inherit; }
button { font-family: inherit; }
ul, ol { margin: 0; padding: 0; list-style: none; }
hr { border: none; border-top: 1px solid var(--periwinkle); margin: 2rem 0; }

:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; border-radius: 4px; }

.tnum { font-variant-numeric: tabular-nums; }

[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- Layout -------------------------------------------------------------*/
.container {
  width: 100%;
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: clamp(20px, 4vw, 32px);
}

section { padding-block: clamp(3rem, 8vw, 6.5rem); }

.grid { display: grid; gap: 20px; }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
@media (min-width: 640px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 860px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

.stack { display: flex; flex-direction: column; gap: 12px; }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.muted { color: var(--muted); }
.text-ok { color: var(--ok); }
.text-lilac { color: var(--lilac); }
.text-periwinkle { color: var(--periwinkle); }
.center { text-align: center; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brand);
  margin-bottom: 18px;
}

.eyebrow::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 2px;
  background: var(--periwinkle);
  transform: rotate(45deg);
}

.section-lede {
  color: var(--muted);
  max-width: 56ch;
  margin-bottom: 40px;
  font-size: 1.08rem;
  line-height: 1.6;
  text-wrap: pretty;
}

/* section headers: title left, lede right on desktop */
.section-head {
  display: grid;
  gap: 12px 48px;
  align-items: end;
  margin-bottom: clamp(28px, 5vw, 52px);
}

@media (min-width: 860px) {
  .section-head { grid-template-columns: 1.1fr 0.9fr; }
  .section-head .section-lede { margin-bottom: 0.4em; }
}

.section-head h2 { margin-bottom: 0; }

/* ---- Watermark (persistent "not a real quote" bar) -----------------------*/
.watermark {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ink);
  color: rgba(255, 255, 255, 0.82);
  text-align: center;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.12em;
  padding: 6px 12px;
  text-transform: uppercase;
}

/* ---- Site nav -------------------------------------------------------------*/
/* The injected header lives inside #nav; the wrapper is what sticks, since a
   sticky element can only stick within its parent's box. */
#nav { position: sticky; top: 0; z-index: 40; }
.watermark + #nav { top: 26px; }

.site-nav {
  background: rgba(250, 249, 255, 0.84);
  -webkit-backdrop-filter: saturate(160%) blur(14px);
  backdrop-filter: saturate(160%) blur(14px);
  border-bottom: 1px solid rgba(26, 20, 64, 0.07);
}

.site-nav .nav-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: var(--nav-h);
  padding-block: 10px;
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.35rem;
  letter-spacing: -0.04em;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-variation-settings: "opsz" 96;
}

.wordmark .mark {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
}

.wordmark img.logo {
  height: 34px;
  width: auto;
  display: block;
}

.site-footer .wordmark img.logo { height: 40px; }

.site-nav .nav-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 4px;
  margin-inline-start: auto;
}

.site-nav .nav-links a {
  position: relative;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.92rem;
  font-weight: 500;
  padding: 7px 12px;
  border-radius: 999px;
  transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}

.site-nav .nav-links a:hover { color: var(--ink); background: rgba(26, 20, 64, 0.05); }

.site-nav .nav-links a.active { color: var(--ink); background: rgba(26, 20, 64, 0.07); }

.site-nav .nav-links .soon {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--muted-2);
  font-size: 0.92rem;
  font-weight: 500;
  padding: 7px 12px;
  cursor: default;
  pointer-events: none;
}

.site-nav .nav-links .soon .pill {
  background: rgba(26, 20, 64, 0.06);
  color: var(--muted-2);
  padding: 2px 7px;
  font-size: 0.62rem;
}

.site-nav .nav-cta { margin-inline-start: 12px; display: flex; align-items: center; gap: 10px; }

/* Language toggle. Two letters, low contrast until chosen: it is a setting,
   not a call to action, and it sits next to one. */
.lang-toggle {
  display: inline-flex;
  align-items: center;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
}

.lang-toggle button {
  appearance: none;
  border: 0;
  background: none;
  cursor: pointer;
  font: inherit;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--muted-2);
  padding: 5px 10px;
  border-radius: 999px;
  line-height: 1;
  transition: color 0.15s var(--ease), background 0.15s var(--ease);
}

.lang-toggle button:hover { color: var(--ink); }
.lang-toggle button.is-on { background: var(--mist); color: var(--ink); }
.lang-toggle button:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

@media (max-width: 639px) {
  .site-nav .nav-cta { margin-inline-start: auto; order: 2; }
  .site-nav .nav-cta .btn { padding: 9px 16px; font-size: 0.88rem; }
  .site-nav .nav-links {
    order: 3;
    margin-inline-start: -10px;
    width: calc(100% + 10px);
    justify-content: flex-start;
    gap: 2px;
  }
  .site-nav .nav-links .soon { display: none; }
}

/* ---- Footer ---------------------------------------------------------------*/
.site-footer {
  margin-top: clamp(40px, 8vw, 96px);
  background: var(--ink);
  color: rgba(255, 255, 255, 0.7);
  padding-block: clamp(40px, 6vw, 64px) 32px;
}

.site-footer .footer-grid {
  display: grid;
  gap: 28px;
  grid-template-columns: 1fr;
}

@media (min-width: 760px) {
  .site-footer .footer-grid { grid-template-columns: 1.3fr 1fr 1fr; }
}

.site-footer .wordmark { color: #fff; }

.site-footer .footer-tag {
  margin: 14px 0 0;
  max-width: 34ch;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.6);
}

.site-footer h4 {
  color: #fff;
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-bottom: 14px;
}

.site-footer .footer-links a,
.site-footer .footer-links span {
  display: block;
  color: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  font-size: 0.95rem;
  padding: 4px 0;
}

.site-footer .footer-links a:hover { color: #fff; }
.site-footer .footer-links span { color: rgba(255, 255, 255, 0.38); }

.site-footer .footer-bottom {
  margin-top: 40px;
  padding-top: 22px;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 10px 24px;
  font-size: 0.8rem;
  color: rgba(255, 255, 255, 0.45);
}

.site-footer .disclaimer { margin: 0; max-width: 70ch; }
.site-footer .copyright { margin: 0; }

/* ---- Buttons ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid transparent;
  border-radius: 999px;
  padding: 12px 22px;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition: transform 0.14s var(--ease), box-shadow 0.2s var(--ease),
    background-color 0.18s var(--ease), border-color 0.18s var(--ease),
    color 0.18s var(--ease);
}

.btn:active { transform: translateY(1px) scale(0.99); }

.btn:disabled,
.btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; pointer-events: none; }

.btn-primary {
  background: var(--brand);
  color: #fff;
  box-shadow: 0 1px 2px rgba(26, 20, 64, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.btn-primary:hover {
  background: var(--brand-hover);
  box-shadow: 0 8px 22px rgba(123, 57, 236, 0.3);
  transform: translateY(-1px);
}

.btn .btn-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-right: -8px;
  border-radius: 50%;
  background: var(--lime);
  flex-shrink: 0;
  transition: transform 0.2s var(--ease-spring);
}

.btn:hover .btn-arrow { transform: translateX(3px); }

.btn .btn-arrow svg { width: 12px; height: 12px; stroke: var(--lime-ink); }

/* A leading glyph, unlike .btn-arrow, which is a trailing disc. */
.btn .btn-icon { width: 15px; height: 15px; flex-shrink: 0; margin-inline-end: -2px; }

.btn-secondary {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--border-strong);
}

.btn-secondary:hover { border-color: var(--ink); transform: translateY(-1px); }

.btn-ghost { background: transparent; color: var(--muted); padding-inline: 10px; }
.btn-ghost:hover { color: var(--ink); background: rgba(26, 20, 64, 0.05); }

.btn-lg { padding: 15px 26px; font-size: 1.02rem; }
.btn-sm { padding: 9px 15px; font-size: 0.86rem; gap: 7px; }
.btn-sm .btn-icon { width: 13px; height: 13px; }

/* Right-hand slot of a page heading: actions that belong to the whole page
   rather than to any one row of it. */
.head-actions { display: flex; gap: 10px; flex-shrink: 0; }
.head-actions:empty { display: none; }

.btn-dark { background: var(--ink); color: #fff; }
.btn-dark:hover { background: var(--ink-3); transform: translateY(-1px); }

/* ---- Pills / badges ------------------------------------------------------*/
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background: rgba(26, 20, 64, 0.06);
  color: var(--muted);
  white-space: nowrap;
}

.pill-ok { background: rgba(14, 122, 80, 0.12); color: var(--ok); }
.pill-accent { background: var(--brand-soft); color: var(--brand); }
.pill-lime { background: var(--lime); color: var(--lime-ink); }

.badge-best {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: var(--lime);
  color: var(--lime-ink);
  border-radius: 999px;
  padding: 4px 11px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* ---- Cards --------------------------------------------------------------*/
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 28px;
}

.card-tight { padding: 16px 18px; }

.card-hover {
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}

.card-hover:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--border-strong); }

/* ---- Forms ---------------------------------------------------------------*/
.field { display: block; margin-bottom: 20px; }

.field label,
label.field-label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 8px;
  letter-spacing: -0.01em;
}

.field .hint { display: block; font-size: 0.82rem; color: var(--muted); margin-top: 6px; }

input[type="text"],
input[type="email"],
input[type="tel"],
input[type="number"],
input[type="password"],
select,
textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--ink);
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 13px 15px;
  line-height: 1.4;
  appearance: none;
  -webkit-appearance: none;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

input::placeholder, textarea::placeholder { color: var(--muted-2); }

input[type="number"] { font-variant-numeric: tabular-nums; }
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type="number"] { -moz-appearance: textfield; }

select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23635a8a' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 4.5 6 8l3.5-3.5'/%3E%3C/svg%3E");
  background-position: calc(100% - 14px) center;
  background-size: 12px 12px;
  background-repeat: no-repeat;
  padding-right: 38px;
  cursor: pointer;
}

textarea { resize: vertical; min-height: 96px; }

input:hover, select:hover, textarea:hover { border-color: var(--border-strong); }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 4px rgba(123, 57, 236, 0.12);
}

input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"],
.field.has-error input,
.field.has-error select,
.field.has-error textarea { border-color: var(--error); background: var(--error-bg); }

.field-error { display: block; font-size: 0.82rem; color: var(--error); margin-top: 6px; }
.field-error:empty { display: none; }

/* input with a unit prefix, e.g. "Rs" */
.input-affix { position: relative; }
.input-affix .affix {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--muted);
  pointer-events: none;
}
.input-affix input { padding-left: 44px; }
.input-affix .affix-end { left: auto; right: 15px; }
.input-affix.affix-right input { padding-left: 15px; padding-right: 52px; }

.checkbox-row { display: flex; align-items: flex-start; gap: 12px; }

.checkbox-row input[type="checkbox"] {
  margin-top: 2px;
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  accent-color: var(--brand);
  border-radius: 6px;
}

.checkbox-row label { font-size: 0.9rem; color: var(--ink); font-weight: 400; margin: 0; }

/* ---- Choice cards (radio-style selections) --------------------------------*/
.choice-group { display: grid; gap: 10px; }

@media (min-width: 640px) {
  .choice-group { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
}

.choice {
  position: relative;
  display: block;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px;
  padding-right: 50px;
  cursor: pointer;
  transition: border-color 0.15s var(--ease), box-shadow 0.15s var(--ease),
    transform 0.15s var(--ease), background-color 0.15s var(--ease);
}

.choice:hover { border-color: var(--border-strong); transform: translateY(-1px); }

.choice input[type="radio"],
.choice input[type="checkbox"] {
  position: absolute;
  top: 18px;
  right: 16px;
  width: 20px;
  height: 20px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.choice::before {
  content: "";
  position: absolute;
  top: 18px;
  right: 16px;
  width: 20px;
  height: 20px;
  border: 2px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  transition: border-color 0.15s var(--ease), background-color 0.15s var(--ease);
  pointer-events: none;
}

.choice::after {
  content: "";
  position: absolute;
  top: 24px;
  right: 22px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #fff;
  transform: scale(0);
  transition: transform 0.2s var(--ease-spring);
  pointer-events: none;
}

.choice:has(input:checked)::before { border-color: var(--brand); background: var(--brand); }
.choice:has(input:checked)::after { transform: scale(1); }
.choice:has(input:focus-visible)::before { box-shadow: 0 0 0 4px rgba(123, 57, 236, 0.18); }

.choice .choice-title {
  font-weight: 600;
  font-size: 1rem;
  margin-bottom: 3px;
  display: block;
  letter-spacing: -0.01em;
}

.choice .choice-desc { font-size: 0.86rem; color: var(--muted); margin: 0; line-height: 1.45; }

.choice.selected,
.choice:has(input:checked) {
  border-color: var(--brand);
  background: var(--brand-tint);
  box-shadow: 0 0 0 3px rgba(123, 57, 236, 0.1);
}

/* ---- Segmented control (compact radios: Private/Commercial, Yes/No) ------*/
.segmented {
  display: inline-grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  width: 100%;
  background: var(--mist);
  border-radius: 999px;
  padding: 4px;
  gap: 2px;
}

.segmented label {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 14px;
  border-radius: 999px;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  margin: 0;
  transition: color 0.15s var(--ease), background-color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.segmented label input { position: absolute; inset: 0; opacity: 0; margin: 0; cursor: pointer; }

.segmented label:has(input:checked) {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(26, 20, 64, 0.12);
}

.segmented label:has(input:focus-visible) { box-shadow: 0 0 0 3px rgba(123, 57, 236, 0.2); }

/* ---- Progress bar (funnel step indicator) ---------------------------------*/
.progress {
  width: 100%;
  height: 4px;
  background: rgba(26, 20, 64, 0.08);
  border-radius: 999px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: var(--brand);
  border-radius: 999px;
  transition: width 0.4s var(--ease);
}

.progress-steps {
  display: flex;
  justify-content: space-between;
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 8px;
}

.progress-steps .done { color: var(--ink); font-weight: 600; }

/* ---- Tick / cross benefit markers -----------------------------------------*/
.tick, .cross {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.88rem;
}

.tick::before, .cross::before {
  content: "";
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background-position: center;
  background-repeat: no-repeat;
  background-size: 10px 10px;
}

.tick::before {
  background-color: var(--brand-soft);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%237b39ec' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 8.5 6.5 12 13 4'/%3E%3C/svg%3E");
}

.cross::before {
  background-color: rgba(99, 90, 138, 0.1);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%239d8ec4' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4l8 8M12 4l-8 8'/%3E%3C/svg%3E");
}

.cross { color: var(--muted-2); }

/* ---- Offer row (results + saved quote) ------------------------------------
   A ranked "leaderboard" row. On wide screens it is a single horizontal line:
   rank · insurer · benefits · price · action. On phones it stacks. */
.offer {
  position: relative;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}

.offer:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); transform: translateY(-2px); }

.offer.is-best {
  border-color: var(--brand);
  background: linear-gradient(180deg, var(--brand-tint), var(--surface) 60%);
  box-shadow: 0 0 0 4px rgba(123, 57, 236, 0.08);
}

@media (min-width: 900px) {
  .offer {
    grid-template-columns: 40px minmax(130px, 1fr) minmax(170px, 1.2fr) auto auto;
    align-items: center;
    gap: 18px;
    padding: 20px 22px;
  }
}

.offer > * { min-width: 0; }

.offer-rank {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--muted-2);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: var(--mist);
}

.offer.is-best .offer-rank { background: var(--brand); color: #fff; }

.offer-header { display: flex; flex-direction: column; gap: 6px; min-width: 0; }

/* Holds the insurer's mark. The heading is kept -- it is still the card's
   heading in the outline, and the logo's alt is its accessible name -- but
   the type on it now only shows if the image fails to load. */
.offer-insurer {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: -0.02em;
  margin: 0;
  font-variation-settings: "opsz" 48;
  --ins-h: 30px;
  min-height: 30px;
  display: flex;
  align-items: center;
}

.offer-meta { font-size: 0.82rem; color: var(--muted); font-variant-numeric: tabular-nums; }

.offer-price {
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
}

@media (min-width: 900px) {
  .offer-price { flex-direction: column; align-items: flex-end; gap: 2px; text-align: right; }
}

.offer-price .amount {
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  white-space: nowrap;
}

.offer-price .period { font-size: 0.82rem; color: var(--muted); }

.offer-savings {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  align-self: flex-start;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--ok);
  white-space: nowrap;
}

@media (min-width: 900px) { .offer-price .offer-savings { align-self: flex-end; } }

.offer-details {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 6px 14px;
  font-size: 0.85rem;
  color: var(--muted);
  border-top: 1px solid var(--border);
  padding-top: 12px;
  margin: 0;
}

.offer-details dt { color: var(--muted); }
.offer-details dd { margin: 0; color: var(--ink); font-weight: 500; text-align: right; font-variant-numeric: tabular-nums; }

.offer-actions { display: flex; flex-direction: column; gap: 8px; align-items: stretch; }
@media (min-width: 900px) { .offer-actions { align-items: center; min-width: 110px; } .offer-actions .btn { padding-inline: 20px; } }

/* ---- Skeleton loaders ------------------------------------------------------*/
.skeleton {
  position: relative;
  overflow: hidden;
  background: rgba(26, 20, 64, 0.07);
  border-radius: 6px;
  color: transparent !important;
  user-select: none;
}

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent);
  animation: tego-shimmer 1.4s infinite;
}

@keyframes tego-shimmer { to { transform: translateX(100%); } }

/* ---- Notices ---------------------------------------------------------------*/
.notice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  background: var(--warn-bg);
  border: 1px solid var(--warn-border);
  border-radius: var(--radius);
  padding: 12px 14px;
  font-size: 0.86rem;
  color: var(--ink);
  margin-top: 10px;
  line-height: 1.5;
}

.notice::before {
  content: "";
  flex-shrink: 0;
  width: 16px;
  height: 16px;
  margin-top: 2px;
  border-radius: 50%;
  background: #e3a92b url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23fff' stroke-width='2.2' stroke-linecap='round'%3E%3Cpath d='M8 4.5v4M8 11.5v.1'/%3E%3C/svg%3E") center / 10px no-repeat;
}

/* ---- Page header (funnel / results / checkout) ----------------------------*/
.page-head { margin-bottom: clamp(22px, 4vw, 36px); }
.page-head h1 { font-size: clamp(2rem, 4.6vw, 3rem); margin-bottom: 0.3em; }
.page-head p { color: var(--muted); margin: 0; font-size: 1.02rem; }

/* ---- Reveal on scroll (progressive; works without JS) --------------------*/
.reveal { opacity: 1; transform: none; }
.js .reveal { opacity: 0; transform: translateY(16px); transition: opacity 0.7s var(--ease), transform 0.7s var(--ease); }
.js .reveal.is-in { opacity: 1; transform: none; }

/* ---- Utilities ------------------------------------------------------------*/
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* =========================================================================
   UI/UX polish pass — new components.
   Same tokens, same brand. Everything here is hierarchy and flow.
   ========================================================================= */

/* ---- Live estimate band (funnel) -----------------------------------------
   The funnel used to ask five screens of questions and show nothing until
   the end. This band gives a real range from step 2, computed by the actual
   rating engine over the answers so far, and narrows it as answers land. */
.estimate-band {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 16px clamp(20px, 4vw, 36px);
  background: var(--mist);
  border-bottom: 1px solid var(--border);
  transition: background-color 0.4s var(--ease);
}

.estimate-band.is-live {
  background: linear-gradient(90deg, var(--brand-tint), var(--surface));
}

.estimate-band .eb-main { display: flex; align-items: center; gap: 14px; min-width: 0; }

.estimate-band .eb-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: var(--muted-2);
  transition: background-color 0.3s var(--ease);
}

.estimate-band.is-live .eb-dot { background: var(--ok); }

.estimate-band .eb-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }

.estimate-band .eb-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.estimate-band .eb-value {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 3vw, 1.4rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.15;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  transition: color 0.3s var(--ease);
}

.estimate-band.is-live .eb-value { color: var(--ink); }

.estimate-band .eb-side { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex-shrink: 0; }
.estimate-band .eb-note { font-size: 0.78rem; color: var(--muted); text-align: right; }
.estimate-band .eb-dots { display: flex; gap: 4px; }

.estimate-band .eb-dots span {
  width: 18px;
  height: 4px;
  border-radius: 999px;
  background: var(--border-strong);
  transition: background-color 0.3s var(--ease);
}

.estimate-band .eb-dots span.on { background: var(--brand); }

@media (max-width: 639px) {
  .estimate-band { padding: 11px 18px; gap: 11px; }
  .estimate-band .eb-note { display: none; }
  .estimate-band .eb-dots span { width: 14px; }
}

/* ---- Range fields (sum insured, engine size, no-claim years) -------------
   A six-digit number is the slowest field to type on a phone, so the slider
   carries the coarse move and the number input beside it stays for the exact
   figure. Built by js/range-field.js; the markup below is all generated, so
   the only thing this file owns is the look of the track.

   These replaced four preset value chips, which could only ever offer four
   answers. --range-fill is written by the script on every paint. */
.range-field {
  --range-fill: 0%;
  margin: 4px 0 12px;
}

.range-readout {
  display: block;
  font-family: var(--font-display);
  font-size: 1.32rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink);
  letter-spacing: -0.01em;
  margin-bottom: 6px;
}

.range-field.is-unset .range-readout { color: var(--muted-2); font-weight: 600; }

/* Pinned means the typed number is past where the track can travel: an
   8000cc engine with a slider that stops at 5000. The thumb sits at the end
   and the readout keeps telling the truth. */
.range-field.is-pinned .range-readout::after {
  content: "";
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 7px;
  vertical-align: 0.18em;
  border-left: 6px solid var(--brand);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
}

.range-input {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 22px;
  margin: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
}

.range-input:focus { outline: none; }

/* The track is painted twice over, once per engine, because there is no
   shared selector for it and grouping them makes both rules vanish. */
.range-input::-webkit-slider-runnable-track {
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--brand) 0 var(--range-fill),
    var(--mist) var(--range-fill) 100%
  );
}

.range-input::-moz-range-track {
  height: 6px;
  border-radius: 999px;
  background: linear-gradient(
    to right,
    var(--brand) 0 var(--range-fill),
    var(--mist) var(--range-fill) 100%
  );
}

.range-field.is-unset .range-input::-webkit-slider-runnable-track { background: var(--mist); }
.range-field.is-unset .range-input::-moz-range-track { background: var(--mist); }

/* 24px so the thumb clears the 24px minimum for a touch target on its own,
   before the padding around the field is counted. */
.range-input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 24px;
  height: 24px;
  margin-top: -9px;
  border-radius: 50%;
  background: var(--surface);
  border: 3px solid var(--brand);
  box-shadow: var(--shadow-sm);
  transition: transform 0.12s var(--ease-spring), box-shadow 0.15s var(--ease);
}

.range-input::-moz-range-thumb {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--surface);
  border: 3px solid var(--brand);
  box-shadow: var(--shadow-sm);
  transition: transform 0.12s var(--ease-spring), box-shadow 0.15s var(--ease);
}

.range-field.is-unset .range-input::-webkit-slider-thumb { border-color: var(--border-strong); }
.range-field.is-unset .range-input::-moz-range-thumb { border-color: var(--border-strong); }

.range-input:active::-webkit-slider-thumb { transform: scale(1.12); }
.range-input:active::-moz-range-thumb { transform: scale(1.12); }

/* Focus lands on the thumb rather than the whole control, so a keyboard user
   can see which stop they are on. */
.range-input:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 4px var(--brand-soft); }
.range-input:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 4px var(--brand-soft); }

/* Ticks are positioned by value, not spaced evenly, so each one sits under
   the point on the track it names. */
.range-ticks {
  position: relative;
  height: 15px;
  margin-top: 1px;
  font-size: 0.72rem;
  color: var(--muted-2);
}

.range-ticks span {
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  white-space: nowrap;
}

/* The end labels anchor to their edge rather than centring on it, so neither
   hangs outside the field and collides with the control in the next column. */
.range-ticks span.is-first { left: 0; transform: none; }
.range-ticks span.is-last { right: 0; transform: none; }

/* No-claim years has no number input under it, so it carries the gap that
   the pair below the others would otherwise provide. */
.range-host-solo .range-field { margin-bottom: 4px; }

@media (prefers-reduced-motion: reduce) {
  .range-input::-webkit-slider-thumb { transition: none; }
  .range-input::-moz-range-thumb { transition: none; }
}

/* Day / Month / Year as one control (js/date-parts.js). Month is widest
   because it carries a name. */
.date-parts {
  display: grid;
  grid-template-columns: 1fr 1.6fr 1.2fr;
  gap: 8px;
}
.date-parts select { min-width: 0; }

/* ---- Combobox (make, model) ----------------------------------------------
   Drawn by js/vehicle-picker.js over the ordinary text inputs, which keep
   their name and their free text. It replaced a <datalist>, which could not
   be styled at all and rendered as a different control in every browser. */
.combo { position: relative; }

.combo-list {
  position: absolute;
  z-index: 30;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  max-height: 264px;
  overflow-y: auto;
  margin: 0;
  padding: 4px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  /* Momentum scrolling, or the list feels stuck on iOS. */
  -webkit-overflow-scrolling: touch;
}

.combo-option {
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  font-size: 0.92rem;
  color: var(--ink);
  cursor: pointer;
}

/* One rule for both, because the pointer and the arrow keys are selecting
   the same thing and should not look like two different states. */
.combo-option:hover,
.combo-option.is-active {
  background: var(--brand-tint);
  color: var(--brand);
}

.combo-empty {
  padding: 9px 11px;
  font-size: 0.86rem;
  color: var(--muted);
}

@media (max-width: 639px) {
  /* 44px targets, and a shorter list so the keyboard does not bury it. */
  .combo-option { padding: 12px 12px; font-size: 0.95rem; }
  .combo-list { max-height: 216px; }
}

/* ---- Discount callout (no-claim years) -----------------------------------
   The largest single lever in the form, shown in rupees rather than
   explained in a hint. */
.discount-note {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  padding: 9px 13px;
  background: rgba(14, 122, 80, 0.09);
  border-radius: var(--radius);
  font-size: 0.86rem;
  color: var(--ok);
  font-weight: 600;
  line-height: 1.4;
}

.discount-note svg { width: 14px; height: 14px; flex-shrink: 0; stroke: currentColor; }
.discount-note[hidden] { display: none; }

/* ---- Rail stepper (funnel sidebar) ---------------------------------------
   Was decorative. Completed steps now show the answer given and jump back
   when clicked, so a typo does not mean restarting. */
.rail-steps { display: flex; flex-direction: column; gap: 2px; margin: 0 0 24px; }

.rail-step {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border: none;
  width: 100%;
  text-align: left;
  background: transparent;
  border-radius: var(--radius);
  font-family: inherit;
  font-size: 1rem;
  color: inherit;
  cursor: default;
  transition: background-color 0.18s var(--ease);
}

.rail-step .dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
  background: var(--mist);
  color: var(--muted-2);
  transition: background-color 0.2s var(--ease), color 0.2s var(--ease);
}

.rail-step .dot svg { width: 12px; height: 12px; stroke: currentColor; }

.rail-step .rail-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }

.rail-step .rail-title {
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--muted-2);
  letter-spacing: -0.01em;
  transition: color 0.2s var(--ease);
}

.rail-step .rail-answer {
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rail-step .rail-answer:empty { display: none; }

.rail-step .rail-edit {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--brand);
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.15s var(--ease);
}

.rail-step.is-active { background: var(--brand-tint); }
/* Body colour comes from --brick (S1 block below) so a financed step's
   locked dot isn't left with this brand-purple body under periwinkle
   studs; the glyph still needs white spelled out here since nothing else
   sets it for this state. */
.rail-step.is-active .dot { color: #fff; }
.rail-step.is-active .rail-title { color: var(--ink); font-weight: 600; }

.rail-step.is-done { cursor: pointer; }
.rail-step.is-done .dot { color: #fff; }
.rail-step.is-done .rail-title { color: var(--ink); }
.rail-step.is-done:hover { background: rgba(26, 20, 64, 0.04); }
.rail-step.is-done:hover .rail-edit,
.rail-step.is-done:focus-visible .rail-edit { opacity: 1; }

/* A financed car's cover step is done but not editable: the bank decided,
   not the customer, and handleRailJump refuses the jump. Overrides is-done
   above (same specificity, declared after) so the checkmark stays but the
   pointer and the Edit reveal, which promised a click would do something, do
   not. */
.rail-step.is-locked { cursor: default; }
.rail-step.is-locked:hover { background: transparent; }
.rail-step.is-locked:hover .rail-edit,
.rail-step.is-locked:focus-visible .rail-edit { opacity: 0; }

/* ---- Savings banner (results) --------------------------------------------
   Was 0.78rem of green text inside each row. It is the reason the product
   exists, so it leads the page, in the one colour reserved for best price. */
.savings-banner {
  display: flex;
  align-items: center;
  gap: 20px;
  background: var(--lime);
  border-radius: var(--radius-lg);
  padding: 18px clamp(18px, 3vw, 26px);
  margin-bottom: 22px;
}

.savings-banner[hidden] { display: none; }

.savings-banner .sb-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: rgba(43, 29, 0, 0.14);
  flex-shrink: 0;
}

.savings-banner .sb-icon svg { width: 20px; height: 20px; stroke: var(--lime-ink); }

.savings-banner .sb-body { flex: 1; min-width: 0; }

.savings-banner .sb-head {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.1rem, 3vw, 1.5rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--lime-ink);
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
}

.savings-banner .sb-sub { margin: 2px 0 0; font-size: 0.9rem; color: rgba(43, 29, 0, 0.72); }

.savings-banner .sb-aside {
  font-size: 0.82rem;
  color: rgba(43, 29, 0, 0.62);
  text-align: right;
  max-width: 22ch;
  flex-shrink: 0;
}

@media (max-width: 859px) {
  .savings-banner { gap: 13px; padding: 14px 16px; }
  .savings-banner .sb-icon { width: 34px; height: 34px; border-radius: 10px; }
  .savings-banner .sb-icon svg { width: 18px; height: 18px; }
  .savings-banner .sb-aside { display: none; }
}

/* ---- Results toolbar (cover + sort) --------------------------------------
   The cover switch used to live in the sidebar, which stacks below all five
   offers on a phone, invisible without scrolling past what it controls. */
.results-toolbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 12px 16px;
  margin-bottom: 14px;
}

/* Cover, Sort and View come to ~990px of controls, more than the offers
   column has beside the sticky sidebar. Rather than let a divider orphan
   itself at the end of a row, the groups wrap on purpose and the uppercase
   labels carry the separation the dividers used to. */
.results-toolbar .tb-scroll {
  display: flex;
  align-items: center;
  column-gap: 22px;
  row-gap: 11px;
  flex-wrap: wrap;
  flex: 1;
  min-width: 0;
}

@media (min-width: 860px) {
  .results-toolbar .tb-divider { display: none; }
}

.results-toolbar .tb-set { display: flex; align-items: center; gap: 10px; }

.results-toolbar .tb-label {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted-2);
  flex-shrink: 0;
}

.results-toolbar .tb-divider { width: 1px; height: 24px; background: var(--border); }

/* The View switch keeps a fixed slot at the right rather than joining the
   scrolling strip, so it is on screen at every width. Its buttons carry an
   icon and a word; the word drops out on a phone, where the pair reads as
   the familiar list/grid switcher. */
.results-toolbar .tb-view {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
  margin-inline-start: auto;
}

.tb-group button .tb-icon {
  width: 15px;
  height: 15px;
  fill: currentColor;
  flex-shrink: 0;
}

#view-group button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

#view-group button.is-active .tb-icon { fill: var(--brand); }

.results-toolbar .tb-count {
  margin-inline-start: auto;
  font-size: 0.84rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.tb-group {
  display: inline-flex;
  background: var(--mist);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}

.tb-group button {
  border: none;
  background: transparent;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--muted);
  padding: 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease), box-shadow 0.15s var(--ease);
}

.tb-group button:hover { color: var(--ink); }

/* Not available on this quote: the cover a bank requires, or ranking by an
   excess every insurer now shares. Both were already set disabled and both
   looked exactly like a live choice, so the click simply did nothing. */
.tb-group button:disabled { opacity: 0.4; cursor: not-allowed; }
.tb-group button:disabled:hover { color: var(--muted); }

.tb-group button.is-active {
  background: var(--surface);
  color: var(--ink);
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(26, 20, 64, 0.12);
}

/* Between the sidebar appearing at 980px and about 1180px the offers column
   is only ~566px, and a labelled View switch pushes the toolbar to a third
   row. Icons alone read fine as a list/grid switcher. */
@media (max-width: 1179px) {
  .results-toolbar .tb-view .tb-label,
  #view-group .tb-btn-text { display: none; }
  #view-group button { padding-inline: 11px; }
  .tb-group button .tb-icon { width: 16px; height: 16px; }
}

@media (max-width: 859px) {
  .results-toolbar {
    position: sticky;
    top: calc(var(--nav-h) + 26px);
    z-index: 30;
    gap: 9px;
    padding: 10px 12px;
    border-radius: var(--radius);
  }

  .results-toolbar .tb-divider,
  .results-toolbar .tb-count { display: none; }

  .results-toolbar .tb-view { gap: 0; margin-inline-start: 0; }

  /* Only where a scrolling strip actually sits to its left: the rule marks
     where that strip ends, and the mask fades the pill it cuts through so
     the clipping reads as "there is more to the right", not broken text.
     The saved-quote toolbar has no strip, and would get a leading rule with
     nothing before it. */
  .results-toolbar .tb-scroll + .tb-view {
    padding-inline-start: 9px;
    border-inline-start: 1px solid var(--border);
  }

  .results-toolbar .tb-scroll {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
    mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent);
  }

  .results-toolbar .tb-scroll {
    gap: 7px;
    width: 100%;
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .results-toolbar .tb-set { gap: 7px; flex-shrink: 0; }


  .results-toolbar .tb-scroll::-webkit-scrollbar { display: none; }

  .tb-group { background: transparent; padding: 0; gap: 7px; }

  .tb-group button {
    border: 1px solid var(--border-strong);
    background: var(--surface);
    min-height: 40px;
    flex-shrink: 0;
  }

  .tb-group button.is-active {
    border-color: var(--brand);
    background: var(--brand-tint);
    color: var(--brand);
    box-shadow: none;
  }
}

/* ---- Offer perk chips ----------------------------------------------------
   Four ticks and crosses per row across five rows is twenty icons competing
   with five prices. Each row now lists only what that insurer includes. */
.offer-perks { display: flex; flex-wrap: wrap; gap: 6px; align-content: center; }

.offer-perks .perk {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--ink-3);
  background: var(--mist);
  border-radius: 999px;
  padding: 4px 10px;
}

.offer-perks .perk svg { width: 11px; height: 11px; flex-shrink: 0; stroke: var(--brand); }

.offer-perks .perk-missing {
  display: inline-flex;
  align-items: center;
  font-size: 0.78rem;
  color: var(--muted-2);
  padding: 4px 2px;
}

/* ---- Columns view (insurer per column) -----------------------------------
   The list ranks; this compares. A real table so the row/column relationship
   survives a screen reader, wrapped in a horizontal scroller so five
   insurers still work at 375px with the label column pinned to the left. */
/* Both widths are read by JS (via scrollPaddingLeft) and by the table's own
   min-width, so the phone override below is the single place that decides
   "two columns, whatever two columns comes to at this width". */
.cmp {
  position: relative;
  margin-bottom: 14px;
  --cmp-label-w: 96px;
  --cmp-col-w: 136px;
}
.cmp[hidden] { display: none; }

.cmp-scroll {
  overflow-x: auto;
  overflow-y: visible;
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius-lg);
  /* A snapped column would otherwise land underneath the pinned labels. */
  scroll-padding-left: var(--cmp-label-w);
  scroll-snap-type: x proximity;
  /* A pointer user gets a real scrollbar; the default grey slab sat badly
     inside the rounded card, so it is slimmed to a pill on a clear track. */
  scrollbar-width: thin;
  scrollbar-color: var(--border-strong) transparent;
}

.cmp-scroll::-webkit-scrollbar { height: 10px; }
.cmp-scroll::-webkit-scrollbar-track { background: transparent; }

.cmp-scroll::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: 999px;
  border: 3px solid var(--surface);
}

.cmp-scroll::-webkit-scrollbar-thumb:hover { background: var(--muted-2); }

.cmp-table {
  table-layout: fixed;
  width: 100%;
  border-collapse: collapse;
  /* JS supplies --cmp-cols; the widths are the two properties above, so a
     breakpoint can change the shape of the table without touching JS. */
  min-width: calc(var(--cmp-label-w) + var(--cmp-cols, 5) * var(--cmp-col-w));
}

.cmp-table col.cmp-labelcol { width: var(--cmp-label-w); }

.cmp-table th,
.cmp-table td {
  padding: 12px 10px;
  text-align: center;
  vertical-align: middle;
  font-weight: 500;
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

/* Pinned label column. Opaque so scrolled figures pass behind it. */
.cmp-table .cmp-corner,
.cmp-table .cmp-rowhead {
  position: sticky;
  left: 0;
  z-index: 2;
  width: var(--cmp-label-w);
  text-align: left;
  background: var(--surface);
  color: var(--muted);
  font-weight: 400;
  font-size: 0.84rem;
  padding-left: 14px;
}

/* Only once there is something hidden behind it, so the divider does not
   sit there implying a scroll that cannot happen. */
.cmp-scroll.is-scrolled .cmp-corner,
.cmp-scroll.is-scrolled .cmp-rowhead {
  box-shadow: 10px 0 10px -10px rgba(26, 20, 64, 0.28);
}

/* ---- header row ----
   A fixed box, so the rank sits at the same height whether the insurer name
   runs to one line or two, and every name clears the same badge row. */
.cmp-table thead th {
  scroll-snap-align: start;
  vertical-align: top;
  height: 132px;
  padding-top: 18px;
  padding-bottom: 14px;
}

.cmp-head-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  height: 100%;
}

.cmp-name-wrap { flex: 1; display: flex; align-items: center; }

/* Holds the row open in the four columns that are not the best price. */
.cmp-badge-ghost { visibility: hidden; }

.cmp-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 9px;
  background: var(--mist);
  color: var(--muted-2);
  font-family: var(--font-display);
  font-size: 0.82rem;
  font-weight: 700;
}

/* Holds the insurer's mark. The type below it only shows if the logo
   fails to load, and the column is narrow, so the mark is capped on width
   as well as height -- Sanlam Allianz is the one that would otherwise run
   past its column and shove the table sideways. */
.cmp-name {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  line-height: 1.2;
  --ins-h: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

.cmp-name .ins-logo { object-position: center; }

.cmp-table .is-best .cmp-rank { background: var(--brand); color: #fff; }

/* ---- body cells ---- */
.cmp-table tbody th,
.cmp-table tbody td { border-top: 1px solid var(--border); }

/* Money and cover are different kinds of fact; the rule says so. */
.cmp-table tbody tr.cmp-sep th,
.cmp-table tbody tr.cmp-sep td { border-top: 1.5px solid var(--border-strong); }

/* Scoped under .cmp-table on purpose: the blanket cell rule above sets
   font-size and font-weight, and at equal specificity it wins. Without this
   the premium renders at body size and weight, which is the one number on
   the page that must not. No nowrap either: a six-figure premium wraps
   inside its cell rather than spilling out of a fixed-layout column. */
.cmp-table .cmp-figure {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  color: var(--ink);
  line-height: 1.15;
}

.cmp-figure small {
  display: block;
  font-family: var(--font-body);
  font-size: 0.7rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--muted-2);
  margin-top: 3px;
}

.cmp-win { color: var(--brand); }
.cmp-table .cmp-save { color: var(--ok); font-weight: 600; }
.cmp-none { color: var(--muted-2); }

.cmp-mark { display: inline-flex; }
.cmp-mark svg { width: 17px; height: 17px; }
.cmp-yes svg { stroke: var(--brand); stroke-width: 2.6; fill: none; }
.cmp-no svg { stroke: var(--muted-2); stroke-width: 2.2; fill: none; }

/* ---- best column ---- */
.cmp-table .is-best { background: var(--brand-tint); }
.cmp-table thead th.is-best { border-radius: var(--radius) var(--radius) 0 0; }
.cmp-table tfoot td.is-best { border-radius: 0 0 var(--radius) var(--radius); }

/* ---- actions row ---- */
.cmp-table tfoot td { border-top: 1px solid var(--border); padding-top: 16px; padding-bottom: 20px; }
.cmp-table tfoot .btn { width: 100%; padding-inline: 12px; }

/* Right-edge fade: the only cue that columns four and five exist. Removed
   by JS at the end of the scroll and never drawn when nothing overflows. */
.cmp-fade {
  position: absolute;
  top: 1.5px;
  right: 1.5px;
  bottom: 1.5px;
  width: 44px;
  pointer-events: none;
  border-radius: 0 var(--radius-lg) var(--radius-lg) 0;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), var(--surface));
  opacity: 0;
  transition: opacity 0.2s var(--ease);
}

.cmp-scroll.can-scroll-right + .cmp-fade { opacity: 1; }

/* ---- pager ----
   "Swipe sideways to see every insurer" told a phone user that more existed
   but not how much more, and gave them no way to reach column five except
   four swipes. One dot per insurer answers both. Hidden whenever the table
   fits, which is most desktop widths. */
.cmp-pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 10px;
}

.cmp-pager[hidden] { display: none; }

.cmp-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  flex-shrink: 0;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  border-radius: 50%;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.15s var(--ease), color 0.15s var(--ease), opacity 0.15s var(--ease);
}

.cmp-nav svg { width: 15px; height: 15px; }
.cmp-nav:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.cmp-nav:disabled { opacity: 0.32; cursor: default; }

.cmp-dots { display: flex; align-items: center; gap: 4px; }

/* The tap target is 30px; the dot inside it is 7px. Anything smaller than
   the first is a miss on a phone, anything bigger than the second is a
   row of buttons competing with the table. */
.cmp-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
}

.cmp-dot span {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--border-strong);
  transition: background-color 0.18s var(--ease), width 0.18s var(--ease);
}

.cmp-dot.is-current span { background: var(--brand); width: 18px; border-radius: 999px; }

/* One spelling of each row label per breakpoint. */
.cmp-lb-short { display: none; }

.cmp-skeleton { display: grid; gap: 12px; padding: 22px; }

/* Phone: exactly two insurers on screen, snapped, with the pager to walk
   the rest. The old free scroll left half a column hanging at the right
   edge whichever way you flicked it. */
@media (max-width: 719px) {
  .cmp {
    --cmp-label-w: 72px;
    --cmp-col-w: calc((100% - var(--cmp-label-w)) / 2);
  }

  .cmp-scroll { scroll-snap-type: x mandatory; }

  /* The edge fade says "a column is cut off here". Snapping means one never
     is, so all it did was grey out the second insurer's price and Choose
     button. The pager carries the "there is more" message instead. */
  .cmp-fade { display: none; }

  .cmp-lb-long { display: none; }
  .cmp-lb-short { display: inline; }
}

@media (max-width: 639px) {
  .cmp-table th,
  .cmp-table td { padding: 10px 6px; font-size: 0.86rem; }
  .cmp-table .cmp-corner,
  .cmp-table .cmp-rowhead { padding-left: 11px; padding-right: 4px; font-size: 0.79rem; line-height: 1.25; }
  .cmp-table .cmp-figure { font-size: 0.96rem; }
  .cmp-table thead th { height: 118px; padding-top: 14px; padding-bottom: 12px; }
  .cmp-name { font-size: 0.92rem; --ins-h: 20px; }
  .cmp-table tfoot .btn { padding: 11px 8px; font-size: 0.88rem; }
}


/* ---- Journey rail (one progress model across all three stages) -----------
   The funnel had a progress bar, results had nothing, checkout an eyebrow. */
.flow-rail { display: flex; align-items: center; gap: 10px; }

.flow-rail .fr-step {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.84rem;
  font-weight: 500;
  color: var(--muted);
  white-space: nowrap;
  text-decoration: none;
}

.flow-rail .fr-step.is-current { font-weight: 600; color: var(--ink); }

.flow-rail .fr-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  flex-shrink: 0;
  font-family: var(--font-display);
  font-size: 0.72rem;
  font-weight: 700;
  background: var(--mist);
  color: var(--muted-2);
}

.flow-rail .fr-dot svg { width: 9px; height: 9px; stroke: #fff; }
.flow-rail .fr-step.is-done .fr-dot { background: var(--brand); color: #fff; }
.flow-rail .fr-step.is-current .fr-dot { background: var(--ink); color: #fff; }
.flow-rail .fr-line { width: 28px; height: 1.5px; background: var(--border-strong); flex-shrink: 0; }
.flow-rail .fr-line.is-done { background: var(--brand); }

.site-nav .flow-rail { margin-inline: auto; }

@media (max-width: 979px) { .flow-rail { display: none; } }

/* ---- Confirmation status cards -------------------------------------------
   The confirmation used to end with one button and no sense of what is
   still outstanding. */
.status-cards { display: grid; grid-template-columns: 1fr; gap: 12px; margin-top: 14px; }

@media (min-width: 760px) {
  .status-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.status-cards .sc {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 20px;
}

.status-cards .sc-state {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.78rem;
  font-weight: 600;
  margin-bottom: 8px;
  color: var(--muted-2);
}

.status-cards .sc-state svg { width: 12px; height: 12px; stroke: currentColor; }
.status-cards .sc-state .sc-bullet { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status-cards .sc-state.is-done { color: var(--ok); }
.status-cards .sc-state.is-active { color: var(--brand); }

.status-cards .sc b { display: block; font-size: 0.98rem; letter-spacing: -0.015em; margin-bottom: 3px; }
.status-cards .sc .sc-note { font-size: 0.86rem; color: var(--muted); }

/* ---- Hero proof row (landing) --------------------------------------------
   Three generic checkmarks became three facts, one of them a real price
   floor computed from the insurer rate tables. */
.hero-proof {
  display: flex;
  align-items: stretch;
  margin-top: 40px;
  border: 1px solid var(--border);
  background: var(--surface);
  border-radius: var(--radius);
  overflow: hidden;
  max-width: 560px;
}

.hero-proof .hp-item { flex: 1; padding: 14px 18px; min-width: 0; }
.hero-proof .hp-divider { width: 1px; background: var(--border); flex-shrink: 0; }

.hero-proof .hp-figure {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.035em;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.hero-proof .hp-label { font-size: 0.78rem; color: var(--muted); margin-top: 3px; }
.hero-footnote { font-size: 0.74rem; color: var(--muted-2); margin: 8px 0 0; }

@media (max-width: 639px) {
  .hero-proof { flex-direction: column; }
  .hero-proof .hp-divider { width: auto; height: 1px; }
  .hero-proof .hp-item { display: flex; align-items: baseline; gap: 10px; padding: 12px 16px; }
  .hero-proof .hp-label { margin-top: 0; }
}

/* ---- Static insurer row --------------------------------------------------
   A scrolling strip of insurer names reads as decoration rather than proof,
   and cannot be scanned. */
/* A strip, not a section: the generic section padding (104px a side) left
   a single row of logos floating in a band three times its height, which
   is half of why they read as small. */
.insurer-row { border-block: 1px solid var(--border); background: var(--surface); padding-block: 28px; }

.insurer-row .ir-inner {
  display: flex;
  align-items: center;
  gap: 32px;
  padding-block: 20px;
}

.insurer-row .ir-label {
  margin: 0;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-2);
  white-space: nowrap;
}

.insurer-row .ir-names {
  display: flex; align-items: center; gap: 18px 38px; flex: 1; flex-wrap: wrap;
}

.insurer-row .ir-more { font-size: 0.9rem; color: var(--muted-2); white-space: nowrap; }

@media (max-width: 859px) {
  .insurer-row .ir-inner { flex-direction: column; align-items: flex-start; gap: 14px; }
  .insurer-row .ir-names { gap: 16px 28px; }
}

/* ---- insurer marks -------------------------------------------------------
   The five logos, wherever they appear. /app/app.css loads after this file
   and sizes its own contexts, so this stays the one place the marks are
   described.

   Set --ins-h on the container and leave the rest alone. The per-insurer
   --k is an optical correction, not a tidy-up: matched purely on height,
   Sicom reads oversized because its wordmark nearly fills its box, while
   Eagle reads small because a third of its box is the INSURANCE subline.
   These are the ratios at which the five carry the same weight side by
   side. If a mark is ever replaced, re-judge its number by eye -- nothing
   here can be derived from the new file's dimensions.

   A broken logo needs no fallback markup: the alt text is the insurer's
   name, so the surface degrades to what it used to show. That is also why
   alt is empty wherever the name is already printed beside the mark. */
.ins-logo {
  --k: 1;
  display: block;
  width: auto;
  height: calc(var(--ins-h, 22px) * var(--k));
  /* Never let a mark widen its container past what the layout allows.
     Sanlam Allianz is a two-name lockup at 8.6:1 against about 3:1 for the
     other four, so in a narrow cell it is the one that would overflow. */
  max-width: 100%;
  object-fit: contain;
  object-position: left center;
}
.ins-logo[data-ins="eagle"] { --k: 1.09; }
.ins-logo[data-ins="swan"] { --k: 0.95; }
.ins-logo[data-ins="sicom"] { --k: 0.95; }
.ins-logo[data-ins="sanlam"] { --k: 0.86; }

/* The strip is proof, not a footnote: at 22px the marks read as fine print
   in a band with room to spare. 34px gives them the weight of the trust row
   they are. Narrow screens wrap the row, so they can stay large too. */
.insurer-row .ir-names { --ins-h: 34px; }
@media (max-width: 859px) { .insurer-row .ir-names { --ins-h: 27px; } }

/* ---- Demo mode: the empty seat -------------------------------------------
   Shown only when an insurer has been held out on /demo. It has to read as
   one of the five and obviously not be one of them at the same time: same
   card, same column width, dashed edge, no price, nothing to click. */

.badge-soon {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  align-self: flex-start;
  background: var(--warn-bg);
  color: #8a5a00;
  border: 1px solid var(--warn-border);
  border-radius: 999px;
  padding: 3px 10px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  white-space: nowrap;
}

.offer-teaser {
  border-style: dashed;
  border-color: var(--border-strong);
  background: linear-gradient(180deg, var(--mist), var(--surface) 70%);
}

.offer-teaser:hover { transform: none; box-shadow: none; }
.offer-teaser .offer-insurer { color: var(--muted); }
/* The held-out insurer's card is deliberately quiet. A colour change did
   that when the heading was type; a logo needs draining instead, or the
   one card with no price in it becomes the loudest thing on the page. */
.offer-teaser .ins-logo { filter: grayscale(1); opacity: 0.5; }
.offer-teaser .offer-meta { color: var(--muted-2); }

.offer-rank-none {
  color: var(--muted-2);
  opacity: 0.55;
}

.offer-price .amount-none {
  font-size: 1.35rem;
  font-weight: 700;
  color: var(--muted-2);
  letter-spacing: -0.02em;
}

/* Columns view */
.cmp-table .cmp-teaser {
  background: var(--mist);
  color: var(--muted-2);
  border-left: 1px dashed var(--border-strong);
}

.cmp-table th.cmp-teaser .cmp-name { color: var(--muted); }
.cmp-table th.cmp-teaser .ins-logo { filter: grayscale(1); opacity: 0.5; }

.cmp-rank-none {
  background: transparent;
  border: 1px dashed var(--border-strong);
  color: var(--muted-2);
}

.cmp-soon {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.25;
  color: #8a5a00;
  letter-spacing: 0;
}


/* ---- Printable quote sheet (js/quote-sheet.js) ---------------------------
   The one-page A4 takeaway. Built into a <div id="quote-sheet"> appended to
   <body>, hidden on screen, and the only thing left standing when the page
   is printed, which is how "Download PDF" is delivered without a PDF
   library: the browser's own print dialog writes the file.

   Sized in pt because the target is paper, not a viewport. Colour is a
   bonus, never load-bearing: most people print with background graphics
   off, so the best-price row is marked by a rule and a tag as well as a
   tint, and every figure reads in plain black. */
#quote-sheet { display: none; }

@media print {
  /* No page margin, and the sheet carries its own padding instead. Chrome's
     print dialog overrides @page margin, and the setting people reach for is
     "None", because it is what removes the browser's URL and date header. On
     that setting a margin declared here is dropped and the sheet prints flush
     to the paper edge with the right-hand column cut off. Padding inside the
     sheet cannot be overridden by the dialog. */
  @page { size: A4 portrait; margin: 0; }

  html, body {
    background: #fff !important;
    overflow: visible !important;
  }

  /* Everything that is not the sheet: nav, watermark, main, footer. Guarded
     on the sheet existing, so a page that never builds one (or a results
     page printed before the offers land) still prints itself rather than a
     blank sheet of paper. */
  body:has(> #quote-sheet) > * { display: none !important; }
  body > #quote-sheet { display: block !important; }

  /* The sheet borrows the site's tokens and fonts, but none of its layout:
     `section { padding-block: clamp(3rem, 8vw, 6.5rem) }` alone was adding
     56px of air above and below the facts block. */
  .qs-page section { padding: 0; }

  .qs-page {
    padding: 12mm 11mm;
    font-family: var(--font-body);
    font-size: 10pt;
    line-height: 1.4;
    color: #1a1440;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .qs-sr {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  /* ---- header ---- */
  .qs-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16pt;
    padding-bottom: 8pt;
    border-bottom: 1.4pt solid #1a1440;
  }

  .qs-logo { height: 26pt; width: auto; }

  .qs-title {
    font-family: var(--font-display);
    font-size: 16pt;
    font-weight: 800;
    letter-spacing: -0.03em;
    margin: 7pt 0 0;
  }

  .qs-title span {
    display: block;
    font-family: var(--font-body);
    font-size: 9pt;
    font-weight: 500;
    letter-spacing: 0;
    color: #635a8a;
    margin-top: 2pt;
  }

  .qs-meta {
    display: grid;
    grid-template-columns: auto auto;
    gap: 1pt 10pt;
    margin: 0;
    font-size: 8.5pt;
    text-align: right;
  }

  .qs-meta dt { color: #635a8a; }
  .qs-meta dd { margin: 0; font-weight: 600; }
  .qs-ref { font-variant-numeric: tabular-nums; letter-spacing: 0.02em; }
  .qs-ref-none { color: #9d8ec4; font-weight: 500; }

  .qs-stamp {
    margin: 7pt 0 0;
    font-size: 7.5pt;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: #9d8ec4;
  }

  /* ---- the number the sheet exists for ---- */
  .qs-saving {
    margin: 10pt 0 0;
    padding: 9pt 11pt;
    border: 0.8pt solid #cdc4ee;
    border-left: 3pt solid #7b39ec;
    border-radius: 3pt;
    background: #f5f3ff;
    font-size: 10pt;
  }

  .qs-saving b {
    font-family: var(--font-display);
    font-size: 13pt;
    letter-spacing: -0.02em;
  }

  /* ---- what was answered ---- */
  .qs-facts { display: flex; gap: 18pt; margin-top: 13pt; }
  .qs-facts-col { flex: 1; min-width: 0; }
  .qs-facts-wide { flex: 2; }

  .qs-facts h2 {
    font-family: var(--font-body);
    font-size: 7.5pt;
    font-weight: 600;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    color: #9d8ec4;
    margin: 0 0 5pt;
  }

  .qs-facts dl { margin: 0; display: grid; grid-template-columns: 1fr; gap: 0 14pt; }
  .qs-facts-wide dl { grid-template-columns: 1fr 1fr; }

  .qs-facts dl > div {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8pt;
    padding: 3pt 0;
    border-bottom: 0.4pt dotted #cdc4ee;
  }

  .qs-facts dt { color: #635a8a; white-space: nowrap; }
  .qs-facts dd { margin: 0; font-weight: 600; text-align: right; }

  /* ---- the comparison ----
     Rows, not the on-screen columns: paper is portrait, and five insurers
     across 186mm would squeeze every figure it exists to show. */
  .qs-table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 14pt;
    font-size: 9.5pt;
    font-variant-numeric: tabular-nums;
  }

  .qs-table thead th {
    font-size: 7pt;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: #635a8a;
    text-align: center;
    padding: 0 3pt 5pt;
    border-bottom: 1pt solid #1a1440;
  }

  .qs-table .qs-th-name { text-align: left; }
  .qs-table .qs-th-mark { width: 8%; }

  .qs-table td {
    padding: 8.5pt 3pt;
    text-align: center;
    vertical-align: middle;
    border-bottom: 0.4pt solid #e6e1f7;
  }

  .qs-row { page-break-inside: avoid; break-inside: avoid; }

  .qs-rank { width: 5%; color: #9d8ec4; font-weight: 700; font-size: 8pt; }

  .qs-name {
    text-align: left;
    font-family: var(--font-display);
    font-size: 11pt;
    font-weight: 700;
    letter-spacing: -0.02em;
  }

  .qs-tag {
    display: inline-block;
    margin-left: 5pt;
    padding: 1pt 4pt;
    border: 0.6pt solid #2b1d00;
    border-radius: 2pt;
    background: #ffd83d;
    font-family: var(--font-body);
    font-size: 6.5pt;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #2b1d00;
    vertical-align: 1.5pt;
  }

  .qs-money {
    font-family: var(--font-display);
    font-size: 13pt;
    font-weight: 800;
    letter-spacing: -0.03em;
    white-space: nowrap;
  }

  .qs-num, .qs-save { white-space: nowrap; }
  .qs-save { color: #0e7a50; font-weight: 600; }

  /* Tint is the nice-to-have; the left rule is what survives a printer with
     background graphics turned off. */
  .qs-best td { background: #f5f3ff; }
  .qs-best .qs-rank { box-shadow: inset 2.5pt 0 0 #7b39ec; }
  .qs-best .qs-money { color: #7b39ec; }

  .qs-mark { display: inline-block; width: 11pt; height: 11pt; }
  .qs-yes { color: #7b39ec; }
  .qs-no { color: #c4b9e4; }

  .qs-row-soon td { color: #9d8ec4; }
  .qs-row-soon .qs-name { color: #635a8a; }
  .qs-soon { text-align: left; font-style: italic; }

  /* ---- small print ---- */
  .qs-foot {
    margin-top: 13pt;
    padding-top: 8pt;
    border-top: 0.4pt solid #cdc4ee;
    font-size: 7.6pt;
    line-height: 1.45;
    color: #635a8a;
  }

  .qs-foot p { margin: 0 0 3pt; }
  .qs-foot b { color: #1a1440; }

  .qs-foot-line {
    display: flex;
    justify-content: space-between;
    margin-top: 6pt;
    padding-top: 5pt;
    border-top: 0.4pt solid #e6e1f7;
    font-size: 6.8pt;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #1a1440;
  }

  /* A shouted URL is a worse URL to type back in. */
  .qs-foot-url { text-transform: none; letter-spacing: 0.03em; }
}

.tb-note { font-size: 0.8rem; color: var(--muted); margin-left: 8px; }

/* The excess slider takes a row of its own in the toolbar. Its readout keeps
   a floor width so the track does not shuffle sideways as the figure grows a
   digit, or as "Insurer's standard" gives way to a number. */
.results-toolbar .tb-excess { width: 100%; flex-wrap: wrap; }
/* display:flex above would otherwise beat the UA rule for [hidden], which is
   how the row leaves on third party. */
.results-toolbar .tb-excess[hidden] { display: none; }
.results-toolbar .tb-excess .range-host { flex: 1; min-width: 160px; max-width: 380px; }
.results-toolbar .tb-excess .range-field { display: flex; align-items: center; gap: 12px; margin: 0; }
.results-toolbar .tb-excess .range-readout {
  font-size: 0.95rem;
  margin: 0;
  min-width: 8.5rem;
  white-space: nowrap;
}
.results-toolbar .tb-excess .range-input { flex: 1; }

/* Kept next to the rules above rather than in the phone block further up the
   file: these selectors are the same weight, so the one that comes last is
   the one that wins and a media query adds nothing to that. */
@media (max-width: 859px) {
  /* Between the readout and Reset the track was down to about 40px of
     travel, which is not a slider. It takes a line of its own here and the
     note takes another, leaving the label and Reset on the first. */
  .results-toolbar .tb-excess { row-gap: 6px; }
  /* 0 0 100%, not flex-basis alone: the shrink the rule above sets would let
     it give the width back and stay on the first line. */
  .results-toolbar .tb-excess .range-host { flex: 0 0 100%; max-width: none; order: 2; }
  .results-toolbar .tb-excess .tb-reset { margin-inline-start: auto; }
  .results-toolbar .tb-excess .tb-note { flex-basis: 100%; order: 3; margin-left: 0; }
}

/* A plain word, not a fourth button: the row already carries a label, a
   figure and a track, and a bordered control would read as a fourth choice
   rather than as the way back out of the three. */
.tb-reset {
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  font-size: 0.8rem;
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  flex-shrink: 0;
}
.tb-reset:hover { color: var(--ink); }

/* ---- proposal form (js/proposal-view.js) ---- */
.pf-count { font-size: 0.8rem; color: var(--muted); margin: 0 0 6px; font-variant-numeric: tabular-nums; }
.pf-title { margin: 18px 0 4px; }
.pf-fields { display: grid; gap: 4px; margin-top: 14px; }
/* The view labels groups with a span or p (radios, dates and rows have no
   single control to point a <label for> at), which the form rules above only
   style when it is a <label>. */
.pf-fields .field-label { display: block; font-size: 0.9rem; font-weight: 600; color: var(--ink); margin-bottom: 8px; letter-spacing: -0.01em; }
.pf-fields textarea { width: 100%; resize: vertical; }
.segmented.pf-wrap { grid-auto-flow: row; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); border-radius: 18px; }
/* .field .pf-check, not .pf-check: `.field label` above is more specific and
   would set it back to display:block and bold. */
.field .pf-check { display: grid; grid-template-columns: 20px 1fr; gap: 10px; align-items: start; font-size: 0.92rem; font-weight: 400; cursor: pointer; }
.pf-check input { margin-top: 3px; }
/* The privacy tick's link to TEGO's notice, under the statement, lined up
   with its text rather than with the box. */
.pf-check-link { display: inline-block; margin: 6px 0 0 30px; font-size: 0.86rem; color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }
.pf-rows { margin: 10px 0; }
.pf-row { border: 1px solid var(--border); border-radius: 14px; padding: 14px 16px 6px; margin: 10px 0; min-width: 0; }
.pf-row legend { font-weight: 600; padding: 0 6px; }
.pf-add, .pf-remove { margin: 4px 0 10px; }
.date-parts.is-month { grid-template-columns: 1.6fr 1.2fr; }
.pf-summary { margin-top: 18px; padding: 16px 18px; }
.pf-summary summary { cursor: pointer; font-weight: 600; }
.pf-summary h3 { font-size: 0.95rem; margin: 16px 0 6px; }
.pf-summary dl { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 4px 14px; margin: 0; font-size: 0.88rem; }
.pf-summary dt { color: var(--muted); }
.pf-summary dd { margin: 0; overflow-wrap: anywhere; }
@media (max-width: 560px) { .pf-summary dl { grid-template-columns: 1fr; } .pf-summary dd { margin-bottom: 6px; } }

/* ---- S2 car data: engine suggestions (25/09) ------------------------------
   Chips under the engine field, one per engine the model is sold with. Real
   buttons with aria-pressed; tapping one fills the field. */
.engine-slot { margin-bottom: 20px; }
.engine-slot > .field { margin-bottom: 0; }
.engine-suggest { margin-top: 12px; }
.engine-suggest-label { font-size: 0.82rem; color: var(--muted); margin: 0 0 8px; }
.engine-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.engine-chip {
  min-height: 36px;
  padding: 6px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink-2);
  font: 500 0.86rem/1.2 var(--font-body);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: background-color 180ms var(--ease), border-color 180ms var(--ease), transform 180ms var(--ease);
}
.engine-chip:hover { border-color: var(--brand); background: var(--brand-tint); }
.engine-chip:active { transform: scale(0.97); }
.engine-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.engine-chip[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); color: var(--ink); box-shadow: inset 0 0 0 1px var(--brand); }
.engine-note { font-size: 0.82rem; color: var(--ink-3); margin: 10px 0 0; }
/* Visually empty, not `hidden`: the note stays in the accessibility tree
   while it has nothing to say (see js/vehicle-picker.js render()). display:
   none would pull it back out, so this only drops the margin that used to
   separate it from the chips above. */
.engine-note:empty { margin: 0; }
@media (prefers-reduced-motion: reduce) {
  .engine-chip { transition: none; }
  .engine-chip:active { transform: none; }
}

/* ---- S4 travel preview: the tag, the line, the visa badge ----------------
   Travel lives on tego.influxe.agency only, which is public, and its prices
   are invented. The tag and the sentence every travel page carries are what
   stop a screenshot from reading as an offer, so they are styled once, here.
   The rest of each travel page's layout is in its own <style>. */
.preview-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 11px;
  border: 1px dashed var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.preview-tag::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lilac);
}
.preview-line { margin: 0; font-size: 0.8rem; color: var(--muted); }

/* The plans a Schengen visa application accepts. Green, the colour the site
   already uses for "this is fine", so it never competes with best price. */
.visa-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: rgba(14, 122, 80, 0.12);
  color: var(--ok);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}
.visa-badge svg { width: 11px; height: 11px; stroke: currentColor; flex-shrink: 0; }

/* The nav's Travel link on the preview hosts (js/shell.js). */
.site-nav .nav-links a .pill {
  margin-left: 6px;
  padding: 2px 7px;
  font-size: 0.62rem;
  background: var(--brand-soft);
  color: var(--brand);
}

/* "Voyage APERÇU" is wider than "Travel Preview"; below 640px it wrapped
   the nav links to a second line, so the pill drops and the link stands
   on its own like every other one next to it. */
@media (max-width: 639px) {
  .site-nav .nav-links a .pill { display: none; }
}

/* ---- S3 proposal v2: recap, groups, chat ---- */
/* The view scrolls its host to the top on a stage change; the nav is sticky
   and would sit over the first line. */
#proposal-host { scroll-margin-top: calc(var(--nav-h) + 18px); }
/* Focus lands on the heading after a stage change, for screen readers; a
   ring round a heading nobody can type into reads as a bug. */
.pf-title:focus { outline: none; }
/* Under the panel's h1, not over it: the global h2 is a landing-page size. */
#proposal-host .pf-title { font-size: clamp(1.35rem, 2.6vw, 1.75rem); line-height: 1.12; letter-spacing: -0.025em; }
.pf-sim-note { margin: 14px 0 0; }

.pf-recap-section { margin-top: 28px; }
.pf-recap-section h3 { font-size: 1.08rem; margin: 0 0 8px; letter-spacing: -0.02em; }
.pf-recap-lede { font-size: 0.86rem; color: var(--muted); margin: 0 0 6px; }
.pf-recap { margin: 0; border-top: 1px solid var(--border); }
/* The quote facts and the cover start are two lists under one heading;
   they read as one. */
.pf-recap + .pf-recap { border-top: 0; }
/* Label | value, badge and Edit. One column on a phone, where a label
   squeezed beside a chassis number and a badge helps nobody. */
.pf-recap-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 4px 18px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--border);
}
.pf-recap-item dt { font-size: 0.88rem; color: var(--muted); }
.pf-recap-item dd { margin: 0; display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.pf-recap-item.is-fact { min-height: 52px; }
.pf-recap-body { display: flex; flex-direction: column; align-items: flex-start; gap: 5px; min-width: 0; }
.pf-recap-value { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; white-space: pre-line; font-variant-numeric: tabular-nums; }
.pf-recap-value.is-empty { color: var(--muted); font-weight: 400; }
.pf-changed { font-size: 0.8rem; font-weight: 500; color: var(--ink-3); }
.pf-recap-asks { margin-top: 16px; }

/* Where a value came from. Three looks for three sources: neutral for the
   quote, the brand outline for TEGO's own suggestion, warm for the
   simulated read, which says "simulation" in its own words. */
.pf-badge {
  display: inline-block;
  max-width: 100%;
  padding: 2px 9px;
  border: 1px solid transparent;
  border-radius: 10px;
  font-size: 0.74rem;
  font-weight: 600;
  line-height: 1.45;
}
.pf-badge.is-quote { background: var(--mist); color: var(--muted); }
.pf-badge.is-derived { background: var(--surface); border-color: var(--brand); color: var(--brand); }
.pf-badge.is-doc { background: var(--warn-bg); border-color: var(--warn-border); color: #8a5a00; }

.pf-edit {
  flex-shrink: 0;
  min-width: 44px;
  min-height: 44px;
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--brand);
  font: inherit;
  font-size: 0.88rem;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), color 0.15s var(--ease);
}
.pf-edit:hover { background: var(--brand-tint); color: var(--brand-hover); }
.pf-edit:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.pf-recap-item.is-editing {
  display: block;
  margin: 8px 0;
  padding: 14px 16px 16px;
  background: var(--brand-tint);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}
.pf-recap-item.is-editing dd { display: block; }
.pf-recap-item.is-editing .pf-fields { margin-top: 0; }
.pf-recap-item.is-editing .field { margin-bottom: 12px; }
.pf-done { min-height: 44px; }

@media (max-width: 560px) {
  .pf-recap-item { grid-template-columns: minmax(0, 1fr); gap: 2px; padding: 10px 0 6px; }
  .pf-recap-item dt { font-size: 0.82rem; }
  .pf-recap-item.is-fact { min-height: 0; padding-bottom: 10px; }
  .pf-recap-item.is-editing { padding: 12px 12px 14px; }
}

/* "Any of these?": one box per item, the whole row the tap target, and
   None of these under a heavier rule, because it answers the whole
   question rather than being one more item in it. */
.pf-group { border: 0; padding: 0; margin: 0 0 20px; min-width: 0; }
.pf-group legend { padding: 0; }
.pf-group-list {
  background: var(--surface);
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.pf-group-item {
  display: grid;
  grid-template-columns: 20px minmax(0, 1fr);
  gap: 12px;
  align-items: start;
  min-height: 44px;
  margin: 0;
  padding: 12px 16px;
  font-size: 0.94rem;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.15s var(--ease);
}
.pf-group-item + .pf-group-item { border-top: 1px solid var(--border); }
.pf-group-item.pf-group-none { border-top: 2px solid var(--border-strong); font-weight: 600; }
.pf-group-item:hover { background: var(--brand-tint); }
.pf-group-item:has(input:checked) { background: var(--brand-soft); }
.pf-group-item:has(input:focus-visible) { box-shadow: inset 0 0 0 2px var(--brand); }
.pf-group-item input { width: 20px; height: 20px; margin: 1px 0 0; accent-color: var(--brand); cursor: pointer; }
.pf-group-text { min-width: 0; }
.pf-group-item .hint { display: block; margin-top: 3px; font-size: 0.82rem; font-weight: 400; color: var(--muted); }
.pf-group.has-error .pf-group-list { border-color: var(--error); }
.pf-group-error { margin: -12px 0 20px; }

@media (prefers-reduced-motion: reduce) {
  .pf-edit, .pf-group-item { transition: none; }
}

/* =========================================================================
   S1 funnel UX (23/09): the brick road and its answers sheet (js/brick-road.js),
   the rail's bricks, the brick loader (js/brick-loader.js)
   ========================================================================= */

/* ---- Brick road ----
   The whole journey as twelve TEGO bricks. Each brick grows by its stud
   count and every gap is fixed, so one stud is the same width everywhere
   and the group labels underneath line up with their bricks: the bricks'
   fixed space (11 gaps + 2 group gaps) equals the labels' (in-group gaps as
   flex-basis + 2 group gaps). */
.brick-road { --br-gap: 3px; --br-group-gap: 10px; max-width: 600px; }

/* The road carries the flow rail's three groups; never both at once. */
.has-brick-road .site-nav .flow-rail { display: none; }

.br-toggle {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
}
button.br-toggle { cursor: pointer; border-radius: var(--radius-sm); }

/* v2 (28/09): the head says where you are AND what comes next. Two lines on
   the left (the step, then "Next: …"), the percentage and the answers pill
   centred against them. The step's count is muted and its title is in ink:
   a screenshot of the road used to read as one muted line and a big
   number, with nothing after the documents step to say four bricks were
   still to come. */
.br-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; font-size: 0.82rem; }
.br-where { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.br-step { display: block; min-width: 0; font-weight: 600; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.br-step-t { color: var(--ink); font-weight: 700; }
.br-next { display: block; min-width: 0; font-size: 0.74rem; font-weight: 500; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.br-pct { font-family: var(--font-display); font-weight: 700; font-size: 0.95rem; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A pill, so the one thing on the road that opens something looks like it. */
.br-more {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--brand);
  white-space: nowrap;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease);
}
.br-more svg { width: 13px; height: 13px; }
button.br-toggle:hover .br-more, button.br-toggle:focus-visible .br-more { background: var(--brand-tint); border-color: var(--brand); }

/* Below 420px the step label and "Vos réponses" fight for the same row in
   French ("Étape 12 sur 12 · Vous êtes a…"): hide the pill's words and keep
   only the icon, sized so .br-where gets the room. Visually hidden, not
   display:none, so the button's accessible name still carries them. */
@media (max-width: 419px) {
  /* 8px, not 10: at 360px "Étape 9 sur 12 · Vérification d'identité" was
     one pixel short of fitting beside the percentage and the pill. */
  .br-head { gap: 8px; }
  .br-more { padding: 6px 7px; }
  .br-more-text {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}

.br-bricks { display: flex; align-items: flex-end; gap: var(--br-gap); }
.br-brick { position: relative; display: block; flex: 2 1 0; min-width: 0; }
.br-brick.is-group-start { margin-left: calc(var(--br-group-gap) - var(--br-gap)); }
.br-brick > span { display: block; }
.br-brick svg { display: block; width: 100%; height: auto; overflow: visible; }
.br-brick .face { vector-effect: non-scaling-stroke; stroke-width: 1.25px; stroke-linejoin: round; }
.br-shell .face { fill: var(--surface); stroke: var(--border-strong); }
.br-fill {
  position: absolute;
  inset: 0;
  clip-path: inset(0 calc((1 - var(--fill, 0)) * 100%) 0 0);
  transition: clip-path 0.35s var(--ease);
}
.br-fill .face { fill: var(--brand); stroke: var(--brand-hover); }
/* Placed by the bank, not by the customer: done, in a lighter shade. */
.br-brick[data-auto] .br-fill .face { fill: var(--periwinkle); stroke: var(--brand); }
.br-brick[data-status="current"] .br-shell .face { fill: var(--brand-tint); stroke: var(--brand); stroke-width: 1.75px; }
/* The current brick hovers, waiting to be pressed down, and carries a caret
   underneath: with the motion off (or in a screenshot) the tint alone was
   not enough to tell it from an empty brick. */
.br-brick[data-status="current"] { animation: br-hover 1.8s ease-in-out infinite; }
.br-brick[data-status="current"]::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -9px;
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-bottom: 6px solid var(--brand);
  transform: translateX(-50%);
}
@keyframes br-hover { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } }
.br-brick.is-snapping .br-fill { animation: br-snap 0.35s var(--ease-spring); }
@keyframes br-snap { from { transform: translateY(-80%); opacity: 0; } to { transform: none; opacity: 1; } }

/* margin-top clears the current brick's caret. */
.br-groups { display: flex; gap: var(--br-group-gap); margin-top: 10px; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.02em; color: var(--muted-2); }
/* Start, centre, end: the middle label is wider than its one brick on a
   phone, and centred it overflows into the space the other two leave. */
.br-group { display: flex; min-width: 0; white-space: nowrap; justify-content: flex-start; }
.br-group:nth-child(2) { justify-content: center; }
.br-group:last-child { justify-content: flex-end; }
.br-group.is-current { color: var(--brand); }
.br-group.is-done { color: var(--ink-3); }
.br-group a { color: inherit; text-decoration: none; }
.br-group a:hover { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; }

/* Results and checkout: the road sits at the top of the page, and on a
   phone it rides under the nav the way the funnel's progress always has.
   min-height holds its place before js/brick-road.js mounts into it, so the
   page below does not jump once it paints (measured with the v2 head's two
   lines: 110px at 390px wide, padding included, 103px at 1280px). */
.brick-road-host { margin: 0 0 22px; min-height: 103px; }
@media (max-width: 919px) {
  .brick-road-host {
    position: sticky;
    top: var(--nav-h);
    z-index: 30;
    max-width: none;
    min-height: 110px;
    margin: 0 calc(-1 * clamp(20px, 4vw, 32px)) 18px;
    padding: 10px clamp(20px, 4vw, 32px) 8px;
    background: rgba(250, 249, 255, 0.92);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
  }
}

/* ---- Answers sheet ----
   A modal <dialog>: a bottom sheet on a phone, a centred card above. */
html.sheet-open { overflow: hidden; }
.answers-sheet {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  width: min(480px, calc(100% - 32px));
  max-width: none;
  max-height: calc(100dvh - 48px);
  overflow: visible;
}
.answers-sheet::backdrop { background: rgba(26, 20, 64, 0.45); }
.as-card {
  background: var(--surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  padding: 20px 20px 18px;
  max-height: inherit;
  overflow-y: auto;
}
.as-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.as-title { font-size: 1.3rem; margin: 0; }
.as-close {
  width: 40px;
  height: 40px;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--mist);
  color: var(--ink);
  cursor: pointer;
}
.as-close svg { width: 16px; height: 16px; }
.as-sub { margin: 4px 0 12px; font-size: 0.85rem; color: var(--muted); }
.as-row {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  gap: 12px;
  align-items: center;
  padding: 12px 0;
  border-top: 1px solid var(--border);
}
.as-brick svg { display: block; width: 26px; height: auto; overflow: visible; }
.as-brick .face { fill: var(--brand); stroke: var(--brand-hover); vector-effect: non-scaling-stroke; stroke-width: 1.25px; }
.as-text b { display: block; font-size: 0.92rem; font-weight: 600; }
.as-text span { display: block; font-size: 0.86rem; color: var(--muted); overflow-wrap: anywhere; }
.as-edit { padding: 6px 12px; font-size: 0.85rem; }
.as-note { font-size: 0.76rem; color: var(--muted); white-space: nowrap; }
.as-empty { margin: 8px 0 0; color: var(--muted); font-size: 0.9rem; }
/* "Coming up": the bricks still to lay, drawn empty like they are on the road. */
.as-coming { margin: 16px 0 0; font-size: 0.7rem; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted-2); }
.as-up {
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding: 9px 0;
  border-top: 1px solid var(--border);
}
.as-up-text { font-size: 0.92rem; font-weight: 500; color: var(--muted); }
.as-brick.is-todo .face { fill: var(--surface); stroke: var(--border-strong); }

@media (max-width: 719px) {
  .answers-sheet { width: 100%; margin: auto 0 0; max-height: 86dvh; }
  .as-card {
    border-radius: 22px 22px 0 0;
    padding-bottom: calc(18px + env(safe-area-inset-bottom));
    animation: as-up 0.32s var(--ease);
  }
}
@keyframes as-up { from { transform: translateY(40px); opacity: 0; } to { transform: none; opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .br-brick, .br-brick .br-fill, .as-card { animation: none !important; transition: none !important; }
}

/* ---- The funnel rail's dots, as small bricks ----
   The desktop rail keeps its answers and Edit; its markers now read as the
   same bricks the road is built from. */
.rail-step .dot {
  --brick: var(--mist);
  position: relative;
  width: 30px;
  height: 22px;
  margin-top: 5px;
  border-radius: 6px;
  background: var(--brick);
}
.rail-step .dot::before,
.rail-step .dot::after {
  content: "";
  position: absolute;
  top: -5px;
  width: 9px;
  height: 5px;
  border-radius: 3px 3px 0 0;
  background: var(--brick);
  transition: background-color 0.2s var(--ease);
}
.rail-step .dot::before { left: 4px; }
.rail-step .dot::after { right: 4px; }
.rail-step.is-active .dot,
.rail-step.is-done .dot { --brick: var(--brand); }
/* White (is-done's glyph colour) is too faint on periwinkle; --ink reads
   clearly on it and wins here since this rule comes after is-done's. */
.rail-step.is-locked .dot { --brick: var(--periwinkle); color: var(--ink); }
/* Reached before, not finished: one click away, no tick. */
.rail-step.is-reachable { cursor: pointer; }
.rail-step.is-reachable .dot { --brick: var(--brand-soft); color: var(--brand); }
.rail-step.is-reachable .rail-title { color: var(--ink); }
.rail-step.is-reachable:hover { background: rgba(26, 20, 64, 0.04); }
.rail-step.is-reachable:hover .rail-edit,
.rail-step.is-reachable:focus-visible .rail-edit { opacity: 1; }

/* ---- Brick loader ----
   currentColor throughout, so it is white inside a primary button and
   brand purple on a white card. The dark edge keeps the bricks apart. */
.brick-loader { display: inline-flex; align-items: center; gap: 10px; vertical-align: middle; }
.bl-build { position: relative; display: block; flex: none; width: 26px; }
.bl-md .bl-build { width: 64px; }
.bl-md { color: var(--brand); }
.bl-plate { position: absolute; left: 0; right: 0; bottom: 0; border-radius: 2px; background: currentColor; opacity: 0.5; }
.bl-brick { position: absolute; display: block; animation: bl-drop 1.8s var(--ease-spring) infinite both; animation-delay: calc(var(--i) * 0.22s); }
.bl-brick svg { display: block; width: 100%; height: 100%; overflow: visible; }
.bl-brick .face { fill: currentColor; stroke: rgba(26, 20, 64, 0.35); stroke-width: 1px; vector-effect: non-scaling-stroke; stroke-linejoin: round; }
@keyframes bl-drop {
  0% { transform: translateY(-120%); opacity: 0; }
  20%, 78% { transform: none; opacity: 1; }
  92%, 100% { transform: none; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .bl-brick { animation: none !important; opacity: 1; transform: none; }
}
/* .btn:disabled's opacity: 0.5 halves the whole button, and a child's
   opacity cannot out-shine a dimmed parent -- so a button carrying the
   loader stays fully opaque and disabled reads as "busy", not "faded".
   No cursor here: .btn:disabled already sets pointer-events: none, so the
   cursor a busy button shows is whatever sits under it, and "progress"
   never drew. */
.btn.is-busy:disabled { opacity: 1; }
/* Form | Chat: two ways to answer the same questions (js/proposal-view.js). */
.pf-mode { margin: 18px 0 16px; }
.pf-mode-label { display: block; font-size: 0.9rem; font-weight: 600; color: var(--ink); margin-bottom: 8px; }
.pf-mode .segmented { max-width: 300px; }
.pf-mode .segmented label { min-height: 44px; }

/* The chat (js/proposal-chat.js). TEGO on the left in the light brand tint,
   the customer on the right in brand purple (white on #7b39ec is 5.8:1). The
   transcript flows with the page rather than scrolling in a box of its own:
   a box inside a page is two scrollbars on a phone. */
.pf-chat { margin-top: 8px; }
.chat-log { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.chat-msg { display: flex; flex-direction: column; align-items: flex-start; max-width: min(86%, 540px); }
.chat-msg.is-me { align-self: flex-end; align-items: flex-end; }
.chat-bubble {
  margin: 0;
  padding: 10px 15px;
  border-radius: 18px;
  font-size: 0.95rem;
  line-height: 1.42;
  overflow-wrap: anywhere;
  white-space: pre-line;
}
.chat-msg.is-tego .chat-bubble { background: var(--brand-tint); border: 1px solid var(--border); border-bottom-left-radius: 6px; color: var(--ink); }
.chat-msg.is-me .chat-bubble { background: var(--brand); border: 0; border-bottom-right-radius: 6px; color: #fff; font-weight: 500; }
.chat-msg.is-tego .chat-bubble.is-error { background: var(--error-bg); border-color: #f0c7c2; color: var(--error); font-weight: 500; }
/* An answer is a button: tap it to answer that question again. */
button.chat-bubble { min-height: 44px; font-family: inherit; text-align: left; cursor: pointer; transition: background-color 0.15s var(--ease); }
button.chat-bubble:hover { background: var(--brand-hover); }
button.chat-bubble:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }
/* Skipped is not an answer, and should not look like one: outlined, not
   filled (brand on brand-soft is 4.8:1). */
.chat-msg.is-me .chat-bubble.is-skipped { background: var(--brand-soft); color: var(--brand); box-shadow: inset 0 0 0 1px var(--border-strong); }
.chat-msg.is-me button.chat-bubble.is-skipped:hover { background: var(--brand-tint); }
.chat-hint { margin: 5px 4px 0; font-size: 0.82rem; line-height: 1.4; color: var(--muted); }

/* Three dots while TEGO "types"; the page's own reduced-motion rule below
   stills them, and the chat skips the pause altogether. */
.chat-typing {
  display: inline-flex;
  gap: 5px;
  margin-top: 10px;
  padding: 14px 16px;
  background: var(--brand-tint);
  border: 1px solid var(--border);
  border-radius: 18px;
  border-bottom-left-radius: 6px;
}
.chat-typing[hidden] { display: none; }
.chat-typing span { width: 7px; height: 7px; border-radius: 50%; background: var(--muted-2); animation: chat-dot 1s var(--ease) infinite; }
.chat-typing span:nth-child(2) { animation-delay: 0.15s; }
.chat-typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes chat-dot { 0%, 60%, 100% { opacity: 0.35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

.chat-answer { margin-top: 16px; outline: none; }
.chat-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chat-chip {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  min-height: 44px;
  max-width: 100%;
  padding: 10px 16px;
  border: 1.5px solid var(--border-strong);
  border-radius: 22px;
  background: var(--surface);
  color: var(--ink);
  font: 500 0.92rem/1.3 var(--font-body);
  text-align: left;
  cursor: pointer;
  transition: background-color 0.15s var(--ease), border-color 0.15s var(--ease), transform 0.15s var(--ease);
}
.chat-chip:hover { border-color: var(--brand); background: var(--brand-tint); }
.chat-chip:active { transform: scale(0.97); }
.chat-chip:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.chat-chip.is-current { border-color: var(--brand); }
.chat-chip-hint { margin-top: 3px; font-size: 0.8rem; font-weight: 400; color: var(--muted); }
/* A ticked item says so in shape as well as colour: a check before it. */
.chat-chip.is-toggle { padding-left: 38px; position: relative; }
.chat-chip.is-toggle::before {
  content: "";
  position: absolute;
  left: 14px;
  top: 50%;
  width: 14px;
  height: 14px;
  margin-top: -7px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: var(--surface);
}
.chat-chip.is-toggle[aria-pressed="true"] { border-color: var(--brand); background: var(--brand-soft); box-shadow: inset 0 0 0 1px var(--brand); }
.chat-chip.is-toggle[aria-pressed="true"]::before {
  border-color: var(--brand);
  background: var(--brand) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.2 5 8.5l4.5-5'/%3E%3C/svg%3E") center / 10px no-repeat;
}
.chat-chip.is-none { font-weight: 600; }
.chat-chip.is-skip { border-style: dashed; color: var(--muted); }
.chat-group-actions { margin-top: 12px; }

/* One line: the control, then Send. A date's three selects need the room,
   so on a phone Send drops under them, on the right. */
.chat-input { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
.chat-input > .chat-control { flex: 1 1 220px; min-width: 0; }
.chat-input > .chat-control.is-wide { flex-basis: 300px; }
.chat-input.is-stacked { flex-direction: column; align-items: stretch; }
.chat-input.is-stacked > .chat-control { flex: none; width: 100%; }
.chat-input.is-stacked .chat-send { align-self: flex-end; }
.chat-send { min-height: 48px; margin-left: auto; }
.chat-extra { margin-top: 10px; }
.chat-done { display: flex; }

/* New bubbles and a new question's controls rise in; a rebuilt transcript
   does not, it is simply there. */
.chat-log > .is-new, .chat-controls.is-new { animation: chat-in 180ms var(--ease) both; }
@keyframes chat-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .chat-log > .is-new, .chat-controls.is-new, .chat-typing span { animation: none; }
  .chat-chip, button.chat-bubble { transition: none; }
  .chat-chip:active { transform: none; }
}

/* ==== Demo fill (28/09) ==== */

/* The sample customer's strip (js/demo-fill.js) on /quote's first step and
   the checkout's documents panel, demo hosts only. Dashed and tinted like
   the funnel's "Demo mode" code line, so it reads as the presenter's aid
   and never as one more question. Nothing in it moves, so it needs no
   reduced-motion path. */
.demo-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0 0 18px;
  padding: 10px 12px 10px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--brand-tint);
  font-size: 0.86rem;
  line-height: 1.45;
  color: var(--muted);
}
/* The sentence takes whatever room is left. Where the row cannot hold it
   at 16rem beside the button, the button drops to a line of its own, still
   on the right; on a narrow phone the pill sits above the sentence. */
.demo-strip-text { flex: 1 1 16rem; min-width: 0; }
.demo-strip .btn { margin-left: auto; }

/* ==== P1: checkout's request states (29/09) ==== */

/* The confirmation panel's blocks, one per state of the request
   (js/checkout.js showState): sending, verify, staff, retry and sent. They
   sit in checkout.html's .confirmation-card, centred; these rules only add
   what a state needs beyond it. */
.cr-state { min-width: 0; }

/* The brick build (js/brick-loader.js) while the request is on its way,
   like the 3-D Secure one. The sentence under it is what a screen reader
   gets. */
.cr-loader { display: flex; justify-content: center; margin: 0 0 16px; }

.cr-lede { margin-bottom: 4px; }

/* The verify state's address and code: a form in a centred card, so the
   fields keep their own left edge, at a width a code is typed into. */
.cr-state .field { max-width: 360px; margin: 22px auto 0; text-align: left; }
.cr-state .field + .btn { margin-top: 12px; }
/* .confirmation-card p would make the error as muted as the lede. */
.cr-state .field-error { color: var(--error); margin-top: 12px; }

/* Where the documents went, under the reference. */
.cr-uploads {
  font-size: 0.86rem;
  line-height: 1.5;
  margin-top: 14px;
  padding: 10px 14px;
  border-radius: var(--radius);
  background: var(--brand-tint);
}
