/* ============================================================
   Component_App.css
   Design tokens extracted from Figma
   File: DesignSystem_App (ZaWzffvWrlmcS4mZ5WjpAB), local collections
   fuji_color (lightMode / darkMode) and fuji_spacing. Figma group
   names dropped "Scheme" on 2026-10-25 (textScheme -> text); the CSS
   names never carried it, so no variable was renamed.
   Values are resolved (aliases flattened to final hex).
   ============================================================ */

:root {
  /* ---------- Semantic tokens ---------- */
  /* text */
  --text-on-surface: #171c1f;
  --text-on-surface-variant: #40484d;
  --text-on-surface-dim: #8c8c8c;
  --text-on-surface-placeholder: #a3a3a3;
  --text-on-surface-disabled: #bfbfbf;
  --text-inverse-on-surface: #edf1f5;
  --text-on-primary: #ffffff;
  --text-brand-primary: #0095ff;
  --text-brand-secondary: #4e616d;

  /* surface */
  --surface: #f8f9fb;
  --surface-container-lowest: #fdfdfd;
  --surface-container-low: #f0f4f8;
  --surface-container: #eaeef2;
  --surface-container-high: #e5e9ed;
  --surface-container-highest: #dfe3e7;
  --surface-overlay-base: #1a1a1a99;

  /* primary */
  --primary: #0095ff;
  --primary-container: #c2e8ff;
  --primary-fixed: #ccecff;
  --primary-fixed-dim: #8ecff2;
  --primary-gradient-stop-one: #01b3e9;
  --primary-gradient-stop-two: #0095ff;

  /* secondary */
  --secondary: #4e616d;
  --secondary-container: #d1e6f3;
  --secondary-fixed: #d1e6f3;
  --secondary-fixed-dim: #b5c9d7;

  /* outline */
  --outline-softest: #f3f4f4;
  --outline-softer: #eeeeee;
  --outline-soft: #bfbfbf;
  --outline-base: #a3a3a3;
  --outline-bold: #575757;
  --outline-boldest: #1a1a1a;
  --outline-brand-primary: #0095ff;
  --outline-brand-secondary: #4e616d;

  /* brand */
  --brand: #01b3e9;

  /* status */
  --status-neutral-softest: #f5f5f5;
  --status-neutral-softer: #e8e8e8;
  --status-neutral-soft: #dbdbdb;
  --status-neutral-base: #8c8c8c;
  --status-neutral-bold: #575757;
  --status-neutral-boldest: #292929;
  --status-alert-softest: #fbe1e1;
  --status-alert-softer: #f8cecc;
  --status-alert-soft: #f6bab8;
  --status-alert-base: #e53935;
  --status-alert-bold: #a02825;
  --status-alert-boldest: #451110;
  --status-positive-softest: #edfef2;
  --status-positive-softer: #dafbe3;
  --status-positive-soft: #b7efc5;
  --status-positive-base: #2dc653;
  --status-positive-bold: #208b3a;
  --status-positive-boldest: #1a7431;
  --status-informative-softest: #d9f4fc;
  --status-informative-softer: #c0ecfa;
  --status-informative-soft: #a6e4f7;
  --status-informative-base: #01b3e9;
  --status-informative-bold: #017da3;
  --status-informative-boldest: #003646;
  --status-notice-softest: #fef2de;
  --status-notice-softer: #fce9c8;
  --status-notice-soft: #fce0b2;
  --status-notice: #f5a623;
  --status-notice-bold: #ab7418;
  --status-notice-boldest: #4a320a;
  --status-notice-alt-softest: #fefbdd;
  --status-notice-alt-softer: #fdf9c6;
  --status-notice-alt-soft: #fdf7b0;
  --status-notice-alt-notice: #f5a623;
  --status-notice-alt-bold: #4a4508;
  --status-notice-alt-boldest: #252304;
  --status-premium-soft: #b9976d;

  /* ---------- Base palette ---------- */
  /* grey */
  --base-grey-0: #fdfdfd;
  --base-grey-50: #f5f5f5;
  --base-grey-75: #e8e8e8;
  --base-grey-100: #dbdbdb;
  --base-grey-200: #bfbfbf;
  --base-grey-300: #a3a3a3;
  --base-grey-400: #8c8c8c;
  --base-grey-500: #575757;
  --base-grey-600: #575757;
  --base-grey-700: #3d3d3d;
  --base-grey-800: #292929;
  --base-grey-900: #1a1a1a;
  --base-grey-1000: #171c1f;

  /* blue */
  --base-blue-50: #d9f4fc;
  --base-blue-75: #c0ecfa;
  --base-blue-100: #a6e4f7;
  --base-blue-200: #73d5f3;
  --base-blue-300: #40c6ee;
  --base-blue-400: #01b3e9;
  --base-blue-500: #01a1d2;
  --base-blue-600: #017da3;
  --base-blue-700: #005a74;
  --base-blue-800: #003646;
  --base-blue-900: #00242f;
  --base-blue-1000: #001217;

  /* salmon */
  --base-salmon-50: #fee8ed;
  --base-salmon-75: #fdd6dd;
  --base-salmon-100: #fdcbd6;
  --base-salmon-200: #fcafbf;
  --base-salmon-300: #fb92a8;
  --base-salmon-400: #fe97b0;
  --base-salmon-500: #f9577a;
  --base-salmon-600: #f63b63;
  --base-salmon-700: #f41f4c;
  --base-salmon-800: #ec1d44;
  --base-salmon-900: #e31b3c;
  --base-salmon-1000: #b3162e;

  /* purple */
  --base-purple-50: #f7ebf9;
  --base-purple-75: #f2ddf5;
  --base-purple-100: #edd0f1;
  --base-purple-200: #e3b5e9;
  --base-purple-300: #d99ae1;
  --base-purple-400: #cc78d7;
  --base-purple-500: #b86cc2;
  --base-purple-600: #8f5496;
  --base-purple-700: #663c6c;
  --base-purple-800: #3d2440;
  --base-purple-900: #29182b;
  --base-purple-1000: #140c16;

  /* green */
  --base-green-50: #edfef2;
  --base-green-75: #dafbe3;
  --base-green-100: #b7efc5;
  --base-green-200: #92e6a7;
  --base-green-300: #6ede8a;
  --base-green-400: #4ad66d;
  --base-green-500: #2dc653;
  --base-green-600: #25a244;
  --base-green-700: #208b3a;
  --base-green-800: #1a7431;
  --base-green-900: #155d27;
  --base-green-1000: #10451d;

  /* orange */
  --base-orange-50: #fef2de;
  --base-orange-75: #fce9c8;
  --base-orange-100: #fce0b2;
  --base-orange-200: #face86;
  --base-orange-300: #f8bc5a;
  --base-orange-400: #f5a623;
  --base-orange-500: #dc9520;
  --base-orange-600: #ab7418;
  --base-orange-700: #7a5312;
  --base-orange-800: #4a320a;
  --base-orange-900: #312107;
  --base-orange-1000: #181104;

  /* yellow */
  --base-yellow-50: #fefbdd;
  --base-yellow-75: #fdf9c6;
  --base-yellow-100: #fdf7b0;
  --base-yellow-200: #dfd019;
  --base-yellow-300: #aea214;
  --base-yellow-400: #7c740e;
  --base-yellow-500: #635c0b;
  --base-yellow-600: #4a4508;
  --base-yellow-700: #322e06;
  --base-yellow-800: #252304;
  --base-yellow-900: #191703;
  --base-yellow-1000: #0c0c01;

  /* red */
  --base-red-50: #fbe1e1;
  --base-red-75: #f8cecc;
  --base-red-100: #f6bab8;
  --base-red-200: #f19290;
  --base-red-300: #ec6a68;
  --base-red-400: #e53935;
  --base-red-500: #ce3330;
  --base-red-600: #a02825;
  --base-red-700: #721c1a;
  --base-red-800: #451110;
  --base-red-900: #2e0b0b;
  --base-red-1000: #170605;

  /* gold */
  --base-gold-50: #f4efe9;
  --base-gold-75: #eee5da;
  --base-gold-100: #e3d5c5;
  --base-gold-200: #d8c6af;
  --base-gold-300: #b9976d;
  --base-gold-400: #9d805d;
  --base-gold-500: #826a4c;
  --base-gold-800: #66533c;
  --base-gold-900: #4a3c2c;
  --base-gold-1000: #2e261b;

  /* white */
  --base-white-0: #ffffff;
  --base-white-50: #f5f5f5;

  /* singpass */
  --base-singpass-logo-singpass: #000000;
}

/* Dark mode: follows the OS setting */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* text */
    --text-on-surface: #dfe4e7;
    --text-on-surface-variant: #b1b9be;
    --text-on-surface-dim: #737373;
    --text-on-surface-placeholder: #757d80;
    --text-on-surface-disabled: #404040;
    --text-inverse-on-surface: #090d10;
    --text-on-primary: #ffffff;
    --text-brand-primary: #2fcefe;
    --text-brand-secondary: #b5c9d7;

    /* surface */
    --surface: #09080b;
    --surface-container-lowest: #14141b;
    --surface-container-low: #171c1f;
    --surface-container: #1b2023;
    --surface-container-high: #262b2e;
    --surface-container-highest: #313539;
    --surface-overlay-base: #48484899;

    /* primary */
    --primary: #34c2ed;
    --primary-container: #00263d;
    --primary-fixed: #00263d;
    --primary-fixed-dim: #0d4f72;
    --primary-gradient-stop-one: #01b3e9;
    --primary-gradient-stop-two: #0095ff;

    /* secondary */
    --secondary: #b5c9d7;
    --secondary-container: #364954;
    --secondary-fixed: #d1e6f3;
    --secondary-fixed-dim: #b5c9d7;

    /* outline */
    --outline-softest: #242424;
    --outline-softer: #2c2c2c5c;
    --outline-soft: #404040;
    --outline-base: #5c5c5c;
    --outline-bold: #a8a8a8;
    --outline-boldest: #e6e6e6;
    --outline-brand-primary: #8ecff2;
    --outline-brand-secondary: #b5c9d7;

    /* brand */
    --brand: #0ab6ea;

    /* status */
    --status-neutral-softest: #151515;
    --status-neutral-softer: #2a2a2a;
    --status-neutral-soft: #737373;
    --status-neutral-base: #242424;
    --status-neutral-bold: #171717;
    --status-neutral-boldest: #f5f5f5;
    --status-alert-softest: #3a0c0b;
    --status-alert-softer: #751a18;
    --status-alert-soft: #b6302d;
    --status-alert-base: #ef7f79;
    --status-alert-bold: #f5a6a2;
    --status-alert-boldest: #f9d3d2;
    --status-positive-softest: #122112;
    --status-positive-softer: #254125;
    --status-positive-soft: #3e6c3d;
    --status-positive-base: #7bd97a;
    --status-positive-bold: #88dd87;
    --status-positive-boldest: #95e195;
    --status-informative-softest: #002834;
    --status-informative-softer: #00475c;
    --status-informative-soft: #016685;
    --status-informative-base: #0ab6ea;
    --status-informative-bold: #06b4e9;
    --status-informative-boldest: #34c2ed;
    --status-notice-softest: #312107;
    --status-notice-softer: #62420e;
    --status-notice-soft: #ab7418;
    --status-notice: #f7b84f;
    --status-notice-bold: #fbd192;
    --status-notice-boldest: #ffeed9;
    --status-notice-alt-softest: #513903;
    --status-notice-alt-softer: #8c6500;
    --status-notice-alt-soft: #d89f00;
    --status-notice-alt-notice: #f9e139;
    --status-notice-alt-bold: #fdeb8b;
    --status-notice-alt-boldest: #fff9db;
    --status-premium-soft: #b9976d;

    /* grey */
    --base-grey-0: #030303;
    --base-grey-50: #0a0a0a;
    --base-grey-75: #171717;
    --base-grey-100: #242424;
    --base-grey-200: #404040;
    --base-grey-300: #5c5c5c;
    --base-grey-400: #737373;
    --base-grey-500: #383838;
    --base-grey-600: #2a2a2a;
    --base-grey-700: #1c1c1c;
    --base-grey-800: #151515;
    --base-grey-900: #0e0e0e;
    --base-grey-1000: #171c1f;

    /* blue */
    --base-blue-50: #34c2ed;
    --base-blue-75: #06b4e9;
    --base-blue-100: #0ab6ea;
    --base-blue-200: #0185ad;
    --base-blue-300: #017599;
    --base-blue-400: #016685;
    --base-blue-500: #005670;
    --base-blue-600: #00475c;
    --base-blue-700: #003748;
    --base-blue-800: #002834;
    --base-blue-900: #001820;
    --base-blue-1000: #00090c;

    /* salmon */
    --base-salmon-50: #fe97b0;
    --base-salmon-75: #fea0b7;
    --base-salmon-100: #fea8bd;
    --base-salmon-200: #ea748d;
    --base-salmon-300: #e36881;
    --base-salmon-400: #dc5c75;
    --base-salmon-500: #d55169;
    --base-salmon-600: #ce455d;
    --base-salmon-700: #c73951;
    --base-salmon-800: #c12d46;
    --base-salmon-900: #ba223a;
    --base-salmon-1000: #b3162e;

    /* purple */
    --base-purple-50: #cc78d7;
    --base-purple-75: #cd7ad8;
    --base-purple-100: #ce7dd8;
    --base-purple-200: #97599f;
    --base-purple-300: #854f8d;
    --base-purple-400: #74447a;
    --base-purple-500: #623a68;
    --base-purple-600: #512f55;
    --base-purple-700: #3f2543;
    --base-purple-800: #2d1b30;
    --base-purple-900: #1c101e;
    --base-purple-1000: #0a060b;

    /* green */
    --base-green-50: #95e195;
    --base-green-75: #88dd87;
    --base-green-100: #7bd97a;
    --base-green-200: #6fc36e;
    --base-green-300: #569855;
    --base-green-400: #3e6c3d;
    --base-green-500: #315731;
    --base-green-600: #254125;
    --base-green-700: #192b18;
    --base-green-800: #122112;
    --base-green-900: #0c160c;
    --base-green-1000: #060b06;

    /* orange */
    --base-orange-50: #ffeed9;
    --base-orange-75: #fbd192;
    --base-orange-100: #f7b84f;
    --base-orange-200: #f5a623;
    --base-orange-300: #dc9520;
    --base-orange-400: #ab7418;
    --base-orange-500: #7a5312;
    --base-orange-600: #62420e;
    --base-orange-700: #4a320a;
    --base-orange-800: #312107;
    --base-orange-900: #181104;
    --base-orange-1000: #0c0802;

    /* yellow */
    --base-yellow-50: #fff9db;
    --base-yellow-75: #fdeb8b;
    --base-yellow-100: #f9e139;
    --base-yellow-200: #ffc905;
    --base-yellow-300: #ffb800;
    --base-yellow-400: #d89f00;
    --base-yellow-500: #b07f00;
    --base-yellow-600: #8c6500;
    --base-yellow-700: #6e4f02;
    --base-yellow-800: #513903;
    --base-yellow-900: #3a2902;
    --base-yellow-1000: #0c0c01;

    /* red */
    --base-red-50: #f9d3d2;
    --base-red-75: #f5a6a2;
    --base-red-100: #ef7f79;
    --base-red-200: #e45d57;
    --base-red-300: #d33f3a;
    --base-red-400: #b6302d;
    --base-red-500: #942420;
    --base-red-600: #751a18;
    --base-red-700: #541210;
    --base-red-800: #3a0c0b;
    --base-red-900: #230808;
    --base-red-1000: #0b0303;

    /* gold */
    --base-gold-50: #1c140c;
    --base-gold-75: #241a0e;
    --base-gold-100: #302013;
    --base-gold-200: #46301c;
    --base-gold-300: #614326;
    --base-gold-400: #7b5930;
    --base-gold-500: #9c7744;
    --base-gold-800: #c79e6a;
    --base-gold-900: #e5c391;
    --base-gold-1000: #fae8c2;

    /* white */
    --base-white-0: #ffffff;
    --base-white-50: #f5f5f5;

    /* singpass */
    --base-singpass-logo-singpass: #f4333d;
  }
}

/* Dark mode: explicit opt-in */
[data-theme="dark"] {
  /* text */
  --text-on-surface: #dfe4e7;
  --text-on-surface-variant: #b1b9be;
  --text-on-surface-dim: #737373;
  --text-on-surface-placeholder: #757d80;
  --text-on-surface-disabled: #404040;
  --text-inverse-on-surface: #090d10;
  --text-on-primary: #ffffff;
  --text-brand-primary: #2fcefe;
  --text-brand-secondary: #b5c9d7;

  /* surface */
  --surface: #09080b;
  --surface-container-lowest: #14141b;
  --surface-container-low: #171c1f;
  --surface-container: #1b2023;
  --surface-container-high: #262b2e;
  --surface-container-highest: #313539;
  --surface-overlay-base: #48484899;

  /* primary */
  --primary: #34c2ed;
  --primary-container: #00263d;
  --primary-fixed: #00263d;
  --primary-fixed-dim: #0d4f72;
  --primary-gradient-stop-one: #01b3e9;
  --primary-gradient-stop-two: #0095ff;

  /* secondary */
  --secondary: #b5c9d7;
  --secondary-container: #364954;
  --secondary-fixed: #d1e6f3;
  --secondary-fixed-dim: #b5c9d7;

  /* outline */
  --outline-softest: #242424;
  --outline-softer: #2c2c2c5c;
  --outline-soft: #404040;
  --outline-base: #5c5c5c;
  --outline-bold: #a8a8a8;
  --outline-boldest: #e6e6e6;
  --outline-brand-primary: #8ecff2;
  --outline-brand-secondary: #b5c9d7;

  /* brand */
  --brand: #0ab6ea;

  /* status */
  --status-neutral-softest: #151515;
  --status-neutral-softer: #2a2a2a;
  --status-neutral-soft: #737373;
  --status-neutral-base: #242424;
  --status-neutral-bold: #171717;
  --status-neutral-boldest: #f5f5f5;
  --status-alert-softest: #3a0c0b;
  --status-alert-softer: #751a18;
  --status-alert-soft: #b6302d;
  --status-alert-base: #ef7f79;
  --status-alert-bold: #f5a6a2;
  --status-alert-boldest: #f9d3d2;
  --status-positive-softest: #122112;
  --status-positive-softer: #254125;
  --status-positive-soft: #3e6c3d;
  --status-positive-base: #7bd97a;
  --status-positive-bold: #88dd87;
  --status-positive-boldest: #95e195;
  --status-informative-softest: #002834;
  --status-informative-softer: #00475c;
  --status-informative-soft: #016685;
  --status-informative-base: #0ab6ea;
  --status-informative-bold: #06b4e9;
  --status-informative-boldest: #34c2ed;
  --status-notice-softest: #312107;
  --status-notice-softer: #62420e;
  --status-notice-soft: #ab7418;
  --status-notice: #f7b84f;
  --status-notice-bold: #fbd192;
  --status-notice-boldest: #ffeed9;
  --status-notice-alt-softest: #513903;
  --status-notice-alt-softer: #8c6500;
  --status-notice-alt-soft: #d89f00;
  --status-notice-alt-notice: #f9e139;
  --status-notice-alt-bold: #fdeb8b;
  --status-notice-alt-boldest: #fff9db;
  --status-premium-soft: #b9976d;

  /* grey */
  --base-grey-0: #030303;
  --base-grey-50: #0a0a0a;
  --base-grey-75: #171717;
  --base-grey-100: #242424;
  --base-grey-200: #404040;
  --base-grey-300: #5c5c5c;
  --base-grey-400: #737373;
  --base-grey-500: #383838;
  --base-grey-600: #2a2a2a;
  --base-grey-700: #1c1c1c;
  --base-grey-800: #151515;
  --base-grey-900: #0e0e0e;
  --base-grey-1000: #171c1f;

  /* blue */
  --base-blue-50: #34c2ed;
  --base-blue-75: #06b4e9;
  --base-blue-100: #0ab6ea;
  --base-blue-200: #0185ad;
  --base-blue-300: #017599;
  --base-blue-400: #016685;
  --base-blue-500: #005670;
  --base-blue-600: #00475c;
  --base-blue-700: #003748;
  --base-blue-800: #002834;
  --base-blue-900: #001820;
  --base-blue-1000: #00090c;

  /* salmon */
  --base-salmon-50: #fe97b0;
  --base-salmon-75: #fea0b7;
  --base-salmon-100: #fea8bd;
  --base-salmon-200: #ea748d;
  --base-salmon-300: #e36881;
  --base-salmon-400: #dc5c75;
  --base-salmon-500: #d55169;
  --base-salmon-600: #ce455d;
  --base-salmon-700: #c73951;
  --base-salmon-800: #c12d46;
  --base-salmon-900: #ba223a;
  --base-salmon-1000: #b3162e;

  /* purple */
  --base-purple-50: #cc78d7;
  --base-purple-75: #cd7ad8;
  --base-purple-100: #ce7dd8;
  --base-purple-200: #97599f;
  --base-purple-300: #854f8d;
  --base-purple-400: #74447a;
  --base-purple-500: #623a68;
  --base-purple-600: #512f55;
  --base-purple-700: #3f2543;
  --base-purple-800: #2d1b30;
  --base-purple-900: #1c101e;
  --base-purple-1000: #0a060b;

  /* green */
  --base-green-50: #95e195;
  --base-green-75: #88dd87;
  --base-green-100: #7bd97a;
  --base-green-200: #6fc36e;
  --base-green-300: #569855;
  --base-green-400: #3e6c3d;
  --base-green-500: #315731;
  --base-green-600: #254125;
  --base-green-700: #192b18;
  --base-green-800: #122112;
  --base-green-900: #0c160c;
  --base-green-1000: #060b06;

  /* orange */
  --base-orange-50: #ffeed9;
  --base-orange-75: #fbd192;
  --base-orange-100: #f7b84f;
  --base-orange-200: #f5a623;
  --base-orange-300: #dc9520;
  --base-orange-400: #ab7418;
  --base-orange-500: #7a5312;
  --base-orange-600: #62420e;
  --base-orange-700: #4a320a;
  --base-orange-800: #312107;
  --base-orange-900: #181104;
  --base-orange-1000: #0c0802;

  /* yellow */
  --base-yellow-50: #fff9db;
  --base-yellow-75: #fdeb8b;
  --base-yellow-100: #f9e139;
  --base-yellow-200: #ffc905;
  --base-yellow-300: #ffb800;
  --base-yellow-400: #d89f00;
  --base-yellow-500: #b07f00;
  --base-yellow-600: #8c6500;
  --base-yellow-700: #6e4f02;
  --base-yellow-800: #513903;
  --base-yellow-900: #3a2902;
  --base-yellow-1000: #0c0c01;

  /* red */
  --base-red-50: #f9d3d2;
  --base-red-75: #f5a6a2;
  --base-red-100: #ef7f79;
  --base-red-200: #e45d57;
  --base-red-300: #d33f3a;
  --base-red-400: #b6302d;
  --base-red-500: #942420;
  --base-red-600: #751a18;
  --base-red-700: #541210;
  --base-red-800: #3a0c0b;
  --base-red-900: #230808;
  --base-red-1000: #0b0303;

  /* gold */
  --base-gold-50: #1c140c;
  --base-gold-75: #241a0e;
  --base-gold-100: #302013;
  --base-gold-200: #46301c;
  --base-gold-300: #614326;
  --base-gold-400: #7b5930;
  --base-gold-500: #9c7744;
  --base-gold-800: #c79e6a;
  --base-gold-900: #e5c391;
  --base-gold-1000: #fae8c2;

  /* white */
  --base-white-0: #ffffff;
  --base-white-50: #f5f5f5;

  /* singpass */
  --base-singpass-logo-singpass: #f4333d;
}


/* ============================================================
   PRIMITIVE TOKENS — spacing
   Source: Figma "[app] fuji_token [migrated]" (WjvozyHkmLhtSfVxTC2ms7),
   variables panel, collection space_* (single mode). Complete.
   ============================================================ */

:root {
  /* The ramp is NOT uniform. Singles to 6, then even steps to 36,
     plus 35 and 37. There is no space_7, _9, _11, _13, _15, _17,
     _19, _21, _23, _25, _27, _29 or _31. Do not fill the gaps:
     a missing step means the scale does not offer that value. */
  --space-0: 0px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-14: 56px;
  --space-16: 64px;
  --space-18: 72px;
  --space-20: 80px;
  --space-22: 88px;
  --space-24: 96px;
  --space-26: 104px;
  --space-28: 112px;
  --space-30: 120px;
  --space-32: 128px;
  --space-34: 136px;
  --space-35: 140px;
  --space-36: 144px;
  --space-37: 148px;

  /* Named spacing */
  --space-container-width: 343px;
  --space-rounded-corner: 8px;
}

/* ============================================================
   TEXT STYLES
   Source: Figma "DesignSystem_App" page 15276:48919 (Typography).
   Complete: 33 styles. Every one is Inter, letterSpacing 0.
   Weights: regular 400, medium 500, bolder 600 (Semi Bold).
   ============================================================ */

:root {
  --font-family-base: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, Helvetica, Arial, sans-serif;

  /* heading — 5 sizes x 3 weights */
  --type-h1-regular: 400 40px/48px var(--font-family-base);
  --type-h1-medium:  500 40px/48px var(--font-family-base);
  --type-h1-bolder:  600 40px/48px var(--font-family-base);
  --type-h2-regular: 400 32px/40px var(--font-family-base);
  --type-h2-medium:  500 32px/40px var(--font-family-base);
  --type-h2-bolder:  600 32px/40px var(--font-family-base);
  --type-h3-regular: 400 24px/32px var(--font-family-base);
  --type-h3-medium:  500 24px/32px var(--font-family-base);
  --type-h3-bolder:  600 24px/32px var(--font-family-base);
  --type-h4-regular: 400 20px/28px var(--font-family-base);
  --type-h4-medium:  500 20px/28px var(--font-family-base);
  --type-h4-bolder:  600 20px/28px var(--font-family-base);
  --type-h5-regular: 400 18px/26px var(--font-family-base);
  --type-h5-medium:  500 18px/26px var(--font-family-base);
  --type-h5-bolder:  600 18px/26px var(--font-family-base);

  /* body — 3 sizes x 3 weights */
  --type-body-01-regular: 400 16px/24px var(--font-family-base);
  --type-body-01-medium:  500 16px/24px var(--font-family-base);
  --type-body-01-bolder:  600 16px/24px var(--font-family-base);
  --type-body-02-regular: 400 14px/20px var(--font-family-base);
  --type-body-02-medium:  500 14px/20px var(--font-family-base);
  --type-body-02-bolder:  600 14px/20px var(--font-family-base);
  --type-body-03-regular: 400 12px/16px var(--font-family-base);
  --type-body-03-medium:  500 12px/16px var(--font-family-base);
  --type-body-03-bolder:  600 12px/16px var(--font-family-base);

  /* metadata — not a full grid, see the note below */
  --type-metadata-01-regular: 400 12px/16px var(--font-family-base);
  --type-metadata-02-regular: 400 11px/12px var(--font-family-base);
  --type-metadata-02-bolder:  600 11px/12px var(--font-family-base);
  --type-metadata-03-regular: 400 10px/12px var(--font-family-base);
  --type-metadata-03-bolder:  600 10px/12px var(--font-family-base);
}

/* The metadata ramp is incomplete in Figma and the gaps are NOT extraction
   holes: metadata01 has only regular, metadata02 has only bolder, metadata03
   has regular and bolder. There is no metadata medium at any size.
   metadata01_regular is also byte-identical to body03_regular. */

/* Text style utilities */
.type-h1-regular { font: var(--type-h1-regular); letter-spacing: 0; }
.type-h1-medium  { font: var(--type-h1-medium);  letter-spacing: 0; }
.type-h1-bolder  { font: var(--type-h1-bolder);  letter-spacing: 0; }
.type-h2-regular { font: var(--type-h2-regular); letter-spacing: 0; }
.type-h2-medium  { font: var(--type-h2-medium);  letter-spacing: 0; }
.type-h2-bolder  { font: var(--type-h2-bolder);  letter-spacing: 0; }
.type-h3-regular { font: var(--type-h3-regular); letter-spacing: 0; }
.type-h3-medium  { font: var(--type-h3-medium);  letter-spacing: 0; }
.type-h3-bolder  { font: var(--type-h3-bolder);  letter-spacing: 0; }
.type-h4-regular { font: var(--type-h4-regular); letter-spacing: 0; }
.type-h4-medium  { font: var(--type-h4-medium);  letter-spacing: 0; }
.type-h4-bolder  { font: var(--type-h4-bolder);  letter-spacing: 0; }
.type-h5-regular { font: var(--type-h5-regular); letter-spacing: 0; }
.type-h5-medium  { font: var(--type-h5-medium);  letter-spacing: 0; }
.type-h5-bolder  { font: var(--type-h5-bolder);  letter-spacing: 0; }

.type-body-01-regular { font: var(--type-body-01-regular); letter-spacing: 0; }
.type-body-01-medium  { font: var(--type-body-01-medium);  letter-spacing: 0; }
.type-body-01-bolder  { font: var(--type-body-01-bolder);  letter-spacing: 0; }
.type-body-02-regular { font: var(--type-body-02-regular); letter-spacing: 0; }
.type-body-02-medium  { font: var(--type-body-02-medium);  letter-spacing: 0; }
.type-body-02-bolder  { font: var(--type-body-02-bolder);  letter-spacing: 0; }
.type-body-03-regular { font: var(--type-body-03-regular); letter-spacing: 0; }
.type-body-03-medium  { font: var(--type-body-03-medium);  letter-spacing: 0; }
.type-body-03-bolder  { font: var(--type-body-03-bolder);  letter-spacing: 0; }

.type-metadata-01-regular { font: var(--type-metadata-01-regular); letter-spacing: 0; }
.type-metadata-02-regular { font: var(--type-metadata-02-regular); letter-spacing: 0; }
.type-metadata-02-bolder  { font: var(--type-metadata-02-bolder);  letter-spacing: 0; }
.type-metadata-03-regular { font: var(--type-metadata-03-regular); letter-spacing: 0; }
.type-metadata-03-bolder  { font: var(--type-metadata-03-bolder);  letter-spacing: 0; }

/* ============================================================
   EFFECTS
   Source: Figma "DesignSystem_App" page 15277:16544 (Shadow). Complete.
   ============================================================ */

:root {
  /* Figma binds shadow_level_2's colour to illustration/grey/100. The
     illustration ramp is not extracted, so the light value is inlined here
     under its own name. Its dark-mode value has not been read, which is why
     it is not aliased to --base-grey-100: those two agree in light and would
     almost certainly disagree in dark. */
  --illustration-grey-100: #dbdbdb;

  --shadow-level-1: 0 6px 12px 0 #1c1c1c1a;
  --shadow-level-2: 0 12px 24px 0 var(--illustration-grey-100);
  --shadow-reversed: 0 -2px 12px 0 #1c1c1c1a;
  --shadow-reversed-2: inset 0 0 0 1px #0009321f,
    inset 0 1.5px 2px 0 var(--status-neutral-softer);
  --halo-focus: 0 0 6px 0 #01b3e980;
  --halo-focus-error: 0 0 6px 0 #e5393540;
}

/* ============================================================
   COMPONENT — button
   Figma: component set "button" (1697:5256)
   Variants: size (large | small) x type (primary | secondary |
   alert | secondary_alert) x state (default | pressed | disabled)
   ============================================================ */

.btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin: 0;
  border: 0;
  border-radius: var(--space-rounded-corner);
  background-color: transparent;
  background-image: none;
  font-family: var(--font-family-base);
  text-align: center;
  text-decoration: none;
  word-break: break-word;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

/* ---------- Size ----------
   Heights are exact: line-height + padding, nothing else. Figma strokes
   are inside-aligned, so the bordered types use an inset box-shadow
   rather than a border, which would add 2 to every height. */

/* ---------- Size ---------- */

/* large — 48 high: 12 top/bottom + 24 line-height */
.btn--lg {
  padding: var(--space-3) var(--space-6);
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
}

/* small — 28 high: 4 top/bottom + 20 line-height.
   Horizontal 16 is a raw value in Figma, not bound to space_4. */
.btn--sm {
  padding: var(--space-1) var(--space-4);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
}

/* Large buttons sit full-width in the mobile frame (327 of 375). */
.btn--block { width: 100%; }

/* ---------- Type: primary ---------- */

.btn--primary {
  background-image: linear-gradient(
    90deg,
    var(--primary-gradient-stop-one),
    var(--primary-gradient-stop-two)
  );
  color: var(--base-white-0);
}

.btn--primary:active,
.btn--primary.is-pressed {
  background-image: none;
  background-color: var(--status-neutral-base);
  color: var(--base-white-0);
}

/* ---------- Type: secondary ---------- */

.btn--secondary {
  box-shadow: inset 0 0 0 1px var(--outline-brand-primary);
  color: var(--text-brand-primary);
}

.btn--secondary:active,
.btn--secondary.is-pressed {
  box-shadow: inset 0 0 0 1px var(--outline-brand-secondary);
  color: var(--text-brand-secondary);
}

/* ---------- Type: alert ---------- */

.btn--alert {
  background-color: var(--status-alert-base);
  color: var(--base-white-0);
}

.btn--alert:active,
.btn--alert.is-pressed {
  background-color: var(--status-alert-boldest);
  color: var(--base-white-0);
}

/* ---------- Type: secondary_alert ---------- */

.btn--secondary-alert {
  box-shadow: inset 0 0 0 1px var(--status-alert-base);
  color: var(--status-alert-base);
}

.btn--secondary-alert:active,
.btn--secondary-alert.is-pressed {
  box-shadow: inset 0 0 0 1px var(--status-alert-boldest);
  color: var(--status-alert-boldest);
}

/* ---------- State: disabled ----------
   Identical across all four types: the fill, the border and the
   label all reset. Keep last so it wins over the type rules. */

.btn:disabled,
.btn.is-disabled {
  background-image: none;
  background-color: var(--status-neutral-softer);
  box-shadow: none;
  color: var(--text-on-surface-disabled);
  cursor: not-allowed;
}

/* An inset shadow is dropped in high-contrast mode, so restore a real
   border there. It changes the box height by 2, which only matters in a
   mode that is already overriding the design. */
@media (forced-colors: active) {
  .btn--secondary,
  .btn--secondary-alert {
    border: 1px solid currentColor;
  }
}

/* ---------- Content: loading ----------
   baseElement_content_large content=loading. The label is replaced
   by a spinner; the button keeps its type styling. */

.btn--loading { pointer-events: none; }

.btn__spinner {
  display: block;
  box-sizing: border-box;
  width: var(--space-6);
  height: var(--space-6);
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.8s linear infinite;
}

.btn--sm .btn__spinner {
  width: var(--space-5);
  height: var(--space-5);
}

@keyframes btn-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .btn__spinner { animation-duration: 2.4s; }
}


/* ============================================================
   COMPONENT — divider
   Figma: component set "divider" (52256:90080), page 15277:16546.
   Described in Figma as "Originally called 'Separator'".
   Variants: orientation (horizontal | vertical) x type
   (default | highlight | Inset)
   ============================================================ */

.divider {
  flex-shrink: 0;
  margin: 0;
  border: 0;
  background-color: var(--outline-softest);
}

.divider--horizontal {
  width: 100%;
  height: 1px;
}

.divider--vertical {
  align-self: stretch;
  width: 1px;
  height: 100%;
}

/* highlight — horizontal only in Figma */
.divider--highlight {
  background-color: var(--outline-brand-secondary);
}

/* Type=Inset is NOT implemented, and that is not an extraction hole.
   Both inset variants — "Horizontal - Emphasised, Type=Inset"
   (52256:90091) and "Vertical, Type=Inset" (52256:90081) — carry no
   fill and no stroke in Figma. They render nothing. Two of the five
   published variants are invisible. Recorded as a library defect;
   build them once the component owner gives them a colour.
   Note also that the variant names are inconsistently cased:
   "horizontal" and "vertical" against "Vertical" and
   "Horizontal - Emphasised", and "default"/"highlight" against
   "Inset". */


/* ============================================================
   COMPONENT — overlay
   Figma: component "overlay" (9173:22626), page 15376:1010.
   A single component, no variants. 375x812 in Figma, which is a
   full mobile screen, so the web equivalent is a fixed full-bleed
   layer rather than a fixed 375x812 box.
   ============================================================ */

.overlay {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background-color: var(--surface-overlay-base);
  cursor: pointer;
}

/* For demos and for scrims scoped to a positioned ancestor. */
.overlay--contained { position: absolute; }


/* ============================================================
   COMPONENT — tag
   Figma: component set "tag" (47235:30124), page 15277:16600.
   Variants: size (small | medium | large) x colour (white | grey |
   green | blue | red | yellow | orange). 21 published variants.
   Also carries leadingIcon and trailingIcon booleans.

   OFF-SCALE VALUES. This component uses four measurements that do
   not exist in the space_* ramp: gap 2, gap 6, padding 10, and
   radius 6. They are inlined below and each one is marked. They
   are NOT extraction holes and NOT invented tokens — they are raw
   values in Figma. Recorded as a library defect.
   ============================================================ */

.tag {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background-color: transparent;
  /* Inside stroke, see the note on the button's size rules. Figma tag
     heights are 20 / 24 / 32 including the stroke; a CSS border would
     make them 22 / 26 / 34. */
  box-shadow: inset 0 0 0 1px var(--tag-stroke, transparent);
  white-space: nowrap;
}

/* ---------- Size ---------- */

.tag--sm {
  gap: 2px;                       /* off-scale */
  padding: var(--space-1) var(--space-1);
  border-radius: 6px;             /* off-scale */
  font: var(--type-metadata-03-regular);
  letter-spacing: 0;
}

.tag--md {
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: 6px;             /* off-scale */
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
}

.tag--lg {
  gap: 6px;                       /* off-scale */
  padding: 6px 10px;              /* off-scale, both */
  border-radius: var(--space-rounded-corner);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
}

/* Icon boxes. Small and medium use one size for both ends; large
   uses 16 leading and 12 trailing, which is deliberate in Figma.
   Put an `.icon icon-<name>` span inside: it masks to currentColor,
   so the glyph takes the tag's label colour automatically. */
.tag__icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.tag--sm .tag__icon { width: 10px; height: 10px; }   /* off-scale */
.tag--md .tag__icon { width: var(--space-3); height: var(--space-3); }
.tag--lg .tag__icon--leading { width: var(--space-4); height: var(--space-4); }
.tag--lg .tag__icon--trailing { width: var(--space-3); height: var(--space-3); }

/* ---------- Colour ---------- */

.tag--white {
  background-color: var(--surface-container-lowest);
  --tag-stroke: var(--outline-soft);
  color: var(--text-on-surface-variant);
}

.tag--grey {
  background-color: var(--status-neutral-softest);
  --tag-stroke: var(--outline-soft);
  color: var(--text-on-surface-variant);
}

.tag--green {
  background-color: var(--status-positive-softest);
  --tag-stroke: var(--status-positive-soft);
  color: var(--status-positive-bold);
}

.tag--blue {
  background-color: var(--status-informative-softest);
  --tag-stroke: var(--status-informative-soft);
  color: var(--status-informative-bold);
}

.tag--red {
  background-color: var(--status-alert-softest);
  --tag-stroke: var(--status-alert-soft);
  color: var(--status-alert-bold);
}

.tag--yellow {
  background-color: var(--status-notice-alt-softest);
  --tag-stroke: var(--status-notice-alt-soft);
  color: var(--status-notice-alt-bold);
}

/* Orange takes its border from `softer`, where the other five
   coloured tags take `soft`. Reproduced as drawn; flagged as a
   likely inconsistency rather than corrected. */
.tag--orange {
  background-color: var(--status-notice-softest);
  --tag-stroke: var(--status-notice-softer);
  color: var(--status-notice-bold);
}


/* ============================================================
   COMPONENT — checkbox
   Figma: component set "checkbox" (48166:37142), page 15277:16559.
   Variants: state (enabled | pressed | disabled) x selected
   (on | off | Indeterminate) x size (16*16 | 24*24). 18 variants.

   NAMING TRAP. The size variant is named after the inner glyph,
   not the control. "16*16" draws a 20x20 box, "24*24" draws a
   24x24 box. Both sit in a 40x40 hit area. The class names below
   are --sm and --lg to avoid repeating the confusion.

   OFF-SCALE. Radius 6 is not on the space_* ramp, same as tag.
   Everything else lands on a token: 40 = space_10, 24 = space_6,
   20 = space_5, 16 = space_4, inner radius 4 = space_1.
   ============================================================ */

.checkbox {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-10);
  height: var(--space-10);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.checkbox__box {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;                 /* off-scale */
  /* Unchecked is a 2px ring: Figma draws a filled box with a
     smaller inset square on top. An inset shadow reproduces it
     exactly, including the inner radius of 4. */
  background-color: var(--surface-container-lowest);
  box-shadow: inset 0 0 0 2px var(--checkbox-ring, var(--outline-soft));
  color: var(--text-on-primary);
}

.checkbox--sm .checkbox__box { width: var(--space-5); height: var(--space-5); }
.checkbox--lg .checkbox__box { width: var(--space-6); height: var(--space-6); }

/* Glyph. 16 in the small box is read from Figma. 20 in the large
   box is derived from the same ratio: the large checked variants
   ship as flattened images, so the inner glyph size cannot be
   read from the API. Confirm before relying on it. */
.checkbox--sm .checkbox__glyph { --icon-size: var(--space-4); }
.checkbox--lg .checkbox__glyph { --icon-size: var(--space-6); }

/* ---------- selected=on and selected=Indeterminate ----------
   Both fill the box solid and drop the ring. */

.checkbox[aria-checked="true"] .checkbox__box,
.checkbox[aria-checked="mixed"] .checkbox__box,
.checkbox.is-checked .checkbox__box,
.checkbox.is-indeterminate .checkbox__box {
  background-color: var(--primary);
  box-shadow: none;
}

/* ---------- state=pressed ---------- */

.checkbox.is-pressed[aria-checked="true"] .checkbox__box,
.checkbox.is-pressed[aria-checked="mixed"] .checkbox__box,
.checkbox.is-pressed.is-checked .checkbox__box,
.checkbox.is-pressed.is-indeterminate .checkbox__box {
  background-color: var(--secondary);
}

/* ---------- state=disabled ----------
   Keep last. Unchecked disabled is visually identical to unchecked
   enabled in Figma, so only the filled states change. */

.checkbox:disabled,
.checkbox.is-disabled { cursor: not-allowed; }

.checkbox:disabled[aria-checked="true"] .checkbox__box,
.checkbox:disabled[aria-checked="mixed"] .checkbox__box,
.checkbox:disabled.is-checked .checkbox__box,
.checkbox:disabled.is-indeterminate .checkbox__box,
.checkbox.is-disabled[aria-checked="true"] .checkbox__box,
.checkbox.is-disabled[aria-checked="mixed"] .checkbox__box,
.checkbox.is-disabled.is-checked .checkbox__box,
.checkbox.is-disabled.is-indeterminate .checkbox__box {
  background-color: var(--status-neutral-softer);
  color: var(--text-on-surface-disabled);
}

/* Figma ships no distinct unchecked-pressed or unchecked-disabled
   rendering: all three unchecked variants are byte-identical. The
   designer sticky on this page says "we do not have any pressed
   state", yet pressed variants are published. Reproduced as drawn. */


/* ---------- checkbox_rounded variant ----------
   Figma: "checkbox_rounded" (8988:30256), page 15277:16559.
   Identical to checkbox except .checkbox__box uses border-radius: 50%. */

.checkbox--rounded .checkbox__box { border-radius: 50%; }

/* Rounded pressed unchecked: the ring turns secondary (square checkbox has no such change). */
.checkbox--rounded.is-pressed:not(.is-checked):not([aria-checked="true"]) .checkbox__box {
  --checkbox-ring: var(--secondary);
}

/* ---------- checkbox_with_label ----------
   Figma: "checkbox_with_label" (9761:6636), page 15277:16559.
   Flex row: checkbox + label text. */

.checkbox-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.checkbox-label__text {
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface);
  padding: 10px 0; /* off-scale — D-checkbox-label-py */
}

.checkbox-label.is-disabled .checkbox-label__text,
.checkbox-label:has(.checkbox:disabled) .checkbox-label__text {
  color: var(--text-on-surface-disabled);
}


/* ============================================================
   COMPONENT — radioButton
   Figma: component set "radioButton" (48166:36612), page 15277:16571.
   Variants: state (enabled | pressed | disabled) x selected
   (yes | no). 6 variants.

   Every variant ships as a flattened SVG, so the values below were
   read out of the exported geometry, not from layer structure:
   40 hit area, outer circle r10 (20 across), inner circle r3 when
   selected (a 6 dot) and r8 when not (a 2 ring).

   OFF-SCALE. The 6 selected dot has no space_* token.

   TWO DISAGREEMENTS WITH CHECKBOX, reproduced as drawn:
   - radio pressed is informative/boldest #003646; checkbox pressed
     is secondary #4e616d.
   - radio disabled differs by selection, neutral/soft when selected
     and neutral/softer when not; checkbox disabled is always
     neutral/softer.
   ============================================================ */

.radio {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-10);
  height: var(--space-10);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.radio__mark {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-5);
  height: var(--space-5);
  border-radius: 50%;
  background-color: var(--outline-soft);
}

.radio__dot {
  width: var(--space-4);
  height: var(--space-4);
  border-radius: 50%;
  background-color: var(--surface-container-lowest);
}

/* ---------- selected=yes ---------- */

.radio[aria-checked="true"] .radio__mark,
.radio.is-checked .radio__mark { background-color: var(--primary); }

.radio[aria-checked="true"] .radio__dot,
.radio.is-checked .radio__dot { width: 6px; height: 6px; }  /* off-scale */

/* ---------- state=pressed ----------
   One colour for both selections. */

.radio.is-pressed .radio__mark {
  background-color: var(--status-informative-boldest);
}

/* ---------- state=disabled ----------
   Keep last. The two selections take different greys. */

.radio:disabled,
.radio.is-disabled { cursor: not-allowed; }

.radio:disabled .radio__mark,
.radio.is-disabled .radio__mark { background-color: var(--status-neutral-softer); }

.radio:disabled[aria-checked="true"] .radio__mark,
.radio:disabled.is-checked .radio__mark,
.radio.is-disabled[aria-checked="true"] .radio__mark,
.radio.is-disabled.is-checked .radio__mark { background-color: var(--status-neutral-soft); }


/* ============================================================
   COMPONENT — toggle
   Figma: component set "toggle" (48166:37782), page 15277:16572.
   Variants: state (enabled | disabled) x selected (yes | no).
   4 variants. No pressed state exists.

   Flattened in Figma; geometry read from the exported SVG:
   40 hit area, track 36x20 rx10 at x2/y10, knob r8 (16 across)
   with cx 12 when off and cx 28 when on, so a 2 inset each end
   and a 16 travel.

   OFF-SCALE: track width 36, radius 10, the 2 inset.
   ============================================================ */

.toggle {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  width: var(--space-10);
  height: var(--space-10);
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.toggle__track {
  position: relative;
  box-sizing: border-box;
  width: 36px;                        /* off-scale */
  height: var(--space-5);
  margin: 0 auto;
  border-radius: 10px;                /* off-scale */
  background-color: var(--status-neutral-soft);
  transition: background-color 120ms ease;
}

.toggle__knob {
  position: absolute;
  top: 2px;                           /* off-scale */
  left: 2px;                          /* off-scale */
  width: var(--space-4);
  height: var(--space-4);
  border-radius: 50%;
  background-color: var(--surface-container-lowest);
  transition: transform 120ms ease;
}

.toggle[aria-checked="true"] .toggle__track,
.toggle.is-checked .toggle__track { background-color: var(--primary); }

.toggle[aria-checked="true"] .toggle__knob,
.toggle.is-checked .toggle__knob { transform: translateX(var(--space-4)); }

/* Disabled is one grey for both selections, unlike radio. */
.toggle:disabled,
.toggle.is-disabled { cursor: not-allowed; }

.toggle:disabled .toggle__track,
.toggle.is-disabled .toggle__track { background-color: var(--status-neutral-softer); }

@media (prefers-reduced-motion: reduce) {
  .toggle__track, .toggle__knob { transition: none; }
}


/* ============================================================
   COMPONENT — star  (base element of rate)
   Figma: component set "star" (15277:42402), page 15277:16570.
   Variants: state (Default | Hover) x type (Full | Half | Zero).

   The glyph is `control_star_filled`, already in Icon_App.css, so
   this is built from the icon rather than a new asset. Full is
   notice #F5A623, empty is neutral/softer #E8E8E8. Half is the
   empty star with the left 50% overlaid in notice, which is how
   Figma does it (a crop mask on the same glyph).

   Hover scales the glyph from 24 to 26. 26 is off-scale, so it is
   expressed as a transform rather than a second size.
   ============================================================ */

.star {
  position: relative;
  display: inline-block;
  width: var(--space-6);
  height: var(--space-6);
  color: var(--status-neutral-softer);
  transition: transform 120ms ease;
}

.star .icon { --icon-size: 100%; }

.star--full { color: var(--status-notice); }

.star__half {
  position: absolute;
  inset: 0;
  color: var(--status-notice);
  clip-path: inset(0 50% 0 0);
}

/* 26/24 */
.star--hover { transform: scale(1.08333); }

.rate {
  display: inline-flex;
  align-items: center;
  gap: 0;
}

@media (prefers-reduced-motion: reduce) {
  .star { transition: none; }
}


/* ============================================================
   COMPONENT — status
   Figma: component set "status" (46978:31952), page 15277:16581.
   Variants: Emphasis (Low only) x Status (Positive | Informative |
   Alert | Notice | Notice - Alt | Neutral). 6 variants.

   Emphasis has one value published. The axis exists, so Medium and
   High are presumably planned but absent.

   Every family fills with its own `softest` and labels with its own
   `bold`. Neutral is the exception: it fills with
   surfaceContainerHighest and labels with neutral/boldest.
   ============================================================ */

.status {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--space-4);
  font: var(--type-metadata-02-bolder);
  letter-spacing: 0;
  white-space: nowrap;
}

.status .icon { --icon-size: var(--space-3); }

.status--positive    { background-color: var(--status-positive-softest);    color: var(--status-positive-bold); }
.status--informative { background-color: var(--status-informative-softest); color: var(--status-informative-bold); }
.status--alert       { background-color: var(--status-alert-softest);       color: var(--status-alert-bold); }
.status--notice      { background-color: var(--status-notice-softest);      color: var(--status-notice-bold); }
.status--notice-alt  { background-color: var(--status-notice-alt-softest);  color: var(--status-notice-alt-bold); }

/* Neutral does not follow the pattern: a surface fill, not a
   status fill, and `boldest` rather than `bold`. As drawn. */
.status--neutral {
  background-color: var(--surface-container-highest);
  color: var(--status-neutral-boldest);
}

/* Icon glyphs: informative and alert use the `base` colour, neutral
   uses text/onSurface. Positive, notice, notice-alt follow the label. */
.status--informative .icon { color: var(--status-informative-base); }
.status--alert .icon       { color: var(--status-alert-base); }
.status--neutral .icon     { color: var(--text-on-surface); }


/* ============================================================
   COMPONENT — badge
   Figma: component set "badge" (46527:35493), page 15277:16581.
   Variants: Type (Dot | Digit | Text | Icon) × Usage (Overlay | Nested).

   Dot: a 10×10 filled circle. Digit/Text: pill with alert-base bg,
   white text (body-03-bolder 12/16). Overlay variants get a 1px
   outline-softest border. Icon: a surface disc holding a
   contentDisplayIcon — re-uses existing .content-display-icon.
   ============================================================ */

.badge {
  box-sizing: border-box;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  min-height: 20px;
  padding: 0 6px; /* off-scale — D-badge-px */
  border-radius: 100px;
  overflow: hidden;
  background-color: var(--status-alert-base);
  font: var(--type-body-03-bolder);
  letter-spacing: 0;
  color: var(--text-inverse-on-surface);
  white-space: nowrap;
  text-align: center;
}

.badge--overlay {
  box-shadow: inset 0 0 0 1px var(--outline-softest);
}

/* ---------- Type=Dot ---------- */

.badge--dot {
  min-width: 10px;
  min-height: 10px;
  width: 10px;
  height: 10px;
  padding: 0;
}

/* ---------- Type=Digit (nested) — smaller min-size ---------- */

.badge--nested:not(.badge--dot) {
  min-width: var(--space-5);
  min-height: var(--space-5);
  padding: 0 var(--space-1);   /* plus the 1 ring = 5 */
  border: 1px solid transparent;
  background-clip: padding-box;
}

.badge--dot.badge--nested {
  border: 1px solid transparent;
  background-clip: padding-box;
}

/* ---------- Type=Icon — surface disc holding an icon ---------- */

.badge--icon {
  min-width: auto;
  min-height: auto;
  padding: 0;
  background-color: var(--surface);
  border-radius: 10240px;
}

.badge--icon { color: var(--text-on-surface); }

.badge--icon.badge--overlay { box-shadow: none; }

.badge--icon .icon { --icon-size: 20px; }

.badge--icon.badge--nested .icon { --icon-size: var(--space-6); }

/* ============================================================
   COMPONENT — badgeOverlay
   Figma: "Badge Overlay | v1.0" (46527:35517), page 15277:16581.
   A positioning wrapper: child slot + absolutely-placed badge.
   Four types: Small (dot), Single Digit, Multiple Digits, Text.
   ============================================================ */

.badge-overlay {
  position: relative;
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
}

.badge-overlay__badge {
  position: absolute;
  top: -4px; /* off-scale — D-badge-overlay-top */
  right: 0;
  z-index: 1;
}

.badge-overlay__badge--digit {
  right: -6px; /* off-scale — D-badge-overlay-digit-right */
}

.badge-overlay__badge--text {
  right: -14px; /* off-scale — D-badge-overlay-text-right */
}

.badge-overlay__badge--dot {
  top: -1px; /* off-scale — D-badge-overlay-dot-top */
  right: -1px; /* off-scale — D-badge-overlay-dot-right */
}


/* ============================================================
   COMPONENT — progressBar
   Figma: component set "progressBar" (7814:11372), page 15277:16609.
   Variants: Progress 10% to 100% in tens. 10 variants.

   Published as ten fixed steps, but the only thing that changes is
   the fill width, so this is one element driven by --progress
   rather than ten classes.

   The track is neutral/base at 20% opacity, which is a raw opacity
   in Figma with no token behind it.
   ============================================================ */

.progress-bar {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: var(--space-1);
  background-color: transparent;
}

.progress-bar::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: var(--status-neutral-base);
  opacity: 0.2;                       /* raw in Figma, no token */
}

.progress-bar__fill {
  position: relative;
  width: var(--progress, 0%);
  height: 100%;
  background-color: var(--primary);
}


/* ============================================================
   COMPONENT — avatar
   Figma: component set "avatar" (47588:35618), page 15277:16580.
   Variants: Size (xsmall | small | medium | large | xlarge) x
   State (Default | Initial | Fallback). 15 variants.

   Unusually clean: every box size and every initial type size
   lands on an existing token, no off-scale values at all.

   | size   | box | token    | initials       |
   | xsmall | 32  | space_8  | body02_regular |
   | small  | 40  | space_10 | body01_regular |
   | medium | 48  | space_12 | h4_regular     |
   | large  | 56  | space_14 | h3_regular     |
   | xlarge | 72  | space_18 | h2_regular     |

   Radius is 100px in Figma, which is just "fully round" — 50%.
   ============================================================ */

.avatar {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  border-radius: 50%;
  background-color: var(--surface-container-highest);
  color: var(--text-on-surface);
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar--xs { width: var(--space-8);  height: var(--space-8);  font: var(--type-body-02-regular); }
.avatar--sm { width: var(--space-10); height: var(--space-10); font: var(--type-body-01-regular); }
.avatar--md { width: var(--space-12); height: var(--space-12); font: var(--type-h4-regular); }
.avatar--lg { width: var(--space-14); height: var(--space-14); font: var(--type-h3-regular); }
.avatar--xl { width: var(--space-18); height: var(--space-18); font: var(--type-h2-regular); }

.avatar--xs, .avatar--sm, .avatar--md, .avatar--lg, .avatar--xl { letter-spacing: 0; }

/* State=Fallback is a placeholder image glyph on the same fill.
   Uses control_image_outline from Icon_App.css. */
.avatar--fallback { color: var(--outline-soft); }
.avatar--fallback .icon { --icon-size: 50%; }


/* ============================================================
   COMPONENT — tooltip
   Figma: component set "tooltip" (47606:23821), page 15277:16598.
   Variants: position (top | bottom) x (left | center | right).
   6 variants, plus a `dismissible` boolean and a `tooltip_beak`
   base element (16x8).

   Figma note on the component: "Adjust the Beak's Padding to
   centrally align it to the subject".

   NOT A TOKEN: the drop shadow is a raw
   `0 12px 12px rgba(28,28,28,0.1)`, not one of the five effect
   styles. Recorded as `--tooltip-shadow` so it is visible rather
   than buried, and flagged as a gap.

   OFF-SCALE: 14 vertical padding, and the 12 right padding is a
   token but pairs asymmetrically with 16 on the left.
   ============================================================ */

:root {
  --tooltip-shadow: 0 12px 24px rgba(28, 28, 28, 0.1);  /* raw in Figma */
}

.tooltip {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  filter: drop-shadow(var(--tooltip-shadow));
}

.tooltip--center { align-items: center; }
.tooltip--right  { align-items: flex-end; }

.tooltip__beak {
  width: var(--space-4);
  height: var(--space-2);
  margin: 0 var(--space-4);
  background-color: var(--status-neutral-boldest);
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.tooltip__body {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: 14px var(--space-3) 14px var(--space-4);   /* 14 off-scale */
  border-radius: var(--space-rounded-corner);
  background-color: var(--status-neutral-boldest);
  color: var(--text-inverse-on-surface);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
}

.tooltip__text { flex: 1 0 0; min-width: 0; }

.tooltip__dismiss {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--space-6);
  height: var(--space-6);
  border: 0;
  padding: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}

.tooltip__dismiss .icon { --icon-size: var(--space-5); }

/* bottom_* variants put the beak underneath */
.tooltip--bottom { flex-direction: column-reverse; }


/* ============================================================
   COMPONENT — tab (tab_pill)
   Figma: component set "tab_pill" (53532:63215), page 15277:16601.
   Variants: type (standard | underlined | subtle) x state
   (inactive | active | disabled). 8 published — subtle has no
   disabled. Booleans: leadingIcon, trailingIcon, aboveIcon, badge.

   The parent `tab` set (53532:63115) is a layout wrapper around
   these pills (fixed | flex | overflow | tab_switch); the pill is
   the atomic unit and is what is built here.

   Radius 40 happens to equal space_10, so it is expressed as a
   token rather than a literal.

   Each type uses a different label WEIGHT for the same size:
   standard inactive medium, underlined inactive regular, every
   active bolder. That is a real distinction, not a slip.
   ============================================================ */

.tab {
  box-sizing: border-box;
  display: inline-flex;
  align-items: flex-start;
  justify-content: center;
  gap: var(--space-2);
  margin: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font: var(--type-body-02-medium);
  letter-spacing: 0;
  color: var(--text-on-surface);
  white-space: nowrap;
}

.tab .icon { --icon-size: var(--space-4); }

/* ---------- type=standard and type=subtle: a pill ---------- */

.tab--standard,
.tab--subtle {
  padding: var(--space-2) var(--space-4);
  border-radius: var(--space-10);
  background-color: var(--surface-container);
}

.tab--subtle { width: 172px; }        /* fixed in Figma */

.tab--standard.is-active,
.tab--subtle.is-active {
  background-color: var(--secondary);
  color: var(--text-inverse-on-surface);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
}

.tab--standard:disabled,
.tab--standard.is-disabled {
  background-color: var(--surface-container-low);
  color: var(--text-on-surface-disabled);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  cursor: not-allowed;
}

/* ---------- type=underlined: no fill, a 2 rule when active ---------- */

.tab--underlined {
  padding: var(--space-3) var(--space-4) var(--space-4) var(--space-4);
  background-color: transparent;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  box-shadow: none;
}

.tab--underlined.is-active {
  color: var(--text-brand-primary);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  box-shadow: inset 0 -2px 0 0 var(--outline-brand-primary);
}

.tab--underlined:disabled,
.tab--underlined.is-disabled {
  color: var(--text-on-surface-disabled);
  cursor: not-allowed;
}

/* ---------- aboveIcon: icon stacked over the label ---------- */

.tab--above-icon {
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.tab--above-icon .icon { --icon-size: var(--space-6); }

/* ---------- badge dot ---------- */

.tab__badge {
  flex-shrink: 0;
  width: var(--space-2);
  height: var(--space-2);
  border-radius: 50%;
  background-color: var(--status-alert-base);
}

/* The disabled badge is a raw #d42e1c in Figma, which is not in
   the colour set at all and is not alert/base. Reproduced, flagged. */
.tab:disabled .tab__badge,
.tab.is-disabled .tab__badge { background-color: #d42e1c; }   /* off-token */


/* ============================================================
   COMPONENT — slider
   Figma: component set "slider" (8300:6604) with the
   `progressIndicator` (8300:6626) and `baseElement_slider_handle`
   (8300:6823) base elements. Page 15277:16573.

   Track 4 high, radius 4, inactive neutral/soft, active primary.
   Handle is a 20 circle in primary. Container pads 34 each side so
   the handle never clips; 34 is off-scale.

   The value bubble on the handle reuses the tooltip recipe:
   neutral/boldest fill, inverseOnSurface label, 12 padding,
   radius 8, and the same raw drop shadow the tooltip uses.
   ============================================================ */

.slider {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: 100%;
  padding: var(--space-2) 34px;       /* 34 off-scale */
}

.slider__track {
  position: relative;
  flex: 1 0 0;
  min-width: 0;
  height: var(--space-1);
  border-radius: var(--space-1);
  background-color: var(--status-neutral-soft);
}

.slider__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--slider-value, 0%);
  border-radius: var(--space-1);
  background-color: var(--primary);
}

.slider__handle {
  position: absolute;
  top: 50%;
  left: var(--slider-value, 0%);
  width: var(--space-5);
  height: var(--space-5);
  margin: calc(var(--space-5) / -2) 0 0 calc(var(--space-5) / -2);
  border-radius: 50%;
  background-color: var(--primary);
}

.slider:disabled,
.slider.is-disabled { cursor: not-allowed; }

.slider.is-disabled .slider__fill,
.slider.is-disabled .slider__handle { background-color: var(--status-neutral-soft); }

/* Value bubble beak: 16x8 pointing down at the handle. */
.slider__value::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  width: var(--space-4);
  height: var(--space-2);
  margin-left: calc(var(--space-4) / -2);
  background-color: var(--status-neutral-boldest);
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

/* Value bubble, shown on the focused variant. */
.slider__value {
  position: absolute;
  bottom: calc(100% + var(--space-3));   /* 8 beak + 4 gap */
  left: 50%;
  transform: translateX(-50%);
  padding: var(--space-3);
  border-radius: var(--space-rounded-corner);
  background-color: var(--status-neutral-boldest);
  color: var(--text-inverse-on-surface);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  white-space: nowrap;
  filter: drop-shadow(var(--tooltip-shadow));
}


/* ============================================================
   COMPONENT — infoBanner
   Figma: component set "infoBanner" (13928:29932), page 15277:16604.
   Variants: status (Neutral | Positive | Notice | Alert |
   Informative | Custom) x leadingElement (true | false). 12
   variants. Booleans: heading, link, button, tag1, tag2, tag3.

   Container: 343 wide (space_containerWidth), radius 8, padding
   16 top/bottom, 16 left, 20 right, gap 8. The asymmetric
   left/right padding is deliberate in Figma.

   THREE DEFECTS, all reproduced as drawn and all flagged:

   1. The Positive banner's heading and body use
      `noticeAlt/boldest` (#252304), a YELLOW-family token, on a
      green banner. Every other status uses `onSurface`. Almost
      certainly a mistake.
   2. The Custom banner's link uses `archive_textBrand/inverseBrand`
      — an ARCHIVED token still bound in a live component. Its
      value #c2e8ff equals `primaryContainer`, which is what the
      CSS points at.
   3. Fill and border levels are inconsistent across the family.
      Positive fills with `softer` where the rest fill with
      `softest`. Alert borders with `softer` where the rest border
      with `soft`.
   ============================================================ */

.info-banner {
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  width: var(--space-container-width);
  padding: var(--space-4) var(--space-5) var(--space-4) var(--space-4);
  border-radius: var(--space-rounded-corner);
  background-color: var(--status-neutral-softest);
  box-shadow: inset 0 0 0 1px var(--info-banner-stroke, var(--outline-soft));
  color: var(--text-on-surface);
}

.info-banner__icon { flex-shrink: 0; }
.info-banner__icon .icon { --icon-size: var(--space-6); }

.info-banner__content {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  min-width: 0;
}

.info-banner__heading {
  margin: 0;
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: inherit;
}

.info-banner__body {
  margin: 0;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: inherit;
}

.info-banner__link {
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: var(--info-banner-link, var(--text-brand-primary));
  text-decoration: none;
}

/* ---------- status ---------- */

.info-banner--neutral     { background-color: var(--status-neutral-softest);     --info-banner-stroke: var(--outline-soft); }
.info-banner--notice      { background-color: var(--status-notice-softest);      --info-banner-stroke: var(--status-notice-soft); }
.info-banner--informative { background-color: var(--status-informative-softest); --info-banner-stroke: var(--status-informative-soft); }

/* Alert borders with `softer`, not `soft`. As drawn. */
.info-banner--alert       { background-color: var(--status-alert-softest);       --info-banner-stroke: var(--status-alert-softer); }

/* Positive fills with `softer`, not `softest`. As drawn. */
.info-banner--positive {
  background-color: var(--status-positive-softer);
  --info-banner-stroke: var(--status-positive-soft);
  /* Defect 1: a yellow-family token on a green banner. */
  color: var(--status-notice-alt-boldest);
}

/* Custom is a dark banner with no stroke at all. */
.info-banner--custom {
  background-color: var(--status-neutral-boldest);
  --info-banner-stroke: transparent;
  color: var(--text-inverse-on-surface);
  /* Defect 2: Figma binds this to archive_textBrand/inverseBrand.
     Same value as primaryContainer, which is used here instead. */
  --info-banner-link: var(--primary-container);
}


/* ============================================================
   COMPONENT — accordion
   Figma: component set "accordion" (10647:25582), page 15277:16583.
   Variants: Size (medium | large) x expanded (No | Yes).
   Booleans: divider, textContent, customSlot.
   Page carries a sticky reading "Not developed yet".

   Header padding differs by size: medium is 10 vertical (off-scale),
   large is 16. Title is body02_bolder at medium, body01_bolder at
   large. The chevron is 20 inside a 24 box at medium, a full 24 at
   large.

   The expanded body pads right by space_8 (32) against space_4 (16)
   on the left — asymmetric on purpose.

   The customSlot fill is `rgba(0,152,216,0.1)`, a raw colour and a
   Figma authoring affordance, not a product style. Not reproduced.
   ============================================================ */

.accordion {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: 100%;
  background-color: var(--surface-container-lowest);
  border-bottom: 1px solid var(--outline-softest);
}

.accordion__header {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  margin: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  color: var(--text-on-surface);
}

.accordion__title { flex: 1 0 0; min-width: 0; }

.accordion--md .accordion__header {
  padding: 10px var(--space-4);       /* 10 off-scale */
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
}

.accordion--lg .accordion__header {
  padding: var(--space-4);
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
}

.accordion__chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--space-6);
  height: var(--space-6);
}

.accordion--md .accordion__chevron .icon { --icon-size: var(--space-5); }
.accordion--lg .accordion__chevron .icon { --icon-size: var(--space-6); }

.accordion__body {
  box-sizing: border-box;
  padding: 0 var(--space-8) var(--space-4) var(--space-4);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

.accordion__body p { margin: 0; }


/* ============================================================
   COMPONENT — snackbar / toast
   Figma: component set "snackbar / toast" (47069:92250),
   page 15277:16607. Variants: status (neutral | positive |
   informative | notice | alert) x with link (no | yes).
   10 variants. Booleans: leadingElement, title, trailingElement.

   343 wide, radius 8, pl 16, pr 8, py 20. Uses `shadow_level_2`
   properly, unlike tooltip and slider which paint a raw shadow.

   All five fills read directly from Figma. **Positive fills with
   `positive/softer` while the other four use their `softest`** —
   the same anomaly infoBanner has, so it is a consistent quirk of
   the Positive family rather than a one-off slip.
   ============================================================ */

.toast {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: var(--space-container-width);
  padding: var(--space-5) var(--space-2) var(--space-5) var(--space-4);
  border-radius: var(--space-rounded-corner);
  background-color: var(--status-neutral-softest);
  color: var(--text-on-surface);
  filter: drop-shadow(var(--shadow-level-2));
}

.toast__main {
  display: flex;
  flex: 1 0 0;
  align-items: flex-start;
  gap: var(--space-2);
  min-width: 0;
  padding-right: var(--space-2);
}

.toast__icon { flex-shrink: 0; }
.toast__icon .icon { --icon-size: var(--space-6); }

.toast__content { display: flex; flex: 1 0 0; flex-direction: column; min-width: 0; }
.toast__title { margin: 0; font: var(--type-body-02-bolder); letter-spacing: 0; }
.toast__body  { margin: 0; min-height: var(--space-6); font: var(--type-body-02-regular); letter-spacing: 0; }

.toast__link {
  padding: var(--space-2) 0;
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: var(--text-brand-primary);
  text-decoration: none;
}

.toast__dismiss {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: 6px;                       /* off-scale */
  border: 0;
  border-radius: 48px;                /* off-scale */
  background: none;
  color: inherit;
  cursor: pointer;
}

.toast__dismiss .icon { --icon-size: var(--space-5); }

/* ---------- status fills, all read from Figma ---------- */

.toast--neutral     { background-color: var(--status-neutral-softest); }
.toast--informative { background-color: var(--status-informative-softest); }
.toast--notice      { background-color: var(--status-notice-softest); }
.toast--alert       { background-color: var(--status-alert-softest); }

/* `softer`, not `softest`. Matches infoBanner's Positive. */
.toast--positive    { background-color: var(--status-positive-softer); }

/* Leading icon colours, read from Figma. */
.toast--informative .toast__icon { color: var(--primary); }
.toast--notice      .toast__icon { color: var(--status-notice-bold); }
.toast--alert       .toast__icon { color: var(--status-alert-base); }
.toast--positive    .toast__icon { color: var(--status-positive-bold); }
.toast--neutral     .toast__icon { color: var(--text-on-surface); }


/* ============================================================
   COMPONENT — dialogBox_popUp
   Figma: component "dialogBox_popUp" (22189:36603), page 15277:16606.
   No variant axis; three booleans: image, subHeading, customSlot.

   327 wide, radius 8, padding 24 all round, gap 24. Heading is
   H4_bolder, subheading body01_regular on `onSurfaceDim`.
   The image container radius is 16, not 8.

   Two things worth knowing:
   - The fill is `surface` (#f8f9fb), the PAGE background token,
     used here as a card fill. Every other card-like component in
     this system uses a `surfaceContainer*` token.
   - The shadow is the same raw `0 12 12 rgba(28,28,28,0.1)` that
     tooltip and slider use, not `shadow_level_2`.
   ============================================================ */

.dialog {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-6);
  width: 327px;                       /* mobile frame less 24 each side */
  padding: var(--space-6);
  border-radius: var(--space-rounded-corner);
  background-color: var(--surface);
  filter: drop-shadow(var(--tooltip-shadow));   /* same raw shadow as tooltip: 0 12 24, 10% */
}


.dialog__image {
  width: 100%;
  border-radius: var(--space-4);
  overflow: hidden;
}

.dialog__image img { display: block; width: 100%; height: auto; }

.dialog__content {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
}

.dialog__heading {
  margin: 0;
  width: 100%;
  font: var(--type-h4-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.dialog__subheading {
  margin: 0;
  width: 100%;
  font: var(--type-body-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

/* buttonGroup, stack=horizontal — two equal buttons side by side.
   The published `buttonGroup` set (57011:34704) also has vertical
   and customSlot stacks, which are not built here. */
.button-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  width: 100%;
}

.button-group__row { display: flex; gap: var(--space-4); width: 100%; }
.button-group--horizontal .button-group__row > .btn { flex: 1 0 0; min-width: 0; }
.button-group--vertical .button-group__row { flex-direction: column; }


/* ============================================================
   COMPONENT — skeletonLoader
   Figma: component set "skeletonLoader" (51234:30878),
   page 15277:16612. Variants: shape (tall_rectangle |
   short_rectangle | circle) x shimmerPosition (start | end).
   Figma note: "Skeleton shape and size can be customized".

   Fill is `surfaceContainerLow`. Published sizes are
   327x57, 200x12 and 40 round, but since the note says size is
   customisable these are defaults, overridable inline.

   shimmerPosition start/end are the two ends of one animation, so
   this is built as a real moving highlight rather than two static
   classes. The shimmer is a white gradient 248 wide, peaking at
   51.5%, which is reproduced.
   ============================================================ */

.skeleton {
  position: relative;
  overflow: hidden;
  display: block;
  background-color: var(--surface-container-low);
}

.skeleton--tall   { width: 327px; height: 57px; }
.skeleton--short  { width: 200px; height: var(--space-3); }
.skeleton--circle { width: var(--space-10); height: var(--space-10); border-radius: 50%; }

.skeleton::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 248px;                       /* off-scale, from Figma */
  background-image: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    #ffffff 51.563%,
    rgba(255, 255, 255, 0) 100%
  );
  animation: skeleton-shimmer 1.4s linear infinite;
}

@keyframes skeleton-shimmer {
  from { transform: translateX(-248px); }
  to   { transform: translateX(calc(100% + 248px)); }
}

@media (prefers-reduced-motion: reduce) {
  .skeleton::after { animation: none; opacity: 0; }
}


/* ============================================================
   COMPONENT — loader (spinner)
   Figma: component set "loader" (46850:36451), page 15277:16612.
   Variants: Theme (Brand | Grey | Theme4). 24 across.

   Ships as an asset, so the ring below is a CSS approximation of
   the same silhouette, not the exported artwork. Same caveat as
   the button's loading spinner. Match both to the real asset
   before shipping.
   ============================================================ */

.loader {
  display: inline-block;
  box-sizing: border-box;
  width: var(--space-6);
  height: var(--space-6);
  border: 2px solid currentColor;     /* off-scale, approximation */
  border-top-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.8s linear infinite;
}

.loader--brand  { color: var(--primary); }
.loader--theme4 { color: var(--primary); }   /* Figma: same as Brand */
.loader--grey   { color: var(--status-neutral-base); }



/* ============================================================
   COMPONENT — bottomSheet_v2_0
   Figma: component "bottomSheet_v2_0" (10466:7250), page 15277:16605.
   No variant axis; booleans: handle, backButton, image, sectionHeader,
   customSlot, button, scrollBar.

   FIGMA NOTE, worth honouring in code: "Custom Slot and Image
   shouldn't coexist together. Only use either one of them."

   375 wide, top corners 24 (space_6), fill surfaceContainerLowest.
   The sheet stacks: handle, then image OR custom slot, then section
   header, then the action container, then the iOS home indicator.
   ============================================================ */

.bottom-sheet {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  overflow: hidden;
  width: 375px;
  border-top-left-radius: var(--space-6);
  border-top-right-radius: var(--space-6);
  background-color: var(--surface-container-lowest);
}

/* The sheet's inner autoLayout wraps handle, image and section
   header and carries a 16 bottom pad of its own, above the action
   container's own padding. Missing it makes the sheet 16 short. */
.bottom-sheet__body {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  overflow: hidden;
  width: 100%;
  padding-bottom: var(--space-4);
  border-top-left-radius: var(--space-6);
  border-top-right-radius: var(--space-6);
  background-color: var(--surface-container-lowest);
}

/* ---------- handle ---------- */

.bottom-sheet__handle {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  width: 100%;
  height: var(--space-10);
  padding: var(--space-3) var(--space-4) 0;
}

.bottom-sheet__puller {
  width: var(--space-10);
  height: var(--space-1);
  border-radius: 100px;               /* fully round */
  background-color: var(--status-neutral-boldest);
}

.bottom-sheet__puller--on-dark {
  background-color: var(--outline-soft);
}

/* ---------- image ---------- */

.bottom-sheet__image {
  box-sizing: border-box;
  width: 100%;
  padding: 0 var(--space-6);
}

.bottom-sheet__image img { display: block; width: 100%; height: auto; }

/* ---------- action container ---------- */

.bottom-sheet__actions {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  padding: 0 var(--space-6) var(--space-6);
}

/* ---------- iOS home indicator ----------
   A platform chrome element rather than a design-system component,
   but it is published inside the sheet so it is reproduced. */

.ios-home-indicator {
  position: relative;
  width: 100%;
  height: 34px;                       /* off-scale, platform value */
  background-color: var(--surface-container-lowest);
}

.ios-home-indicator::after {
  content: "";
  position: absolute;
  bottom: var(--space-2);
  left: 50%;
  transform: translateX(-50%);
  width: 134px;                       /* off-scale, platform value */
  height: 5px;                        /* off-scale, platform value */
  border-radius: 100px;
  background-color: var(--text-on-surface);
}


/* ============================================================
   COMPONENT — sectionHeader
   Figma: "sectionHeader" (10466:7251), standalone page 15373:62047.
   4 densities (superLoose/multiLoose/singleLoose/singleDense),
   7 title types, 5 trailing types, 3 subheading sizes, accordion.

   Base padding: pl space-6, pr space-4. Density sets py.
   Default title is H5_bolder (medium_title). Subheading is
   body02_regular on `onSurfaceVariant` with its own pr space-4.
   ============================================================ */

.section-header {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-4) var(--space-4) var(--space-2) var(--space-6);
}

.section-header__title {
  margin: 0;
  width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  font: var(--type-h5-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.section-header__subheading {
  box-sizing: border-box;
  margin: 0;
  width: 100%;
  padding-right: var(--space-4);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-variant);
}

/* sectionHeader — density modifiers (override vertical padding) */
.section-header--super-loose { padding-top: var(--space-6); padding-bottom: var(--space-6); }
.section-header--multi-loose  { padding-top: var(--space-4); padding-bottom: var(--space-4); }
.section-header--single-loose { padding-top: var(--space-3); padding-bottom: var(--space-3); }
.section-header--single-dense { padding-top: var(--space-2); padding-bottom: var(--space-2); }

/* sectionHeader — title row (wraps title text + trailing) */
.section-header__title-row { display: flex; gap: var(--space-2); align-items: center; width: 100%; }

/* sectionHeader — title type modifiers (default is H5_bolder = medium_title) */
.section-header__title--lg       { font: var(--type-h3-bolder);       letter-spacing: 0; }
.section-header__title--body     { font: var(--type-body-01-bolder);  letter-spacing: 0; }
.section-header__title--caption  { font: var(--type-body-02-bolder);  letter-spacing: 0; white-space: nowrap; }
.section-header__title--metadata { font: var(--type-metadata-01-regular); letter-spacing: 0; white-space: nowrap; }
.section-header__title--hug      { flex: 0 0 auto; width: auto; }

/* sectionHeader — trailing element types */
.section-header__trailing { display: flex; align-items: center; flex-shrink: 0; }
.section-header__trailing-link { display: inline-flex; align-items: center; flex-shrink: 0; padding: var(--space-3) 0; border: 0; border-radius: var(--space-rounded-corner); background: none; font: var(--type-body-01-bolder); letter-spacing: 0; color: var(--text-brand-primary); cursor: pointer; white-space: nowrap; }
.section-header__trailing-link--sm { font: var(--type-body-03-bolder); padding: var(--space-2) 0; }
.section-header__trailing-metadata { flex-shrink: 0; margin: 0; font: var(--type-metadata-01-regular); letter-spacing: 0; color: var(--text-on-surface-dim); text-align: right; white-space: nowrap; }

/* sectionHeader — subheading size modifiers (default is body02_regular) */
.section-header__subheading--metadata-01 { font: var(--type-metadata-01-regular); letter-spacing: 0; }
.section-header__subheading--metadata-02 { font: var(--type-metadata-02-regular); letter-spacing: 0; }

/* sectionHeader, no title: right pad 24 instead of 16 */
.section-header--no-title { padding-right: var(--space-6); }

/* sectionHeader — accordion variant */
.section-header--accordion { padding: var(--space-4) var(--space-6); gap: var(--space-6); }
.section-header--accordion.is-expanded { gap: var(--space-2); }


/* ============================================================
   COMPONENT — textField
   Figma: component set "textField" (51945:61225), page 15277:16561.
   Variants: size (x-large | medium) x state (default | focused |
   error | focused on error | disabled | disabled_focus) x
   populated (No | Yes). 20 published.
   Booleans: label, bodyText, helperText, leadingElement,
   trailingElement, errorMessage.

   Figma note: "Trailing Icon is swappable, enter Icon Button
   Layer to swap".

   **This is where `haloFocus` is used.** The focused state pairs a
   brand-primary border with the `haloFocus` drop shadow. That is
   the first component found using it, and it resolves what that
   effect is for.

   Input min-height is 52 at x-large and 40 at medium; padding is
   16 horizontal, 12 vertical.
   ============================================================ */

.field {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
}

.field__label {
  display: flex;
  gap: var(--space-1);
  align-items: flex-start;
  margin: 0;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

/* The required marker is 12/16 where the label is 14/20, so it
   sits high against the label baseline. As drawn. */
.field__required {
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--status-alert-base);
}

.field__input {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  min-height: 52px;                   /* off-scale, x-large */
  padding: var(--space-3) var(--space-4);
  border: 0;
  border-radius: var(--space-rounded-corner);
  background-color: var(--surface-container-lowest);
  box-shadow: inset 0 0 0 1px var(--field-stroke, var(--outline-soft));
  font: var(--type-body-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.field--md .field__input {
  min-height: var(--space-10);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
}

.field__control {
  flex: 1 0 0;
  min-width: 0;
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
}

.field__control::placeholder { color: var(--text-on-surface-placeholder); }
.field--md .field__input { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.field--md .field__leading { padding: 0; }
.field.is-disabled .field__control { color: var(--text-on-surface-dim); }
.field.is-disabled.is-focused .field__control { color: var(--text-on-surface-variant); }

.field__leading { padding: 2px; }     /* off-scale */
.field__leading, .field__trailing {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--space-6);
  height: var(--space-6);
}
.field__leading .icon, .field__trailing .icon { --icon-size: var(--space-5); }

.field__helper {
  margin: 0;
  width: 100%;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

/* ---------- states ---------- */

.field.is-focused .field__input {
  --field-stroke: var(--outline-brand-primary);
  box-shadow: inset 0 0 0 1px var(--field-stroke), var(--halo-focus);
}

.field.is-error .field__input { --field-stroke: var(--status-alert-base); }

.field.is-error.is-focused .field__input {
  --field-stroke: var(--status-alert-base);
  box-shadow: inset 0 0 0 1px var(--field-stroke), var(--halo-focus-error);
}

.field.is-error .field__helper { color: var(--status-alert-base); }

.field.is-disabled .field__input {
  --field-stroke: var(--outline-softest);
  background-color: var(--surface-container-low);
  cursor: not-allowed;
}


/* ============================================================
   COMPONENT — dropdown  (aka Select)
   Figma: component set "dropdown" (46752:36129), page 15277:16561.
   Variants: variant (default | focused | error | focused_on_error |
   disabled) x selected (No | Yes). 9 published — `disabled` has no
   selected=Yes.

   Figma note: "Initially 'Dropdown', renamed to 'Select' according
   to Industry Term." The set is still named `dropdown`, so both
   names are live. Class is `.select`, with the Figma name recorded
   here.

   Structurally a textField, with two differences that matter:
   - **It fills with `surface` (#f8f9fb), not
     `surfaceContainerLowest` like textField.** Two controls that
     sit next to each other in the same form, on different fills.
   - Its radius is bound to `space_2` where textField uses
     `space_roundedCorner`. Same value 8, different token.
   ============================================================ */

.select { }

.select .field__input {
  background-color: var(--surface);
  border-radius: var(--space-2);      /* space_2, not space_roundedCorner */
}

.select.is-disabled .field__input {
  background-color: var(--surface-container-low);
  --field-stroke: var(--outline-softest);
}

.select.is-disabled .field__control { color: var(--text-on-surface-disabled); }


/* ============================================================
   COMPONENT — textArea
   Figma: component set "textArea" (6302:88902), page 15277:16561.
   Variants: State (Default | Focused | Error | Focused on Error |
   Disabled) x Populated (No | Yes). 10 variants.
   Booleans: label, mandatory, helperText, characCount, customSlot.

   Fills `surfaceContainerLowest` like textField, not `surface` like
   the select. Padding 16 all round, gap 8, radius 8.
   The input area is min-height 82 and max-height 144, so it grows
   with content and then scrolls. Both off-scale.

   Its helper text carries a 12 icon alongside, which textField's
   does not.
   ============================================================ */

.textarea .textarea__input {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-4);
  border: 0;
  border-radius: var(--space-rounded-corner);
  background-color: var(--surface-container-lowest);
  box-shadow: inset 0 0 0 1px var(--field-stroke, var(--outline-soft));
}

.textarea__control {
  width: 100%;
  min-height: 82px;                   /* off-scale */
  max-height: 144px;                  /* off-scale */
  overflow: auto;
  resize: vertical;
  border: 0;
  padding: 0;
  background: none;
  font: var(--type-body-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.textarea__control::placeholder { color: var(--text-on-surface-placeholder); }

.textarea__count {
  width: 100%;
  margin: 0;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  text-align: right;
  color: var(--text-on-surface-dim);
}

/* The text area's helper line pairs the text with a 12 icon.
   textField's helper has no icon. */
.textarea .field__helper {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.textarea .field__helper .icon { --icon-size: var(--space-3); }

.textarea.is-focused .textarea__input {
  --field-stroke: var(--outline-brand-primary);
  box-shadow: inset 0 0 0 1px var(--field-stroke), var(--halo-focus);
}

.textarea.is-error .textarea__input { --field-stroke: var(--status-alert-base); }

.textarea.is-error.is-focused .textarea__input {
  --field-stroke: var(--status-alert-base);
  box-shadow: inset 0 0 0 1px var(--field-stroke), var(--halo-focus-error);
}

.textarea.is-error .field__helper { color: var(--status-alert-base); }

.textarea.is-disabled .textarea__input {
  box-shadow: none;
  background-color: var(--surface-container-low);
}
.textarea.is-disabled .textarea__control,
.textarea.is-disabled .textarea__count { color: var(--text-on-surface-disabled); }
.textarea.is-error .field__helper .icon { color: var(--text-on-surface-dim); }


/* ============================================================
   COMPONENT — otp
   Figma: component set "otp" (14967:39974) with the
   `otp_base _element` set (14967:39954), page 15277:16561.
   Variants: Input state (Default | Filled | Successful | Error) x
   Code state (Default | Code sent). 8 published.

   Cell 46x60, radius 12, 1 border, gap 10 between cells. The digit
   is `H1_regular` (40/48) — the largest type in the system, used
   only here.

   **`haloFocus` again.** The active cell pairs a brand-primary
   border with that drop shadow, exactly as textField's focused
   state does. Two components now confirmed using it.
   ============================================================ */

.otp {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;                          /* off-scale */
}

.otp__cell {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;                        /* off-scale */
  height: 60px;                       /* off-scale */
  border-radius: 12px;                /* off-scale */
  background: none;
  box-shadow: inset 0 0 0 1px var(--otp-stroke, var(--outline-softest));
  font: var(--type-h1-regular);
  letter-spacing: 0;
  text-align: center;
  color: var(--text-on-surface);
}

.otp__cell.is-active {
  --otp-stroke: var(--outline-brand-primary);
  box-shadow: inset 0 0 0 1px var(--otp-stroke), var(--halo-focus);
}

.otp__cell.is-error { --otp-stroke: var(--status-alert-base); color: var(--status-alert-base); }
.otp__error { margin: 0; font: var(--type-metadata-01-regular); letter-spacing: 0; color: var(--status-alert-base); }


/* ============================================================
   COMPONENT — pin
   Figma: component set "pin" (14967:40053) with the
   `pin_baseElement` set (14967:40034), page 15277:16561.
   Variants: State (Default | Filled | Successful | Error).

   Same 46x60 cell footprint as OTP but **no box border at all** —
   only a dot. Empty is an 11 circle stroked in `outline-soft`;
   filled is a 12 dot in `primary`. Read from the exported SVG,
   since the base elements ship flattened.

   NAMING: one base-element variant is literally named
   `Active=Yes, Filled=🔒`. An emoji as a variant value will not
   survive most code generators.
   ============================================================ */

.pin {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;                          /* off-scale, matches otp */
}

.pin__cell {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 46px;                        /* off-scale */
  height: 60px;                       /* off-scale */
}

.pin__dot {
  box-sizing: border-box;
  width: 12px;                        /* off-scale */
  height: 12px;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--outline-soft);
}

.pin__cell.is-filled .pin__dot {
  background-color: var(--text-on-surface-variant);
  box-shadow: none;
}
.pin.is-success .pin__cell.is-filled .pin__dot { background-color: var(--primary); }
.pin.is-error .pin__cell.is-filled .pin__dot { background-color: var(--status-alert-base); }
.pin__cell.is-active { font: var(--type-h1-regular); letter-spacing: 0; color: var(--text-on-surface); }
.pin__error { margin: 0; font: var(--type-metadata-01-regular); letter-spacing: 0; color: var(--status-alert-base); }


/* ============================================================
   COMPONENT — asset_upload  (the drop zone)
   Figma: component set "asset_upload" (15277:46096), page 15277:16561.
   Variants: Property 1 (Default | Error).

   327 wide, radius 16, **dashed** 1 border in `outline-soft`,
   fill `surfaceContainerLowest`. Icon 32. Title `H5_bolder`,
   subheading `metadata01_regular` on `onSurfacePlaceholder`, both
   centred.

   TWO THINGS FOUND HERE:
   - The inner frame is named **"[DELETE] PLEASE REPLACE THIS
     SECTION HEADER"** — a leftover authoring instruction baked
     into a published component.
   - The Error variant binds **`archive_outline/disabled`**,
     whose value is `#e920b0`. Archived tokens in this file are all
     set to that magenta deliberately, as a "this is dead" marker.
     So the Error state paints a warning colour, not a design
     colour. NOT reproduced — `alert/base` is used instead, which
     is what every other error state in the system uses.
   ============================================================ */

.asset-upload {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* 327 in Figma, i.e. the 375 frame less 24 each side. NOT
     `space_containerWidth` (343), which is the frame less 16. Two
     different container widths coexist in this system. */
  width: 327px;
  padding: var(--space-4) var(--space-6) 0;
  border: 1px dashed var(--outline-soft);
  border-radius: var(--space-4);
  background-color: var(--surface-container-lowest);
  text-align: center;
}

.asset-upload__icon .icon { --icon-size: var(--space-8); }

.asset-upload__content {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-4) 18px var(--space-6) var(--space-6);   /* 18 off-scale */
}

.asset-upload__title {
  margin: 0;
  font: var(--type-h5-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.asset-upload__hint {
  margin: 0;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-placeholder);
}

/* Error: `alert/base`, deliberately NOT the archived token Figma
   binds here. See the note above. */
.asset-upload.is-error { border-color: var(--status-alert-base); background-color: var(--surface-container-low); }
.asset-upload__icon { color: var(--primary); }
.asset-upload.is-error .asset-upload__icon { color: var(--text-on-surface-placeholder); }
.asset-upload.is-error .asset-upload__title { color: var(--text-on-surface-placeholder); }


/* ============================================================
   COMPONENT — upload  (the file tile)
   Figma: component set "upload" (52520:32857), page 15277:16577.
   Variants: State (Disabled | Uploading | Uploaded | Error).
   Booleans: title, subtitle.

   96 square, radius 16, gap 4, padding 16. Label is 12/16 bolder.

   Three of the four states change the FILL as well as the border,
   and Error switches the border from dashed to solid:

   | state     | fill                   | border               |
   | Disabled  | surfaceContainerLowest | dashed outline-soft  |
   | Uploading | surface                | dashed outline-soft  |
   | Uploaded  | the image itself       | none                 |
   | Error     | surface                | SOLID alert/base     |
   ============================================================ */

.upload-tile {
  box-sizing: border-box;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  overflow: hidden;
  width: 96px;                        /* off-scale */
  height: 96px;                       /* off-scale */
  padding: var(--space-4);
  border: 1px dashed var(--outline-soft);
  border-radius: var(--space-4);
  background-color: var(--surface-container-lowest);
  font: var(--type-body-03-bolder);
  letter-spacing: 0;
  text-align: center;
  color: var(--text-on-surface-disabled);
}

.upload-tile .icon { --icon-size: var(--space-6); }
.upload-tile p { margin: 0; }

.upload-tile__subtitle { font: var(--type-body-03-regular); letter-spacing: 0; }

.upload-tile--uploading {
  background-color: var(--surface);
  color: var(--text-on-surface-variant);
}

.upload-tile--uploading .upload-tile__subtitle { color: var(--text-on-surface-dim); }

.upload-tile--uploaded {
  padding: 0;
  border: 0;
  background-color: var(--surface-container-low);
}

.upload-tile--uploaded img { width: 100%; height: 100%; object-fit: cover; }

.upload-tile--error {
  padding: 0 var(--space-4);
  border-style: solid;
  border-color: var(--status-alert-base);
  background-color: var(--surface);
  color: var(--status-alert-base);
}

.upload-tile--error .upload-tile__subtitle { color: var(--status-alert-base); }

/* The remove control on an uploaded tile sits 4 from the top and
   60 from the left inside the 96 box. */
.upload-tile__remove {
  position: absolute;
  top: var(--space-1);
  left: 60px;                         /* off-scale */
  display: inline-flex;
  align-items: center;
  padding: 6px;                       /* off-scale */
  border: 0;
  border-radius: 48px;                /* off-scale */
  background: none;
  color: var(--text-on-surface);
  cursor: pointer;
}

.upload-tile__remove .icon { --icon-size: var(--space-6); }


/* ============================================================
   COMPONENT — appBar
   Figma: component set "appBar" (47133:32125), page 15277:16553.
   Level 1 (Sub) variants: state (default | transparent | scrolled)
   x content (Yes | No). 6 variants. Booleans: statusBar,
   leadingAction, trailingAction, customSlot, searchBarRow,
   progressBar, divider.

   375 wide, fill `surfaceContainerLowest`. The bar row is
   16 horizontal, 12 vertical. The title block adds 8 horizontal
   and **7 vertical**, which is off-scale.

   Base elements on this page also cover 9 content types
   (smallTitle, largeTitle, with subheading, with dropdown,
   searchBar, customSlot), 4 leading actions and 5 trailing
   actions. Shell, title, search bar and progress row are here;
   content-type modifiers, scrolled state, trailing-label and
   trailing-link are appended further down.
   ============================================================ */

.app-bar {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 375px;
  background-color: var(--surface-container-lowest);
}

.app-bar--transparent { background-color: transparent; }

.app-bar__row {
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  width: 100%;
  padding: var(--space-3) var(--space-4);
}

.app-bar__action {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: var(--space-2);
  border: 0;
  border-radius: 48px;                /* off-scale */
  background: none;
  color: var(--text-on-surface);
  cursor: pointer;
}

.app-bar__action .icon { --icon-size: var(--space-6); }

.app-bar__trailing { display: flex; align-items: center; gap: var(--space-2); flex-shrink: 0; }

.app-bar__content {
  box-sizing: border-box;
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  padding: 7px var(--space-2);        /* 7 off-scale */
}

.app-bar__title {
  margin: 0;
  width: 100%;
  font: var(--type-h5-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

/* Search bar. Fills `surfaceContainerHigh`, which no other
   component in the extracted set uses. */
.app-bar__search-row {
  box-sizing: border-box;
  width: 100%;
  padding: 0 var(--space-6) var(--space-4);
}

.search-bar {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  height: var(--space-10);
  padding: 0 var(--space-1) 0 10px;   /* 10 off-scale */
  border-radius: var(--space-rounded-corner);
  background-color: var(--surface-container-high);
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-placeholder);
}

.search-bar .icon { --icon-size: var(--space-4); }
.search-bar__text { flex: 1 0 0; min-width: 0; }


/* ============================================================
   COMPONENT — bottomNavigation
   Figma: "bottomNavigation" (10881:11079) with the
   `bottomNavigation_menu` set (46776:94597), page 15277:16552.
   Menu item variants: state (active | inactive).

   Item is 72 wide, gap 2, padding 8 horizontal and 4 vertical.
   Icon 24. The label is 10/12 — `Metadata03_bolder` in `primary`
   when active, `Metadata03_regular` in `onSurfaceVariant` when
   not. So active changes weight AND colour, which is why the
   metadata ramp carries both a bolder and a regular at 10.
   ============================================================ */

.bottom-nav {
  box-sizing: border-box;
  display: flex;
  align-items: flex-start;
  justify-content: space-around;
  width: 375px;
  padding: 0 var(--space-1);
  background-color: var(--surface-container);
}

.bottom-nav__item {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;                           /* off-scale */
  width: 72px;                        /* off-scale */
  padding: var(--space-1) var(--space-2);
  border: 0;
  background: none;
  cursor: pointer;
  font: var(--type-metadata-03-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-variant);
  text-align: center;
}

.bottom-nav__item .icon { --icon-size: var(--space-6); }

.bottom-nav__item.is-active {
  font: var(--type-metadata-03-bolder);
  letter-spacing: 0;
  color: var(--primary);
}

/* ---------- scanAndPay menu item ----------
   Figma: "bottomNavigation_menu_scanAndPay/v1.1" (10924:24845).
   A circular gradient button centred in the nav bar, wider than
   normal items (79px vs 72px). The circle has a 4px surface border
   ring and a primary gradient fill. */

.bottom-nav__scan-and-pay {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;                            /* off-scale — same as item gap */
  width: 79px;                         /* off-scale — D-scan-and-pay-w */
  padding-bottom: var(--space-1);
  border: 0;
  background: none;
  cursor: pointer;
  font: var(--type-metadata-03-regular);
  letter-spacing: 0;
  color: var(--text-on-surface);
  text-align: center;
}

.bottom-nav__scan-and-pay-circle {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  border: 4px solid var(--surface-container); /* off-scale — D-scan-ring */
  border-radius: 100px;
  background-image: linear-gradient(
    90deg,
    var(--primary-gradient-stop-one),
    var(--primary-gradient-stop-two)
  );
  color: var(--base-white-0);
}

.bottom-nav__scan-and-pay-circle .icon { --icon-size: var(--space-6); }


/* ============================================================
   COMPONENT — thumbnail
   Figma: page "Thumbnail / image" (15277:16590).
   Sets: `thumbnail_circular` (51727:60011), `thumbnail_squircle`
   (51727:60081).

   circular: a clipped image at a fixed square size, radius 100.
     outline=Yes adds a 1 `outline/softest` stroke — inside-
     aligned in Figma, so an inset shadow, not a border.
     thumbnail=icon is a different shape entirely: a
     `surfaceContainerLow` disc with 10 padding around a 24 icon
     box holding a 20 glyph. The variant labelled "40x40"
     therefore measures 44 — see A19.

   squircle: same clipped image, corner 16 at every size except
     32 (corner 8) and 64 (corner 18.286 — a scaled instance,
     see A20).
   ============================================================ */

.thumbnail {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  width: var(--thumbnail-size, var(--space-10));
  height: var(--thumbnail-size, var(--space-10));
}

.thumbnail > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.thumbnail--20  { --thumbnail-size: var(--space-5); }
.thumbnail--24  { --thumbnail-size: var(--space-6); }
.thumbnail--32  { --thumbnail-size: var(--space-8); }
.thumbnail--40  { --thumbnail-size: var(--space-10); }
.thumbnail--48  { --thumbnail-size: var(--space-12); }
.thumbnail--56  { --thumbnail-size: var(--space-14); }
.thumbnail--64  { --thumbnail-size: var(--space-16); }
.thumbnail--80  { --thumbnail-size: var(--space-20); }
.thumbnail--104 { --thumbnail-size: var(--space-26); }
.thumbnail--144 { --thumbnail-size: var(--space-36); }
.thumbnail--160 { --thumbnail-size: 160px; }        /* off-scale, D20 */

.thumbnail--circular { border-radius: 100px; }

.thumbnail--squircle { border-radius: var(--space-4); }
.thumbnail--squircle.thumbnail--32 { border-radius: var(--space-2); }
/* 64 carries 18.286 in Figma — a scaled instance, not reproduced.
   Held at 16 with the rest of the ramp. See A20. */

.thumbnail--outline { box-shadow: inset 0 0 0 1px var(--outline-softest); }

@media (forced-colors: active) {
  .thumbnail--outline { outline: 1px solid CanvasText; outline-offset: -1px; }
}

/* thumbnail=icon: a tinted disc, sized by its padding, not by
   --thumbnail-size. 10 + 24 + 10 = 44 for the "40x40" variant. */
.thumbnail--icon {
  box-sizing: content-box;
  width: var(--space-6);
  height: var(--space-6);
  padding: 10px;                      /* off-scale, D21 */
  border-radius: 100px;
  background-color: var(--surface-container-low);
  color: var(--text-on-surface);
}

.thumbnail--icon .icon { --icon-size: var(--space-5); }

/* Other sizes of thumbnail=icon. 20, 24, 32 are a plain disc of that
   size; 48, 56, 80 are 24 box + padding (52, 56, 80 overall). */
.thumbnail--icon.thumbnail--20,
.thumbnail--icon.thumbnail--24,
.thumbnail--icon.thumbnail--32 {
  box-sizing: border-box;
  width: var(--thumbnail-size);
  height: var(--thumbnail-size);
  padding: 0;
}
.thumbnail--icon.thumbnail--20 .icon { --icon-size: var(--space-3); }
.thumbnail--icon.thumbnail--24 .icon,
.thumbnail--icon.thumbnail--32 .icon { --icon-size: var(--space-4); }
.thumbnail--icon.thumbnail--56 { padding: var(--space-4); }
.thumbnail--icon.thumbnail--56 .icon,
.thumbnail--icon.thumbnail--80 .icon { --icon-size: var(--space-6); }

/* the 12 badge that clips to the bottom-right of a circular
   thumbnail. `surface` disc, glyph fills it edge to edge. */
.thumbnail-wrap { position: relative; display: inline-flex; }

.thumbnail-wrap__badge {
  position: absolute;
  right: -1px;
  bottom: -2px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--space-3);
  height: var(--space-3);
  border-radius: 100px;
  background-color: var(--surface);
}

.thumbnail-wrap__badge .icon { --icon-size: var(--space-3); }


/* ============================================================
   COMPONENT — imageContainer
   Figma: `imageContainer` set (14019:30367), page 15277:16590.
   Ratio = 2:1 | 16:9 | 1:1 | 9:16 | 5:4 | 20:8, state =
   default | loading | empty.

   The frame is a ratio box; the image fills it and crops. The
   empty state fills `#ebf4f9` — a raw hex with no token behind
   it (B11) — and centres `control_addImage_outline`. Loading is
   the skeleton fill.
   ============================================================ */

.image-container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  width: 100%;
  aspect-ratio: var(--image-ratio, 2 / 1);
}

.image-container > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-container--2-1  { --image-ratio: 2 / 1; }
.image-container--16-9 { --image-ratio: 16 / 9; }
.image-container--1-1  { --image-ratio: 1 / 1; }
.image-container--9-16 { --image-ratio: 9 / 16; }
.image-container--5-4  { --image-ratio: 5 / 4; }
.image-container--20-8 { --image-ratio: 20 / 8; }

.image-container.is-empty {
  background-color: #ebf4f9;          /* raw hex in Figma, B11 */
  color: var(--text-on-surface-variant);
}

.image-container.is-empty .icon { --icon-size: var(--space-6); }

.image-container.is-loading {
  background-color: var(--status-neutral-softest);
}


/* ============================================================
   COMPONENT — progressTracker
   Figma: page "Progress tracker / timeline" (15277:16599).
   Sets: `.vertical_dotStep` (50880:38291), `.vertical_iconStep`
   (50880:38314), `.vertical)numericStep` (50880:38360 — the
   stray `)` is Figma's, see C31), `.horizontalStep`
   (50880:38347), `.lineType` (50880:38378).

   States: Default | In Progress | Done (+ Warning on the icon
   and horizontal steps only — the dot step has no Warning,
   see B12).

   Marker colour is the whole story: `onSurfaceDim` before,
   `primary` at and after. In Progress adds a ring in
   #0098D8 at 15%, which is NOT --halo-focus (#01b3e9 at 50%).
   A second, undeclared halo colour — see B13.
   ============================================================ */

.progress-tracker {
  --track-marker: var(--status-neutral-base);
  --track-line: var(--status-neutral-soft);
  display: flex;
  flex-direction: column;
}

.progress-tracker--horizontal { flex-direction: row; }

.progress-tracker__step {
  display: flex;
  gap: 6px;                           /* off-scale, D22 */
  align-items: flex-start;
}

.progress-tracker__step.is-done { --track-marker: var(--primary); }
.progress-tracker__step.is-in-progress { --track-marker: var(--outline-brand-primary); }

/* the line runs grey until the step is Done, then turns primary */
.progress-tracker__step.is-done { --track-line: var(--primary); }

/* ---------- rail: marker stacked over the connecting line ---------- */

.progress-tracker__rail {
  display: flex;
  flex-direction: column;
  align-self: stretch;
  align-items: center;
  width: var(--space-4);
  padding-top: 3px;                   /* off-scale, D23 */
}

.progress-tracker__marker {
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  /* the symbol is a 12 box holding a 9 dot; the dot is what
     you see, so 9 is the honest width. */
  width: 9px;                         /* off-scale, D26 */
  height: 9px;
  margin-bottom: -1px;                /* the line tucks under it */
  border-radius: 100px;
  background-color: var(--track-marker);
}

/* In Progress wears a 3 ring at 15% — a second halo colour, B13 */
.progress-tracker__step.is-in-progress .progress-tracker__marker {
  box-shadow: 0 0 0 3px rgba(0, 152, 216, 0.15);
}

.progress-tracker__line {
  position: relative;
  z-index: 1;
  flex: 1 0 0;
  min-height: 0;
  width: 1px;
  background-color: var(--track-line);
}

.progress-tracker__line--thick { width: 2px; }

/* Dotted: 4 dots on a 10 pitch, not a dash pattern. Reproduced
   with a repeating radial gradient so it scales with the rail. */
.progress-tracker__line--dotted {
  width: var(--space-1);
  background-color: transparent;
  background-image: radial-gradient(
    circle at 2px 2px,
    var(--track-line) 2px,
    transparent 2px
  );
  background-size: var(--space-1) 10px;   /* 10 pitch, off-scale */
  background-repeat: repeat-y;
}

/* ---------- label column ---------- */

.progress-tracker__labels {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  gap: 1px;                           /* off-scale, D24 */
  align-self: stretch;
  min-width: 0;
  padding-bottom: 22px;               /* off-scale, D25 */
  word-break: break-word;
}

.progress-tracker__heading {
  /* Figma binds `[archive] caption/caption02_bolder` — an
     ARCHIVED style still live in this component (A21). Its
     metrics are 600 14/20, identical to body02_medium's box but
     a heavier weight, so body02_bolder is the honest match. */
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
}

.progress-tracker__label {
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

/* Icon and numeric steps (vertical): 12 gap, 24 rail, 20 marker,
   body01_bolder heading. The -1 content gap is not reproduced. */
.progress-tracker--icon .progress-tracker__step { gap: var(--space-3); }
.progress-tracker--icon .progress-tracker__rail { width: var(--space-6); }
.progress-tracker--icon .progress-tracker__marker { width: var(--space-5); height: var(--space-5); margin-bottom: 0; }
.progress-tracker--icon .progress-tracker__heading { font: var(--type-body-01-bolder); letter-spacing: 0; }

/* ---------- horizontal ---------- */

.progress-tracker--horizontal .progress-tracker__step {
  display: flex;
  flex: 1 0 0;
  gap: 0;
  align-items: center;
  isolation: isolate;
}

.progress-tracker--horizontal .progress-tracker__marker {
  z-index: 2;
  width: var(--space-5);
  height: var(--space-5);
  margin: 0 -2px 0 0;
}

.progress-tracker--horizontal
  .progress-tracker__step.is-in-progress .progress-tracker__marker,
.progress-tracker--horizontal
  .progress-tracker__step.is-done .progress-tracker__marker {
  width: var(--space-6);
  height: var(--space-6);
}

.progress-tracker--horizontal .progress-tracker__line {
  z-index: 1;
  flex: 1 0 0;
  width: auto;
  min-width: 0;
  height: 2px;
  border-radius: var(--space-2);
}

/* Done and Warning both draw a primary bar; only the marker
   differs. Warning's marker is the 20 `status_warningAlt_filled`
   glyph, so it stays at 20 while Done goes to 24 — see B14. */
.progress-tracker--horizontal
  .progress-tracker__step.is-warning .progress-tracker__line {
  background-color: var(--primary);
}


/* ============================================================
   COMPONENT — listView
   Figma: page "List ⏳" (15277:16591), section `listView`
   (15290:38185). Sets: `listView_default` (3084:171151, six
   densities), `listView_contained` (3845:243599, four states).

   listView_default is a full-bleed 375 row on
   `surfaceContainerLowest`. Density is NOT a content setting —
   it only moves two paddings, the row's top pad and the main
   content's bottom pad:

     superLoose  16 / 16   77 tall
     superDense  12 / 12   69
     multiLoose   8 /  8   61
     multiDense   4 /  4   53
     singleLoose  0 /  4   49
     singleDense  0 /  0   45

   Every one of those heights is 44 + the two pads + the 1
   divider, because the row is sized by the trailing icon's
   44 box (a 24 glyph in 10 of padding), not by its text.
   Drop the trailing element and the density scale stops
   meaning what its names say — see C32.

   listView_contained is a 343 card, radius 8, on the same
   fill, bordered `outline/softer`. Selected swaps the
   border to `outlineBrand/primary`; elevated adds
   `shadow_level_2`; disabled greys the primary text only.
   ============================================================ */

.list-view {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 375px;
  padding-top: var(--list-row-pad, var(--space-3));
  padding-right: 6px;                 /* off-scale, D27 */
  padding-left: var(--space-3);
  background-color: var(--surface-container-lowest);
}

.list-view--super-loose  { --list-row-pad: var(--space-4); --list-body-pad: var(--space-4); }
.list-view--super-dense  { --list-row-pad: var(--space-3); --list-body-pad: var(--space-3); }
.list-view--multi-loose  { --list-row-pad: var(--space-2); --list-body-pad: var(--space-2); }
.list-view--multi-dense  { --list-row-pad: var(--space-1); --list-body-pad: var(--space-1); }
.list-view--single-loose { --list-row-pad: var(--space-0); --list-body-pad: var(--space-1); }
.list-view--single-dense { --list-row-pad: var(--space-0); --list-body-pad: var(--space-0); }

/* The row carries two 8 spacers named "leftPadding -
   toBeRemoved" and "rightPadding - toBeRemoved" in Figma —
   authoring leftovers, still shipping. They make the real
   insets 20 left and 14 right, not the 12/6 the frame
   declares. Reproduced, because removing them shifts every
   row. See A22. */
.list-view__row {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0 var(--space-2);
}

.list-view__body {
  display: flex;
  flex: 1 0 0;
  gap: var(--space-2);
  align-items: center;
  min-width: 0;
  padding-bottom: var(--list-body-pad, var(--space-3));
}

.list-view__leading {
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  align-items: flex-start;
  justify-content: center;
  padding: var(--space-1);
}

.list-view__middle {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
  padding-left: var(--space-1);
}

.list-view__line {
  display: flex;
  gap: var(--space-6);
  align-items: center;
  width: 100%;
  min-height: var(--space-8);
}

.list-view__content {
  display: flex;
  flex: 1 0 0;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
  min-width: 0;
}

/* primaryData: four published sizes, body01/body02 in regular
   or bolder, per the component's own description. body02
   regular is the default the set ships. */
.list-view__primary {
  margin: 0;
  overflow: hidden;
  width: 100%;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.list-view__primary--body01          { font: var(--type-body-01-medium);  letter-spacing: 0; }
.list-view__primary--body01-bolder   { font: var(--type-body-01-bolder);  letter-spacing: 0; }
.list-view__primary--body02-bolder   { font: var(--type-body-02-bolder);  letter-spacing: 0; }
.list-view__primary--medium          { font: var(--type-body-02-medium);  letter-spacing: 0; }
.list-view__primary--dim             { color: var(--text-on-surface-dim); }

.list-view__secondary {
  margin: 0;
  width: 100%;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-variant);
}

.list-view__tertiary {
  margin: 0;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

/* ---------- trailing ---------- */

.list-view__trailing {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: flex-end;
}

.list-view__trailing-data {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
  max-width: 150px;                   /* off-scale, D28 */
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
  text-align: right;
}

/* the 44 box that actually sets the row height */
.list-view__trailing-icon {
  box-sizing: content-box;
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  /* a 24 box holding a 20 glyph, in 10 of padding: 44 square.
     This is what sets the row height at every density. */
  width: var(--space-6);
  height: var(--space-6);
  padding: 10px;                      /* off-scale, D29 */
  color: var(--text-on-surface-dim);
}

.list-view__trailing-icon .icon { --icon-size: var(--space-5); }
.list-view__trailing-icon--brand { color: var(--primary); }

/* ---------- divider ---------- */

.list-view__divider {
  width: 100%;
  height: 1px;
  padding-right: 6px;                 /* off-scale, D27 */
  background-color: var(--outline-softest);
}

/* ---------- disabled ---------- */

.list-view.is-disabled .list-view__primary,
.list-view.is-disabled .list-view__secondary {
  color: var(--text-on-surface-placeholder);
}

.list-view.is-disabled .list-view__trailing-data,
.list-view.is-disabled .list-view__trailing-icon {
  color: var(--text-on-surface-disabled);
}


/* ============================================================
   COMPONENT — listView_contained
   Figma: `listView_contained` (3845:243599).
   state = default | selected | disabled | elevated.
   ============================================================ */

.list-card {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
  justify-content: center;
  width: var(--space-container-width);
  padding: var(--space-3) 6px var(--space-3) var(--space-3);
  border-radius: var(--space-rounded-corner);
  background-color: var(--surface-container-lowest);
  box-shadow: inset 0 0 0 1px var(--list-card-stroke, var(--outline-softer));
}

.list-card__row {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  width: 100%;
}

.list-card.is-selected { --list-card-stroke: var(--outline-brand-primary); }

.list-card.is-elevated { box-shadow:
  inset 0 0 0 1px var(--outline-softer),
  var(--shadow-level-2); }

/* Disabled greys the primary text and nothing else — the
   thumbnail, the trailing data and the chevron all stay at
   full strength. It also stops the primary text truncating,
   because that one variant drops `flex: 1` for a fixed width.
   See B15. */
.list-card.is-disabled .list-card__primary {
  flex: 0 0 auto;
  color: var(--text-on-surface-placeholder);
  white-space: nowrap;
}

.list-card__primary {
  margin: 0;
  flex: 1 0 0;
  overflow: hidden;
  min-width: 0;
  font: var(--type-body-02-medium);
  letter-spacing: 0;
  color: var(--text-on-surface);
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (forced-colors: active) {
  .list-card { outline: 1px solid CanvasText; outline-offset: -1px; }
}


/* ═══════════════════════════════════════════════════════
   contentDisplayIcon
   Icon display wrapper — 5 sizes, 2 states.
   Default renders the icon at the given size.
   Loading replaces the icon with a shimmer circle.
   ═══════════════════════════════════════════════════════ */

.content-display-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: var(--cdi-size, var(--space-6));
  height: var(--cdi-size, var(--space-6));
}

.content-display-icon--x-large { --cdi-size: var(--space-8); }
.content-display-icon--large   { --cdi-size: var(--space-6); }
.content-display-icon--medium  { --cdi-size: var(--space-5); }
.content-display-icon--small   { --cdi-size: var(--space-4); }
.content-display-icon--x-small { --cdi-size: var(--space-3); }

.content-display-icon__icon {
  width: 100%;
  height: 100%;
  mask-size: contain;
  mask-repeat: no-repeat;
  mask-position: center;
  background-color: currentColor;
}

.content-display-icon.is-loading {
  position: relative;
  overflow: hidden;
  border-radius: 100px;
  background-color: var(--status-neutral-softest);
}

.content-display-icon.is-loading .content-display-icon__icon { display: none; }

.content-display-icon.is-loading::after {
  content: "";
  position: absolute;
  top: -78px;
  left: -264px;
  width: 248px; /* off-scale D11 */
  height: 350px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0) 0%,
    #ffffff 51.563%,
    rgba(255, 255, 255, 0) 100%
  );
  animation: shimmer-slide 1.5s ease-in-out infinite;
}


/* ═══════════════════════════════════════════════════════
   carousel indicator + dot
   Horizontal pagination dots for carousel/swipe views.
   Quantity is set by the number of .carousel-dot children.
   ═══════════════════════════════════════════════════════ */

.carousel-indicator {
  display: flex;
  gap: var(--space-1);
  align-items: flex-start;
  justify-content: center;
  width: var(--space-container-width);
  padding: var(--space-4) var(--space-6);
}

.carousel-dot {
  flex-shrink: 0;
  width: var(--space-1);
  height: var(--space-1);
  border-radius: 10px; /* off-scale */
  background-color: var(--text-on-surface);
  opacity: 0.4;
}

.carousel-dot.is-selected {
  width: var(--space-5);
  opacity: 1;
}


/* ═══════════════════════════════════════════════════════
   story progress bar
   Horizontal segmented progress bar for story views.
   Each segment is a .story-bar inside a .story-progress-bar.
   ═══════════════════════════════════════════════════════ */

.story-progress-bar {
  display: flex;
  gap: var(--space-1);
  align-items: flex-start;
  width: 100%;
  padding: var(--space-4);
}

.story-bar {
  flex: 1 0 0;
  height: var(--space-1);
  overflow: hidden;
  border-radius: var(--space-1);
  background-color: var(--status-neutral-soft);
}

.story-bar.is-done {
  background: linear-gradient(
    90deg,
    var(--primary-gradient-stop-one) 0%,
    var(--primary-gradient-stop-two) 100%
  );
}

.story-bar.is-active {
  position: relative;
  background-color: var(--status-neutral-softer);
}

.story-bar.is-active::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    90deg,
    var(--primary-gradient-stop-one) 0%,
    var(--primary-gradient-stop-two) 100%
  );
  transform-origin: left;
  animation: story-fill 5s linear forwards;
}

@keyframes story-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}


/* ═══════════════════════════════════════════════════════
   card tile
   Content card with thumbnail + text, 6 width sizes.
   Sizes 106–164 stack a 1:1 image over content.
   Size 327 (container-width) adds a border and 2:1 image.
   ═══════════════════════════════════════════════════════ */

.card-tile {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  overflow: hidden;
  width: var(--card-tile-width);
  border-radius: var(--space-rounded-corner);
}

.card-tile--106 { --card-tile-width: 106px; } /* off-scale */
.card-tile--116 { --card-tile-width: 116px; } /* off-scale */
.card-tile--128 { --card-tile-width: var(--space-32); }
.card-tile--156 { --card-tile-width: 156px; } /* off-scale */
.card-tile--164 { --card-tile-width: 164px; } /* off-scale */

.card-tile--327 {
  --card-tile-width: var(--space-container-width);
  gap: var(--space-2);
  padding-bottom: var(--space-5);
  background-color: var(--surface-container-lowest);
  box-shadow: inset 0 0 0 1px var(--outline-softer);
}

.card-tile__image-wrap {
  flex-shrink: 0;
  width: 100%;
  overflow: hidden;
}

.card-tile__image-wrap img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card-tile:not(.card-tile--327) .card-tile__image-wrap {
  aspect-ratio: 1 / 1;
}

.card-tile--327 .card-tile__image-wrap {
  aspect-ratio: 2 / 1;
}

.card-tile__content-container {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: flex-start;
  width: 100%;
}

.card-tile--327 .card-tile__content-container {
  gap: 0;
  padding: 0 var(--space-4);
}

.card-tile__content {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  align-items: flex-start;
  width: 100%;
}

.card-tile__primary {
  margin: 0;
  width: 100%;
  overflow: hidden;
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-tile__metadata {
  margin: 0;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

.card-tile__tag-wrap {
  padding-top: var(--space-1);
}


/* ═══════════════════════════════════════════════════════
   listView – notification trailing data
   Variant of the list trailing zone for notification rows.
   Unread shows bold text + red badge dot.
   Read shows regular text, no dot.
   ═══════════════════════════════════════════════════════ */

.list-view__trailing-notification {
  display: flex;
  flex-shrink: 0;
  gap: var(--space-2);
  align-items: center;
  justify-content: flex-end;
  padding-right: 10px; /* off-scale, same as trailing icon D29 */
}

.list-view__trailing-notification__text {
  margin: 0;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-variant);
  white-space: nowrap;
  text-align: right;
}

.list-view.is-unread .list-view__trailing-notification__text {
  font: var(--type-body-02-bolder);
}

.list-view__notification-badge {
  flex-shrink: 0;
  width: var(--space-2);
  height: var(--space-2);
  border-radius: 100px;
  background-color: var(--status-alert-base);
}


/* ═══════════════════════════════════════════════════════
   COMPONENT — link_button
   Figma: component set "link" (2657:28505), page 15273:48917.
   Variants: state (default | pressed) × size (large | medium |
   small) × leadingIcon (true | false) × trailingIcon (true | false).

   Inline link-style button. No fill, no border — text + optional
   icon in brand-primary colour.
   ═══════════════════════════════════════════════════════ */

.link-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border: 0;
  border-radius: var(--space-rounded-corner);
  background: none;
  cursor: pointer;
  color: var(--text-brand-primary);
  text-decoration: none;
}

.link-btn--lg {
  padding: var(--space-3) 0;
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
}

.link-btn--md {
  gap: var(--space-1);
  padding: var(--space-2) 0;
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
}

.link-btn--sm {
  gap: var(--space-1);
  padding: var(--space-2) 0;
  font: var(--type-body-03-bolder);
  letter-spacing: 0;
}

.link-btn .icon { flex-shrink: 0; }
.link-btn--lg .icon { --icon-size: var(--space-6); }
.link-btn--md .icon { --icon-size: var(--space-6); }
.link-btn--sm .icon { --icon-size: var(--space-4); }

.link-btn:active,
.link-btn.is-pressed { color: var(--status-informative-boldest); }


/* ═══════════════════════════════════════════════════════
   COMPONENT — icon_button
   Figma: component set "icon_button" (46238:35259),
   page 15273:48917.
   Variants: size (large | medium | small) × label (yes | no)
   × state (default | pressed) × floatingShadow (yes | no).

   Circular button with an icon; optionally a text label and a
   pill background.
   ═══════════════════════════════════════════════════════ */

.icon-btn {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  border: 0;
  border-radius: 48px;
  background: none;
  color: var(--text-on-surface);
  cursor: pointer;
}

.icon-btn--lg { padding: var(--space-4); }
.icon-btn--md { padding: var(--space-2); }
.icon-btn--sm { padding: var(--space-2); }

.icon-btn--lg .icon { --icon-size: var(--space-6); }
.icon-btn--md .icon { --icon-size: var(--space-6); }
.icon-btn--sm .icon { --icon-size: var(--space-5); }

.icon-btn.has-label {
  gap: var(--space-1);
  background-color: var(--surface-container-highest);
}

.icon-btn.has-label.icon-btn--lg {
  padding: var(--space-4) var(--space-6) var(--space-4) var(--space-4);
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
}

.icon-btn.has-label.icon-btn--md {
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-3);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
}

.icon-btn.has-label.icon-btn--sm {
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-3);
  font: var(--type-body-03-bolder);
  letter-spacing: 0;
}

.icon-btn.has-floating-shadow {
  filter: drop-shadow(0 12px 12px var(--illustration-grey-100));
}

.icon-btn:active,
.icon-btn.is-pressed { background-color: var(--surface-container-highest); }

.icon-btn.has-label.icon-btn--lg:active,
.icon-btn.has-label.icon-btn--lg.is-pressed { padding-right: var(--space-5); }


/* ═══════════════════════════════════════════════════════
   COMPONENT — slide_button
   Figma: component set "slideButton" (8439:6081),
   page 15273:48917.
   Variants: state (default | disabled | loading).

   Fixed-size pill with a draggable "slide bar" handle.
   263 × 52 — both off-scale.
   ═══════════════════════════════════════════════════════ */

.slide-btn {
  position: relative;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 263px;                        /* off-scale */
  height: 52px;                        /* off-scale */
  padding-left: var(--space-2);        /* label sits 4px right of centre in Figma */
  border: 0;
  border-radius: var(--space-8);
  background-image: linear-gradient(
    90deg,
    var(--primary-gradient-stop-one),
    var(--primary-gradient-stop-two)
  );
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
  color: var(--base-white-0);
  cursor: pointer;
}

.slide-btn__bar {
  position: absolute;
  top: 50%;
  left: var(--space-3);
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;                         /* off-scale */
  height: 36px;                        /* off-scale */
  border-radius: 18px;
  background-color: var(--surface-container-low);
}

.slide-btn__bar .icon { --icon-size: var(--space-5); }

.slide-btn:disabled,
.slide-btn.is-disabled {
  background-image: none;
  background-color: var(--surface-container-highest);
  color: var(--text-on-surface-disabled);
  cursor: not-allowed;
}

.slide-btn.is-disabled .slide-btn__bar {
  background-color: var(--surface-container-low);
}

.slide-btn.is-loading {
  padding: var(--space-3);
  pointer-events: none;
}

.slide-btn.is-loading .slide-btn__bar { display: none; }

.slide-btn__spinner {
  display: block;
  box-sizing: border-box;
  width: var(--space-6);
  height: var(--space-6);
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  animation: btn-spin 0.8s linear infinite;
}


/* ═══════════════════════════════════════════════════════
   COMPONENT — button_floating
   Figma: component set "button_floating" (9283:7125),
   page 15273:48917.
   Variants: t&c (yes | no) × buttonSliding (yes | no)
   × shadow (level_2 | reversed) × density × buttonGroup.

   Bottom-of-screen action container. Holds one or more buttons,
   optional slide-to-pay, optional T&C text, optional divider.
   ═══════════════════════════════════════════════════════ */

.btn-floating {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  width: 375px;
  background-color: var(--surface);
}

.btn-floating--level-2 {
  filter: drop-shadow(0 12px 12px var(--illustration-grey-100));
}

.btn-floating--reversed {
  box-shadow: var(--shadow-reversed);
}

.btn-floating--reversed::before {
  content: "";
  display: block;
  align-self: stretch;
  height: 1px;
  background-color: var(--outline-softest);
}

.btn-floating__action {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
  width: 100%;
  padding: var(--space-4) var(--space-6);
  background-color: var(--surface-container-lowest);
}

.btn-floating__action--centered { align-items: center; }

.btn-floating__action--tc { gap: var(--space-4); }

.btn-floating__tc {
  margin: 0;
  font: var(--type-metadata-01-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-variant);
}

.btn-floating__tc a {
  color: var(--text-brand-primary);
  text-decoration: none;
}


/* ═══════════════════════════════════════════════════════
   COMPONENT — buttonGroup (additions)
   Extends the existing .button-group rules above.
   Adds the link row and customSlot stack variant.
   ═══════════════════════════════════════════════════════ */

.button-group__link {
  align-self: center;
}

.button-group--custom-slot .button-group__row {
  flex-direction: row;
}

.button-group--custom-slot .button-group__row > * {
  flex: 1 0 0;
  min-width: 0;
}


/* ═══════════════════════════════════════════════════════
   COMPONENT — app-bar (additions)
   Extends the existing .app-bar rules above.

   Adds: scrolled state, 9 content types (appBar_content),
   4 leading actions, 5 trailing actions, progress bar,
   active search bar.
   ═══════════════════════════════════════════════════════ */

/* ---------- State: scrolled ---------- */

.app-bar--scrolled {
  box-shadow: var(--shadow-level-1);
}

/* ---------- Content type: large title ----------
   Types largeTitle and largeTitle_with_icon use H3-bolder
   in a row layout rather than the default column. */

.app-bar__content--lg {
  flex-direction: row;
  align-items: center;
  height: var(--space-10);
  padding: 0 var(--space-2);
}

.app-bar__content--lg-icon {
  flex-direction: row;
  align-items: center;
  height: 50px;                        /* off-scale */
  padding: 0 var(--space-2);
}

.app-bar__title--lg {
  font: var(--type-h3-bolder);
  letter-spacing: 0;
  white-space: nowrap;
}

/* ---------- Content type: with subheading ----------
   Applies to smallTitle_with_subheading, smallTitle_withDropdown,
   title_with_subheading, title_withDropdown. */

.app-bar__content--with-sub {
  gap: var(--space-1);
  padding: 0 var(--space-2);
}

.app-bar__subtitle {
  margin: 0;
  width: 100%;
  font: var(--type-body-02-regular);
  letter-spacing: 0;
  color: var(--text-on-surface-dim);
}

.app-bar__dropdown {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.app-bar__dropdown .app-bar__subtitle {
  width: auto;
  white-space: nowrap;
}

.app-bar__dropdown .icon { --icon-size: var(--space-5); color: var(--text-on-surface-dim); }

/* ---------- Content type: search bar ---------- */

.app-bar__content--search-bar {
  flex-direction: column;
  align-items: flex-start;
  padding: 0;
}

/* ---------- Trailing action: icon-with-label ---------- */

.app-bar__trailing-label {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border: 0;
  border-radius: 48px;
  background-color: var(--surface-container-highest);
  font: var(--type-body-02-bolder);
  letter-spacing: 0;
  color: var(--text-on-surface);
  cursor: pointer;
}

.app-bar__trailing-label .icon { --icon-size: var(--space-6); }

/* ---------- Trailing action: link ---------- */

.app-bar__trailing-link {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: var(--space-3) var(--space-2);
  border: 0;
  border-radius: var(--space-rounded-corner);
  background: none;
  font: var(--type-body-01-bolder);
  letter-spacing: 0;
  color: var(--text-brand-primary);
  cursor: pointer;
}

/* ---------- Progress bar ---------- */

.app-bar__progress {
  position: relative;
  width: 100%;
  height: var(--space-1);
}

.app-bar__progress-track {
  position: absolute;
  inset: 0;
  background-color: var(--status-neutral-base);
  opacity: 0.2;
}

.app-bar__progress-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background-color: var(--primary);
}

/* ---------- Divider ---------- */

.app-bar__divider {
  width: 100%;
  height: 1px;
  background-color: var(--outline-softest);
}

/* ---------- Search bar: active state ---------- */

.search-bar--active {
  color: var(--text-on-surface);
}

.search-bar > .icon:first-child { color: var(--text-on-surface); }

.search-bar__close {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  padding: var(--space-2);
  border: 0;
  border-radius: 48px;
  background: none;
  color: var(--text-on-surface-variant);
  cursor: pointer;
}

.search-bar__close .icon { --icon-size: var(--space-5); }
