
  /* 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. */
body:has(#cv-cookie-banner) #cv-cookie-banner{left:var(--cvt-space-2);right:var(--cvt-space-2);bottom:var(--cvt-space-2);gap:var(--cvt-space-4);padding:var(--cvt-space-5);border:1px solid var(--cvt-border-subtle);border-radius:var(--cvt-radius-xl);background:var(--cvt-bg-surface);color:var(--cvt-text-primary);box-shadow:var(--cvt-shadow-e3);font:400 15px/1.5 var(--cvt-font-ui)}
@media (min-width:900px){body:has(#cv-cookie-banner) #cv-cookie-banner{left:50%;right:auto;bottom:var(--cvt-space-4);width:min(var(--cvt-size-container-max),100% - 2*var(--cvt-gutter));padding:var(--cvt-space-5) var(--cvt-space-6);transform:translateX(-50%)}}
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:var(--cvt-space-1);color:var(--cvt-text-secondary);font-size:var(--cvt-type-small-size)}
body:has(#cv-cookie-banner) .cv-cookie-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--cvt-space-2);width:100%}
@media (min-width:900px){body:has(#cv-cookie-banner) .cv-cookie-actions{display:flex;align-items:center;width:auto}}
body:has(#cv-cookie-banner) .cv-cookie-btn{min-height:var(--cvt-size-touch-min);padding:0 var(--cvt-space-5);border:1px solid transparent;border-radius:var(--cvt-radius-md);font:var(--cvt-type-button-weight) var(--cvt-type-button-size)/1.2 var(--cvt-font-ui);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 (W57): the banner was 284 to 346px tall at 390, a third of the
   screen. Below 600 it is a bottom sheet, as the system's dialogs are
   (design-system.md): full width, top corners rounded, clear of the home
   indicator. Small type, tighter padding and the preferences control in
   the text keep it at 180px or less at 390 (200 in fr, ru and pt-pt, whose
   legal notices run one line longer); Reject and Accept keep one size, side
   by side. scripts/check_release_ui.py (brand, at 390) holds the bound. */
@media (max-width:599px){
body:has(#cv-cookie-banner) #cv-cookie-banner{left:0;right:0;bottom:0;gap:var(--cvt-space-2);padding:var(--cvt-space-3) var(--cvt-space-3) calc(var(--cvt-space-3) + env(safe-area-inset-bottom,0px));border-width:1px 0 0;border-radius:var(--cvt-radius-xl) var(--cvt-radius-xl) 0 0;font:400 var(--cvt-type-small-size)/1.35 var(--cvt-font-ui)}
body:has(#cv-cookie-banner) #cv-cookie-banner .cv-cookie-fine{margin-top:2px;font-size:12px;line-height:1.3}
body:has(#cv-cookie-banner) #cv-cookie-banner .cv-cookie-btn{padding:0 var(--cvt-space-3)}
}
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)}
