
  /* Banner */
  #cv-cookie-banner {
    position: fixed;
    bottom: 0; left: 0; right: 0;
    background: var(--cvt-bg-surface);
    color: var(--cvt-text-primary);
    padding: 16px 24px;
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
    z-index: 9999;
    font-size: 13.5px;
    line-height: 1.5;
    box-shadow: var(--cvt-shadow-e3);
  }
  #cv-cookie-banner.hidden { display: none; }
  #cv-cookie-banner p { margin: 0; flex: 1; min-width: 220px; }
  #cv-cookie-banner a { color: var(--cvt-text-link); text-decoration: underline; cursor: pointer; }
  #cv-cookie-banner .cv-cookie-fine { color: var(--cvt-text-secondary); font-size: 12px; display: block; margin-top: 3px; }
  .cv-cookie-actions {
    display: flex; gap: 8px; flex-wrap: wrap; flex-shrink: 0;
  }
  .cv-cookie-btn {
    padding: 7px 16px;
    border-radius: var(--r-md, 8px);
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    border: 1.5px solid transparent;
    white-space: nowrap;
    transition: opacity 0.15s;
    font-family: inherit;
  }
  .cv-cookie-btn:hover { opacity: 0.85; }
  .cv-cookie-btn-accept {
    background: var(--cvt-action-primary-bg);
    color: var(--cvt-action-primary-fg);
    border-color: var(--cvt-action-primary-bg);
  }
  .cv-cookie-btn-reject {
    background: transparent;
    color: var(--cvt-text-primary);
    border-color: var(--cvt-border-control);
  }
  .cv-cookie-btn-manage {
    display: inline;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--cvt-text-link);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
  }

  /* Preferences modal */
  #cv-cookie-modal-overlay {
    position: fixed; inset: 0;
    background: var(--cvt-overlay-scrim);
    z-index: 10000;
    display: flex; align-items: center; justify-content: center;
    /* On a phone the dialog was taller than the screen and Save sat below
       the fold. The overlay is the visible viewport (dvh follows Safari's
       toolbar, vh is the fallback), clear of the notch and home indicator;
       the dialog fits inside it. */
    height: 100vh; height: 100dvh;
    padding: max(16px, env(safe-area-inset-top, 0px)) max(16px, env(safe-area-inset-right, 0px))
             max(16px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px));
    box-sizing: border-box;
    overscroll-behavior: contain;
  }
  #cv-cookie-modal-overlay.hidden { display: none; }
  #cv-cookie-modal {
    background: var(--cvt-bg-surface);
    border-radius: var(--r-lg, 10px);
    padding: 28px;
    max-width: 480px;
    width: 100%;
    box-shadow: var(--cvt-shadow-e3);
    color: var(--cvt-text-primary);
    font-family: "Inter", ui-sans-serif, system-ui, sans-serif;
    /* Header and footer stay put; .cv-cm-body scrolls between them. */
    display: flex; flex-direction: column;
    max-height: 100%;
    box-sizing: border-box;
    overflow: hidden;
  }
  #cv-cookie-modal:focus { outline: none; }
  #cv-cookie-modal .cv-cm-body {
    flex: 1 1 auto; min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    margin: 0 -4px; padding: 0 4px;
  }
  #cv-cookie-modal h2 {
    margin: 0 0 6px;
    font-size: 17px;
    font-weight: 600;
    color: var(--cvt-text-primary);
  }
  #cv-cookie-modal .cv-cm-subtitle {
    font-size: 13px;
    color: var(--cvt-text-secondary);
    margin: 0 0 20px;
    line-height: 1.5;
  }
  .cv-cm-category {
    border: 1px solid var(--cvt-border-subtle);
    border-radius: var(--r-md, 8px);
    padding: 14px 16px;
    margin-bottom: 10px;
  }
  .cv-cm-cat-header {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
  }
  .cv-cm-cat-title {
    font-size: 14px; font-weight: 600; color: var(--cvt-text-primary);
  }
  .cv-cm-cat-desc {
    font-size: 12.5px; color: var(--cvt-text-secondary); margin-top: 6px; line-height: 1.5;
  }
  /* Toggle switch */
  .cv-toggle { position: relative; display: inline-block; width: 38px; height: 22px; flex-shrink: 0; }
  .cv-toggle input { opacity: 0; width: 0; height: 0; }
  .cv-toggle-slider {
    position: absolute; inset: 0;
    background: var(--cvt-border-control);
    border-radius: 11px;
    cursor: pointer;
    transition: background 0.2s;
  }
  .cv-toggle-slider::before {
    content: '';
    position: absolute;
    width: 16px; height: 16px;
    left: 3px; top: 3px;
    background: white;
    border-radius: 50%;
    transition: transform 0.2s;
  }
  .cv-toggle input:checked + .cv-toggle-slider { background: var(--cvt-action-primary-bg); }
  .cv-toggle input:checked + .cv-toggle-slider::before { transform: translateX(16px); }
  .cv-toggle input:disabled + .cv-toggle-slider { opacity: 0.5; cursor: not-allowed; }
  .cv-cm-footer {
    flex: none;
    display: flex; gap: 8px; margin-top: 16px; padding-top: 12px; justify-content: flex-end;
    border-top: 1px solid var(--cvt-border-subtle);
  }
  /* The page behind an open dialog does not scroll. iOS Safari ignores
     overflow:hidden on body for touch scrolling, so JS also pins the body
     with position:fixed at the current offset and restores it on close. */
  html.cv-cookie-locked { overflow: hidden; overscroll-behavior: none; }
  body.cv-cookie-locked { position: fixed; left: 0; right: 0; width: 100%; overflow: hidden; }
  .cv-cm-footer .cv-cookie-btn { font-size: 13.5px; }
  .cv-cm-footer .cv-cookie-btn-accept {
    background: var(--cvt-action-primary-bg);
    border-color: var(--cvt-action-primary-bg);
    color: white;
  }
  .cv-cm-footer .cv-cookie-btn-reject {
    background: transparent;
    color: var(--cvt-text-primary);
    border-color: var(--cvt-border-control);
  }


  /* Direction A (W57): every page that shows this banner loads _cvt_ui.html,
     so the banner and the preferences dialog use the design tokens on all of
     them, the app and account pages included. Moved here from
     _cvt_marketing.html, where it reached the marketing pages only. */
/* ── Cookie banner and preferences on the system ───────────────────────
   Every page that includes this partial is on the system (W57), so these
   rules apply everywhere the banner shows. /app keeps the banner in its
   column instead of floating (_cvt_app.html).
   A paper card with the page's buttons: Accept is the green primary,
   Reject the outlined secondary, both the same size (rejecting is as easy
   as accepting). Behaviour, copy and ids are unchanged. */
/* W236: a larger floating card, centred at the bottom, on every width. */
body:has(#cv-cookie-banner) #cv-cookie-banner{left:50%;right:auto;bottom:24px;width:min(880px,100vw - 32px);box-sizing:border-box;gap:24px;padding:28px 32px;border:1px solid var(--cvt-border-subtle);border-radius:18px;background:var(--cvt-bg-surface);color:var(--cvt-text-primary);box-shadow:var(--cvt-shadow-e3);font:400 16px/1.5 var(--cvt-font-ui);transform:translateX(-50%);flex-wrap:nowrap;flex-direction:column;align-items:stretch;max-height:calc(100vh - 36px);max-height:calc(100dvh - 36px);overflow-y:auto;overscroll-behavior:contain}
@media (min-width:720px){body:has(#cv-cookie-banner) #cv-cookie-banner{flex-direction:row;align-items:center;gap:32px}}
body:has(#cv-cookie-banner) #cv-cookie-banner .cv-cookie-title{display:block;margin-bottom:6px;font:700 20px/1.25 var(--cvt-font-display);color:var(--cvt-text-primary)}
@media (min-width:720px){body:has(#cv-cookie-banner) #cv-cookie-banner .cv-cookie-title{font-size:22px}}
body:has(#cv-cookie-banner) #cv-cookie-banner p{min-width:0}
body:has(#cv-cookie-banner) #cv-cookie-banner a{color:var(--cvt-text-link);font-weight:600;text-underline-offset:3px}
body:has(#cv-cookie-banner) #cv-cookie-banner a:focus-visible{outline:2px solid var(--cvt-focus-ring);outline-offset:2px}
body:has(#cv-cookie-banner) #cv-cookie-banner .cv-cookie-fine{margin-top:8px;color:var(--cvt-text-secondary);font-size:13.5px;line-height:1.45}
body:has(#cv-cookie-banner) .cv-cookie-actions{display:grid;grid-template-columns:1fr 1fr;gap:12px;width:100%}
@media (min-width:720px){body:has(#cv-cookie-banner) .cv-cookie-actions{width:360px;flex:none}}
body:has(#cv-cookie-banner) .cv-cookie-btn{min-height:52px;padding:0 16px;border:1px solid transparent;border-radius:12px;font:700 16px/1.2 var(--cvt-font-ui);white-space:normal;transition:background-color var(--cvt-motion-duration-fast) var(--cvt-motion-ease-standard)}
body:has(#cv-cookie-banner) .cv-cookie-btn:hover{opacity:1}
body:has(#cv-cookie-banner) .cv-cookie-btn:focus-visible{outline:2px solid var(--cvt-focus-ring);outline-offset:2px}
body:has(#cv-cookie-banner) .cv-cookie-btn-accept{background:var(--cvt-action-primary-bg);border-color:var(--cvt-action-primary-bg);color:var(--cvt-action-primary-fg)}
body:has(#cv-cookie-banner) .cv-cookie-btn-accept:hover{background:var(--cvt-action-primary-bg-hover)}
body:has(#cv-cookie-banner) .cv-cookie-btn-reject{background:transparent;border-color:var(--cvt-border-control);color:var(--cvt-text-primary)}
body:has(#cv-cookie-banner) .cv-cookie-btn-reject:hover{background:var(--cvt-action-secondary-bg-hover)}
body:has(#cv-cookie-banner) .cv-cookie-btn-manage{display:inline;padding:0;border:0;background:transparent;color:var(--cvt-text-link);font:inherit;font-weight:600;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
body:has(#cv-cookie-banner) .cv-cookie-btn-manage:focus-visible{outline:2px solid var(--cvt-focus-ring);outline-offset:2px}
/* Phones (W236): the same card, tighter: 12px from the bottom edge (and the
   home indicator), 22px 20px padding, 20px heading. Reject and Accept stay
   side by side and the same size. The old 180px bound (W57) is replaced
   by scripts/check_release_ui.py BANNER_MAX_PHONE. */
@media (max-width:599px){
body:has(#cv-cookie-banner) #cv-cookie-banner{bottom:calc(12px + env(safe-area-inset-bottom,0px));gap:18px;padding:22px 20px}
}
body:has(#cv-cookie-banner) #cv-cookie-modal-overlay{background:var(--cvt-overlay-scrim)}
body:has(#cv-cookie-banner) #cv-cookie-modal{padding:var(--cvt-space-6);border-radius:var(--cvt-radius-lg);background:var(--cvt-bg-surface);color:var(--cvt-text-primary);box-shadow:var(--cvt-shadow-e3);font-family:var(--cvt-font-ui)}
@media (max-width:599px){body:has(#cv-cookie-banner) #cv-cookie-modal{padding:var(--cvt-space-4)}body:has(#cv-cookie-banner) #cv-cookie-modal .cv-cm-subtitle{margin-bottom:var(--cvt-space-3)}}
body:has(#cv-cookie-banner) #cv-cookie-modal h2{font:700 20px/1.3 var(--cvt-font-ui);color:var(--cvt-text-primary)}
body:has(#cv-cookie-banner) #cv-cookie-modal .cv-cm-subtitle,body:has(#cv-cookie-banner) .cv-cm-cat-desc{color:var(--cvt-text-secondary);font-size:var(--cvt-type-small-size)}
body:has(#cv-cookie-banner) .cv-cm-category{border-color:var(--cvt-border-subtle);border-radius:var(--cvt-radius-md);background:var(--cvt-bg-canvas)}
body:has(#cv-cookie-banner) .cv-cm-cat-title{color:var(--cvt-text-primary)}
body:has(#cv-cookie-banner) .cv-toggle-slider{background:var(--cvt-border-control)}
body:has(#cv-cookie-banner) .cv-toggle-slider::before{background:var(--cvt-bg-surface)}
body:has(#cv-cookie-banner) .cv-toggle input:checked + .cv-toggle-slider{background:var(--cvt-action-primary-bg)}
body:has(#cv-cookie-banner) .cv-toggle input:focus-visible + .cv-toggle-slider{outline:2px solid var(--cvt-focus-ring);outline-offset:2px}
body:has(#cv-cookie-banner) .cv-cm-footer .cv-cookie-btn-accept{background:var(--cvt-action-primary-bg);border-color:var(--cvt-action-primary-bg);color:var(--cvt-action-primary-fg)}
body:has(#cv-cookie-banner) .cv-cm-footer .cv-cookie-btn-reject{background:transparent;border-color:var(--cvt-border-control);color:var(--cvt-text-primary)}
