/* برنگار fonts - generated by barnegar/tools/barnegar.py from core.tokens.json. Do not edit.
 * Barnegar 33.003 and Noto Naskh Arabic 2.021 and Noto Sans 2.015: SIL Open Font License 1.1; OFL.txt travels beside each family's files. */
@font-face {
  font-family: 'Barnegar';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/Barnegar/Barnegar-Light.woff2?v=61d22fb84193') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200F, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Barnegar';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/Barnegar/Barnegar-Regular.woff2?v=5057b50b016a') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200F, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Barnegar';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/Barnegar/Barnegar-Bold.woff2?v=aaa206ea98c7') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200F, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Barnegar';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/Barnegar/Barnegar-ExtraBold.woff2?v=a2474cefc052') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200F, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: 'Noto Naskh Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/NotoNaskhArabic/NotoNaskhArabic-Regular.woff2?v=abffcce5c78e') format('woff2');
}
@font-face {
  font-family: 'Noto Naskh Arabic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/NotoNaskhArabic/NotoNaskhArabic-Bold.woff2?v=fb5deeb4234a') format('woff2');
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/NotoSans/NotoSans-Light.woff2?v=4b5a2f487d7d') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/NotoSans/NotoSans-Regular.woff2?v=8a9fefad2b0d') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/NotoSans/NotoSans-Bold.woff2?v=e5b7ba50e7cf') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Noto Sans';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/NotoSans/NotoSans-ExtraBold.woff2?v=c7dc649a4dcc') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* برنگار core - generated by barnegar/tools/barnegar.py from system/foundation/tokens/core.tokens.json. Do not edit. */
:root {
  --font: 'Barnegar', 'Noto Naskh Arabic', 'Noto Sans', 'Tahoma', sans-serif;
  --font-mono: ui-monospace, 'Cascadia Mono', 'DejaVu Sans Mono', 'Consolas', monospace;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
  --s-2: 4px;
  --s-3: 8px;
  --s-4: 12px;
  --s-5: 16px;
  --s-6: 24px;
  --s-7: 32px;
  --s-8: 48px;
  --s-9: 64px;
  --r-ctl: 10px;
  --r-row: 12px;
  --r-card: 14px;
  --r-sheet: 22px;
  --r-thumb: 6px;
  --r-pill: 999px;
  --tap-min: 40px;
  --target-min: 24px;
  --ic: 22px;
  --ic-sm: 18px;
  --ic-xs: 15px;
  --focus-ring: 3px;
  --focus-gap: 2px;
  --measure: 640px;
  --measure-min: 360px;
  --empty-max: 240px;
  --row-min: 56px;
  --gereh: 8px;
  --gaz: 128px;
  --motion-press: 100ms;
  --motion-move: 160ms;
  --motion-pane: 330ms;
  --motion-max: 400ms;
  --motion-fade-reduced: 100ms;
  --motion-pending-show: 1000ms;
  --motion-pending-deadline: 10000ms;
  --motion-undo-window: 5000ms;
  --motion-undo-window-long: 15000ms;
  --motion-notice-time: 4000ms;
  --motion-arm-pause: 480ms;
  --motion-loader-turn: 1000ms;
  --motion-move-exit: 112ms;
  --motion-pane-exit: 231ms;
  --ease-enter: cubic-bezier(0.32, 0.72, 0, 1);
  --ease-exit: cubic-bezier(0.3, 0, 0.8, 0.15);
  --ease-state: cubic-bezier(0.2, 0, 0, 1);
  --media-scrim: rgba(10,14,22,.72);
  --on-scrim: #FFFFFF;
  --viewer-bg: #0A0A0C;
  --on-fill: #FFFFFF;
  --paper: #FFFFFF;
  --paper-line: #D9DDE3;
  --paper-line-strong: #9AA3B0;
  --ink-on-paper: #0F1B2D;
  --a0-from: #7A8CF0;
  --a0-to: #4D62D9;
  --a1-from: #F5A05E;
  --a1-to: #E06A3B;
  --a2-from: #54C08A;
  --a2-to: #1F9D62;
  --a3-from: #9B7BF5;
  --a3-to: #6C4DD9;
  --a4-from: #5EB8F5;
  --a4-to: #2A7FD4;
  --a5-from: #F07AA8;
  --a5-to: #D44A7E;
  --a6-from: #8B99B0;
  --a6-to: #5E6C84;
  --shadow-pressed: inset 0 1px 2px rgba(0,0,0,.12);
}
/* persian */
:lang(fa) {
  --font: 'Barnegar', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* arabic */
:lang(ar), :lang(arz) {
  --font: 'Noto Naskh Arabic', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1.25rem var(--font);
  --t-11b: 700 0.6875rem/1.25rem var(--font);
  --t-11x: 800 0.6875rem/1.25rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.5rem var(--font);
  --t-13b: 700 0.8125rem/1.5rem var(--font);
  --t-13x: 800 0.8125rem/1.5rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.75rem var(--font);
  --t-16b: 700 1rem/1.75rem var(--font);
  --t-16x: 800 1rem/1.75rem var(--font);
  --t-18: 400 1.125rem/2rem var(--font);
  --t-18b: 700 1.125rem/2rem var(--font);
  --t-18x: 800 1.125rem/2rem var(--font);
  --t-22: 400 1.375rem/2.25rem var(--font);
  --t-22b: 700 1.375rem/2.25rem var(--font);
  --t-22x: 800 1.375rem/2.25rem var(--font);
  --t-28: 400 1.75rem/3rem var(--font);
  --t-28b: 700 1.75rem/3rem var(--font);
  --t-28x: 800 1.75rem/3rem var(--font);
  --t-36: 400 2.25rem/3.75rem var(--font);
  --t-36b: 700 2.25rem/3.75rem var(--font);
  --t-36x: 800 2.25rem/3.75rem var(--font);
}
/* nastaliq */
:lang(ur) {
  --font: 'Noto Nastaliq Urdu', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/2.25rem var(--font);
  --t-11b: 700 0.6875rem/2.25rem var(--font);
  --t-11x: 800 0.6875rem/2.25rem var(--font);
  --t-12: 400 0.75rem/2.5rem var(--font);
  --t-12b: 700 0.75rem/2.5rem var(--font);
  --t-12x: 800 0.75rem/2.5rem var(--font);
  --t-13: 400 0.8125rem/2.75rem var(--font);
  --t-13b: 700 0.8125rem/2.75rem var(--font);
  --t-13x: 800 0.8125rem/2.75rem var(--font);
  --t-14: 400 0.875rem/3rem var(--font);
  --t-14b: 700 0.875rem/3rem var(--font);
  --t-14x: 800 0.875rem/3rem var(--font);
  --t-16: 400 1rem/3.25rem var(--font);
  --t-16b: 700 1rem/3.25rem var(--font);
  --t-16x: 800 1rem/3.25rem var(--font);
  --t-18: 400 1.125rem/3.75rem var(--font);
  --t-18b: 700 1.125rem/3.75rem var(--font);
  --t-18x: 800 1.125rem/3.75rem var(--font);
  --t-22: 400 1.375rem/4.5rem var(--font);
  --t-22b: 700 1.375rem/4.5rem var(--font);
  --t-22x: 800 1.375rem/4.5rem var(--font);
  --t-28: 400 1.75rem/5.75rem var(--font);
  --t-28b: 700 1.75rem/5.75rem var(--font);
  --t-28x: 800 1.75rem/5.75rem var(--font);
  --t-36: 400 2.25rem/7.25rem var(--font);
  --t-36b: 700 2.25rem/7.25rem var(--font);
  --t-36x: 800 2.25rem/7.25rem var(--font);
}
/* latin */
:lang(en), :lang(es), :lang(fr), :lang(pt), :lang(id), :lang(de), :lang(pcm), :lang(vi), :lang(ha), :lang(tr) {
  --font: 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* cyrillic */
:lang(ru) {
  --font: 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* devanagari */
:lang(hi), :lang(mr) {
  --font: 'Noto Sans Devanagari', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* bengali */
:lang(bn) {
  --font: 'Noto Sans Bengali', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3.25rem var(--font);
  --t-36b: 700 2.25rem/3.25rem var(--font);
  --t-36x: 800 2.25rem/3.25rem var(--font);
}
/* telugu */
:lang(te) {
  --font: 'Noto Sans Telugu', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3.25rem var(--font);
  --t-36b: 700 2.25rem/3.25rem var(--font);
  --t-36x: 800 2.25rem/3.25rem var(--font);
}
/* han */
:lang(zh) {
  --font: 'Noto Sans CJK SC', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* japanese */
:lang(ja) {
  --font: 'Noto Sans CJK JP', 'Noto Sans', sans-serif;
  --t-11: 400 0.6875rem/1rem var(--font);
  --t-11b: 700 0.6875rem/1rem var(--font);
  --t-11x: 800 0.6875rem/1rem var(--font);
  --t-12: 400 0.75rem/1.25rem var(--font);
  --t-12b: 700 0.75rem/1.25rem var(--font);
  --t-12x: 800 0.75rem/1.25rem var(--font);
  --t-13: 400 0.8125rem/1.25rem var(--font);
  --t-13b: 700 0.8125rem/1.25rem var(--font);
  --t-13x: 800 0.8125rem/1.25rem var(--font);
  --t-14: 400 0.875rem/1.5rem var(--font);
  --t-14b: 700 0.875rem/1.5rem var(--font);
  --t-14x: 800 0.875rem/1.5rem var(--font);
  --t-16: 400 1rem/1.5rem var(--font);
  --t-16b: 700 1rem/1.5rem var(--font);
  --t-16x: 800 1rem/1.5rem var(--font);
  --t-18: 400 1.125rem/1.75rem var(--font);
  --t-18b: 700 1.125rem/1.75rem var(--font);
  --t-18x: 800 1.125rem/1.75rem var(--font);
  --t-22: 400 1.375rem/2rem var(--font);
  --t-22b: 700 1.375rem/2rem var(--font);
  --t-22x: 800 1.375rem/2rem var(--font);
  --t-28: 400 1.75rem/2.5rem var(--font);
  --t-28b: 700 1.75rem/2.5rem var(--font);
  --t-28x: 800 1.75rem/2.5rem var(--font);
  --t-36: 400 2.25rem/3rem var(--font);
  --t-36b: 700 2.25rem/3rem var(--font);
  --t-36x: 800 2.25rem/3rem var(--font);
}
/* The base of a page built with برنگار: what the page itself has before any component - its ground, its ink and its
   type from the face, the element every sentence may hold (inline code: a word of code in a sentence, left to right
   inside right-to-left text, ژ۱۱), and the platform's own `hidden`, kept even on an element whose class sets its
   display. Like controls.css it is plain CSS that a product copies unchanged, and it comes before it. */
body { margin: 0; background: var(--bg); color: var(--ink); font: var(--t-14); }   /* on body, not the root: the root's size is every rem's */
code { font-family: var(--font-mono); font-size: inherit; overflow-wrap: break-word; unicode-bidi: isolate; }   /* its face only; it breaks inside itself only where it would leave its line - a name kept whole is a bng-phrase */
pre code { overflow-wrap: normal; }
[hidden] { display: none !important; }   /* the attribute wins over a class that sets display: a hidden part stays hidden */

/* On paper (system/foundation/print.md). The face's print block has already put the light roles in place, with the
   paper as the page's ground. What a part says by its fill - a filled button, a chosen day, a badge - prints as it is
   drawn, so a black-and-white printer keeps it as a shade, as the colour-blind view keeps it (ژ۱۳); nothing that
   floats over the work, or exists only to be pressed, is printed; nothing that is read as one is cut across sheets;
   and a link to another site says where it goes, since paper has no pointer. */
@media print {
  @page { margin: 16mm 14mm; }
  body { background: var(--bg); }
  [class*='bng-'] { print-color-adjust: exact; }
  .bng-btn--fab, .bng-undo, .bng-menu, .bng-tooltip, .bng-field__reveal, .bng-field__clear, .bng-codeblock__copy, .bng-skip { display: none !important; }
  .bng-row, .bng-card, .bng-notice, .bng-msg, .bng-stat, .bng-field, .bng-calendar, figure, tr, img, svg { break-inside: avoid; }
  h1, h2, h3, h4, .bng-head { break-after: avoid; }
  a[href^='http']:not([class*='bng-btn'])::after { content: ' (' attr(href) ')'; overflow-wrap: anywhere; }
}
/* برنگار's controls - the shared control grammar of every product built with برنگار: icon, focus ring,
   button, field, choice, toggle, the four-node loader, skeleton and the empty/failed state; the
   flow parts of strand five (ژ۲۱-ژ۲۵): page head, row, in-place editor, side panel, menu, undo bar
   and the one dialog, confirm; and the parts for data and choice: table, tabs, the Jalali calendar,
   count and tag, progress and steps, rating scale, file drop, avatar, tooltip and inline notice.

   This file is the source. A product's application takes a verbatim copy (plain CSS is valid SCSS, so
   a client that builds with a preprocessor keeps the copy as a partial), and the gallery renders from
   the same bytes, so a reference cannot quietly disagree with the product.
   That is why it is plain CSS with no nesting: the moment it needs a preprocessor, the copies stop
   being the same thing.

   These are classes rather than per-component styles because three of the rules bind to EVERY
   interactive element whatever drew it - the focus ring (signature S1), the disabled rendering and
   the hit-area minimum - and a rule that must be remembered per component is a rule that will be
   forgotten in one. Every value is a token of برنگار's foundation or of the product's face; each
   control's behaviour is the contract written beside it here, and its document in system/components/ (one per control)
   is what the gallery draws it from. */

/* ============================================================
   The icon, sized. This lives here rather than in the gallery's chrome because this sheet ships to
   the application, where there is no gallery chrome to fall back on - a control stylesheet that
   needs someone else's rule to size its own icons is not self-sufficient.
   ============================================================ */
.bng-ic { width: var(--ic); height: var(--ic); flex: none; display: block; color: inherit; }
.bng-ic--sm { width: var(--ic-sm); height: var(--ic-sm); }
.bng-ic--xs { width: var(--ic-xs); height: var(--ic-xs); }
.bng-ic--mirror:dir(rtl) { transform: scaleX(-1); }   /* direction is one attribute (ژ۱۱) */

/* ============================================================
   Focus. One ring, every control, no opt-out.

   Solid brand-ink, not a translucent tint: mix(brand 55%, transparent) composites to 2.0–2.6 against
   the grounds it lands on, short of the 3:1 WCAG 1.4.11 asks of a non-text indicator. Solid clears
   it everywhere (4.06 worst, surface-3 in dark). The 2px offset is what makes it work on a
   brand-filled control, where brand-on-brand would otherwise be 1.00.

   There is deliberately no :focus fallback. :focus-visible is what keeps a pointer click from
   leaving a ring behind, and a ring after every mouse click is why outlines got removed from the
   web in the first place.
   ============================================================ */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible,
.bng-focusable:focus-visible {
  outline: var(--focus-ring) solid var(--brand-ink);
  outline-offset: var(--focus-gap);
  z-index: 1;
}

/* ============================================================
   Disabled. One rule, and opacity is not the mechanism: a blanket opacity drags the label below AA
   and turns "not available now" into "unreadable". Focus still lands — a keyboard user has to be
   able to reach a disabled control to find out why it is disabled.
   ============================================================ */
.bng-ctl:disabled,
.bng-ctl[aria-disabled='true'] {
  background: var(--surface-2);
  color: var(--ink-3);
  border-color: var(--line);
  cursor: not-allowed;
  box-shadow: none;
}
.bng-ctl:disabled:hover,
.bng-ctl:disabled:active,
.bng-ctl[aria-disabled='true']:hover,
.bng-ctl[aria-disabled='true']:active {
  background: var(--surface-2);
  color: var(--ink-3);
}
.bng-ctl:disabled .bng-ic,
.bng-ctl[aria-disabled='true'] .bng-ic { color: var(--ink-3); }

/* Type: every control reads a type ROLE (--t-button, --t-label, --t-help ...), bound to a step by
   core.tokens.json `control-type` and rebindable by a product's face - a product with a 13px floor keeps
   these same controls. */

/* ============================================================
   Button. Five variants, one geometry.
   ============================================================ */
.bng-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-3);
  min-height: 36px;
  padding-block: 0;
  padding-inline: var(--s-5);
  border: 0;
  border-radius: var(--r-ctl);             /* a button is never a pill (signature ن۴) */
  min-inline-size: var(--tap-min);         /* a one-word label still makes a button the tap minimum wide */
  font: var(--t-button);
  cursor: pointer;
  user-select: none;
  text-align: center;
  transition: background-color var(--motion-press) var(--ease-state), color var(--motion-press) var(--ease-state);
}
/* A long label goes on to a second line rather than be cut or leave its frame: the act is never hidden (ADR-0019). */
.bng-btn:not(.bng-btn--icon) { padding-block: var(--s-2); }

/* The paint is 36 high, the hit box is 40. Padding the hit area rather than the paint is what keeps
   a 36px chip legal under the 40×40 minimum without drawing a fat button. */
.bng-btn::before {
  content: '';
  position: absolute;
  inset-block: -2px;
  inset-inline: 0;
  min-height: var(--tap-min);
}

.bng-btn--sm { min-height: 30px; padding-inline: var(--s-4); font: var(--t-button-sm); }
.bng-btn--block { display: flex; width: 100%; }
.bng-btn--rect { border-radius: var(--r-ctl); }

.bng-btn--filled { background: var(--brand-fill); color: var(--on-brand); }
.bng-btn--filled:hover:not(:disabled):not([aria-disabled='true']) { background: color-mix(in srgb, var(--brand-fill), var(--brand-strong)); }   /* halfway to pressed: a tenant's colour moves both */
.bng-btn--filled:active:not(:disabled):not([aria-disabled='true']) { background: var(--brand-strong); }

.bng-btn--chip { background: var(--brand-soft); color: var(--ink); }   /* a soft button: still a button, so r-ctl (ن۴) */
.bng-btn--chip .bng-ic { color: var(--brand-ink); }
.bng-btn--chip:hover:not(:disabled):not([aria-disabled='true']) { background: var(--brand-soft-2); }
.bng-btn--chip:active:not(:disabled):not([aria-disabled='true']) { background: var(--brand-soft-2); box-shadow: var(--shadow-pressed); }

.bng-btn--ghost { background: transparent; color: var(--ink-2); }
.bng-btn--ghost:hover:not(:disabled):not([aria-disabled='true']) { background: var(--surface-2); }
.bng-btn--ghost:active:not(:disabled):not([aria-disabled='true']) { background: var(--surface-3); }

/* The label is ink, not danger: a status colour on a tint of itself measures 3.5–4.3 whatever the
   percentage, because the tint moves with the text. The tint and the icon carry the meaning. */
.bng-btn--danger { background: color-mix(in srgb, var(--danger) 20%, transparent); color: var(--ink); }
.bng-btn--danger .bng-ic { color: var(--danger); }
.bng-btn--danger:hover:not(:disabled):not([aria-disabled='true']) { background: color-mix(in srgb, var(--danger) 28%, transparent); }
.bng-btn--danger:active:not(:disabled):not([aria-disabled='true']) { background: color-mix(in srgb, var(--danger) 34%, transparent); }

.bng-btn--icon {
  width: var(--tap-min);
  height: var(--tap-min);
  min-height: var(--tap-min);
  padding: 0;
  border-radius: var(--r-ctl);             /* one glyph is still a button: never a circle, never a row (ن۴) */
  background: transparent;
  color: var(--ink-3);
}
.bng-btn--icon::before { content: none; }
.bng-btn--icon:hover:not(:disabled):not([aria-disabled='true']) { background: var(--surface-2); }
.bng-btn--icon:active:not(:disabled):not([aria-disabled='true']) { background: var(--surface-3); }
.bng-btn--icon.bng-btn--primary { background: var(--brand-fill); color: var(--on-brand); }
.bng-btn--icon.bng-btn--primary:hover:not(:disabled):not([aria-disabled='true']) { background: color-mix(in srgb, var(--brand-fill), var(--brand-strong)); }
.bng-btn--icon.bng-btn--primary:active:not(:disabled):not([aria-disabled='true']) { background: var(--brand-strong); }

/* Pending keeps the size and the label and does not grey out: greying out says "unavailable",
   this says "working". */
.bng-btn[aria-busy='true'] { cursor: progress; pointer-events: none; }

/* ============================================================
   The loader: the four nodes (signature S2). A 16px ring in a faint currentColor with a node at each
   cardinal point; one node is lit at a time, clockwise, a quarter-turn per 250ms, for five turns - nothing
   moves longer than five seconds (WCAG 3 «No visual motion») - then it stands with its top node lit, and the
   product says in words that the wait goes on (ژ۸). Clockwise in both
   directions of text - it is a clock, not a reading order - so nothing here mirrors. One element,
   no children: the dim nodes are ::before, the lit node is ::after turning in four steps.
   ============================================================ */
.bng-spinner {
  position: relative;
  width: 16px;
  height: 16px;
  flex: none;
  border-radius: 50%;
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, currentColor 30%, transparent);
}
.bng-spinner::before,
.bng-spinner::after {
  content: '';
  position: absolute;
  inset: -1.75px;
  border-radius: 50%;
}
.bng-spinner::before {
  --n: color-mix(in srgb, currentColor 35%, transparent);
  background:
    radial-gradient(circle at 50% 2.5px, var(--n) 2px, transparent 2.4px),
    radial-gradient(circle at 50% calc(100% - 2.5px), var(--n) 2px, transparent 2.4px),
    radial-gradient(circle at 2.5px 50%, var(--n) 2px, transparent 2.4px),
    radial-gradient(circle at calc(100% - 2.5px) 50%, var(--n) 2px, transparent 2.4px);
}
.bng-spinner::after {
  background: radial-gradient(circle at 50% 2.5px, currentColor 2px, transparent 2.4px);
  animation: bng-nodes var(--motion-loader-turn) steps(4) 5;   /* five seconds, then still (WCAG 3 «No visual motion»): the wait is said in words */
}

@keyframes bng-nodes { to { transform: rotate(360deg); } }   /* bng: loader - the four-node ring (ن۲), the one thing that repeats */

/* حر-۲ «گره بستن», the Iranian face's motion: when the wait ends (data-state="done"), the ring closes into the core's
   shamseh grown from its four knots (m-1), once, in motion-move. It is drawn in the face's `frame` role, so the calm
   face, which has none, shows the plain ring and says the end in words, as every face does (ژ۸). */
.bng-spinner[data-state="done"]::before { background: none; }
.bng-spinner[data-state="done"]::after { inset: -4px; background: var(--frame, transparent); animation: bng-close var(--motion-move) var(--ease-enter) 1;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='none' stroke='currentColor' stroke-width='1'/%3E%3Cpath d='M12.00 1.00 L19.78 19.78 L1.00 12.00 L19.78 4.22 L12.00 23.00 L4.22 4.22 L23.00 12.00 L4.22 19.78 Z' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='none' stroke='currentColor' stroke-width='1'/%3E%3Cpath d='M12.00 1.00 L19.78 19.78 L1.00 12.00 L19.78 4.22 L12.00 23.00 L4.22 4.22 L23.00 12.00 L4.22 19.78 Z' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
@keyframes bng-close { from { opacity: 0; transform: rotate(-45deg) scale(.6); } }   /* bng: once, at the end of a wait (حر-۲) */

/* ============================================================
   Form field. The subscript line is reserved whether or not it has content — an error that appears
   out of nothing pushes the page down at the moment the person is reading it.
   ============================================================ */
.bng-field { display: flex; flex-direction: column; gap: var(--s-2); }
.bng-field__label { font: var(--t-label); color: var(--ink-2); }
.bng-field__required { color: var(--danger); margin-inline-start: var(--s-2); }

.bng-field__box {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 44px;
  padding-inline: var(--s-4);
  background: var(--surface-2);
  border: 1px solid var(--control-edge);   /* the edge that identifies the field (1.4.11): 3:1 */
  border-radius: var(--r-ctl);
  transition: border-color var(--motion-press) var(--ease-state);
}
.bng-field__box:hover { border-color: var(--ink-3); }   /* darker than rest */
.bng-field__box:focus-within { border-color: var(--brand-ink); }

/* The ring belongs to the box, so the bare input inside it must not draw one of its own. */
.bng-field__box:has(:focus-visible) { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }

.bng-field input,
.bng-field textarea,
.bng-field select {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  color: var(--ink);
  font: var(--t-value);
}
.bng-field input::placeholder,
.bng-field textarea::placeholder { color: var(--ink-3); }
.bng-field textarea { resize: vertical; padding-block: var(--s-4); max-height: 9lh; }
/* A select is the same box with the chevron of the icon set drawn at its inline end - the native
   arrow differs per platform, and a field must look like every other field (signature ن۳). */
.bng-field select { appearance: none; align-self: stretch; cursor: pointer; }
.bng-field__box--select { position: relative; }
.bng-field__box--select::after {
  content: '';
  position: absolute;
  inset-inline-end: 14px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -5px;
  border-right: 1.8px solid var(--ink-3);   /* bng: allow - a drawn chevron points down in either direction */
  border-bottom: 1.8px solid var(--ink-3);
  transform: rotate(45deg);
  pointer-events: none;
}
.bng-field__box--select select { padding-inline-end: 24px; }

.bng-field__sub {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-3);
  min-height: 1lh;
  font: var(--t-help);
  color: var(--ink-3);
}
.bng-field__sub > span:not(.bng-field__count) { min-inline-size: 0; overflow-wrap: anywhere; }   /* a long help line wraps (ADR-0019) */
/* Digits of one width (ن۷): Noto Naskh Arabic draws its Persian digits at one width already; tnum gives Noto Sans's
   Latin digits one width too, where a count is written in Latin digits. */
.bng-field__count { font-feature-settings: 'tnum'; flex: none; }
.bng-field__count--over { color: var(--danger); }

.bng-field--error .bng-field__box { border-color: var(--danger); box-shadow: inset 0 0 0 1px var(--danger); }   /* a heavier edge, not a colour alone (ژ۱۳); drawn inside, so nothing moves */
.bng-field--error .bng-field__sub { color: var(--danger); }

.bng-field--disabled .bng-field__box { background: var(--surface-2); border-color: var(--line); }
.bng-field--disabled input,
.bng-field--disabled textarea { color: var(--ink-3); cursor: not-allowed; }
.bng-field--disabled .bng-field__label { color: var(--ink-3); }

/* ============================================================
   Checkbox, radio and toggle. The drawn box is 18px; the hit box is 40. Drawing a small box and
   giving it a small hit area is the defect this geometry exists to prevent.
   ============================================================ */
.bng-choice {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--tap-min);
  cursor: pointer;
  font: var(--t-choice);
  color: var(--ink);
}
.bng-choice input { position: absolute; opacity: 0; width: 0; height: 0; }

.bng-choice__box {
  width: 18px;
  height: 18px;
  flex: none;
  display: grid;
  place-items: center;
  border: 1.5px solid var(--control-edge);   /* the box is the control: 3:1 (1.4.11) */
  border-radius: var(--r-thumb);
  background: var(--surface);
  color: transparent;
  transition: background-color var(--motion-press) var(--ease-state), border-color var(--motion-press) var(--ease-state);
}
.bng-choice--radio .bng-choice__box { border-radius: 50%; }
.bng-choice__dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

.bng-choice input:checked + .bng-choice__box {
  background: var(--brand-fill);
  border-color: var(--brand-fill);
  color: var(--on-brand);
}
.bng-choice input:focus-visible + .bng-choice__box { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }
.bng-choice input:disabled + .bng-choice__box { background: var(--surface-2); border-color: var(--line); }
.bng-choice:has(input:disabled) { color: var(--ink-3); cursor: not-allowed; }

.bng-toggle {
  display: inline-grid;
  grid-template-columns: minmax(0, max-content) auto;   /* the label's column may narrow, so a long label wraps beside its switch (ADR-0019) */
  align-items: center;
  max-inline-size: 100%;
  overflow-wrap: anywhere;
  gap: var(--s-3);
  min-height: var(--tap-min);
  cursor: pointer;
  font: var(--t-choice);
  color: var(--ink);
}
.bng-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }

.bng-toggle__track {
  position: relative;
  width: 40px;
  height: 24px;
  flex: none;
  border-radius: var(--r-pill);
  /* Off is a `control-edge` track under a `surface` knob: one measured pair (3:1, symmetric) proves
     both the track against the page and the knob against the track. */
  background: var(--control-edge);
  transition: background-color var(--motion-press) var(--ease-state);
}
.bng-toggle__knob {
  position: absolute;
  inset-block-start: 3px;
  inset-inline-start: 3px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  transition: transform var(--motion-move) var(--ease-enter);
}
.bng-toggle input:checked + .bng-toggle__track { background: var(--brand-fill); }
.bng-toggle input:checked + .bng-toggle__track .bng-toggle__knob { transform: translateX(16px); }
.bng-toggle input:checked + .bng-toggle__track .bng-toggle__knob:dir(rtl) { transform: translateX(-16px); }
.bng-toggle input:focus-visible + .bng-toggle__track { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }
.bng-toggle input:disabled + .bng-toggle__track { background: var(--surface-2); }
.bng-toggle input:disabled + .bng-toggle__track .bng-toggle__knob { background: var(--surface-3); box-shadow: none; }

/* Pending sits at the track's inline-end: the knob has already moved — a toggle that does not move
   when pressed reads as broken — and this says the server has not caught up yet. */
.bng-toggle__pending { position: absolute; inset-inline-end: -22px; inset-block-start: 4px; color: var(--ink-3); }
.bng-toggle:has(.bng-toggle__pending) { padding-inline-end: 24px; }   /* the room the pending nodes stand in, inside the switch's own box (ADR-0019) */


/* ============================================================
   The four surface faces of 08-application-states.md. Three of them share one anatomy and differ
   only in tint and copy; the fourth is the list with its content removed.
   ============================================================ */
.bng-state {
  margin: auto; display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: var(--s-3); padding: var(--s-6); max-width: 320px;
}
.bng-state__circle {
  width: 120px; height: 120px; border-radius: 50%; display: grid; place-items: center;
  background: var(--brand-soft); color: var(--brand-ink); margin-bottom: var(--s-3);
}
.bng-state__circle .bng-ic { width: 52px; height: 52px; }
/* A no-match is not a problem, so it is not tinted like one. */
.bng-state__circle--no-match { background: var(--surface-3); color: var(--ink-3); }
.bng-state__circle--failed { background: color-mix(in srgb, var(--danger) 18%, transparent); color: var(--danger); }
.bng-state__title { font: var(--t-state-title); color: var(--ink-2); margin: 0; }
.bng-state__body { font: var(--t-state-body); color: var(--ink-3); margin: 0 0 var(--s-3); }

/* The skeleton is the list with its content removed, so its rows are the list's: the face's own list
   row when it declares one (`row-h`, `avatar-list`), the shared row otherwise. */
.bng-skeleton { display: flex; flex-direction: column; width: 100%; padding: var(--s-2); }
.bng-skeleton__row { height: var(--row-h, var(--row-min)); display: flex; align-items: center; gap: var(--s-4); padding-inline: var(--s-4); }
.bng-skeleton__avatar { width: var(--avatar-list, 40px); height: var(--avatar-list, 40px); border-radius: 50%; background: var(--surface-2); flex: none; }
.bng-skeleton__lines { flex: 1; display: flex; flex-direction: column; gap: var(--s-3); }
.bng-skeleton__bar { height: 10px; border-radius: var(--r-pill); background: var(--surface-2); width: 62%; }
.bng-skeleton__bar--title { width: 38%; }
/* Still: only the loader loops (ن۹, ژ۳۰). A still skeleton still says "not yet", which is the whole job. */

/* ============================================================
   Reduced motion. The loops stop; the loader stands still with its top node lit, which reads as
   waiting rather than as a decoration.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .bng-spinner::after, .bng-spinner[data-state="done"]::after { animation: none; }
  .bng-tree__row .bng-ic, .bng-accordion__item > summary .bng-ic { transition: none; }
  /* ن۹: colour changes stay, travel stops. */
  .bng-toggle__knob { transition: none; }
}


/* ============================================================
   Flow (genome strand five). These are the parts every product builds its pages from, so a page
   header or a row is not drawn by hand per screen: drawn by hand, back buttons drift to the far end
   and the same data comes out in two layouts.
   ============================================================ */

/* The page head (ژ۲۲, ژ۲۳): back at the inline START, then the title, then the page's actions right
   after the title - never flung to the far edge of a wide pane (ژ۲۵). The back glyph is the mirrored
   arrow; on a wide screen a page that is a pane of its screen has no back at all. */
.bng-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 64px;
  padding-inline: var(--s-5);
}
.bng-head__back { flex: none; margin-inline-start: calc(var(--s-3) * -1); }   /* a bng-btn--icon; its glyph is the mirrored arrow */
/* A title goes to two lines and is then cut with «…» at its logical end; the whole title is still its accessible name, and
   the web core gives it as a tooltip too (ADR-0019). */
.bng-head__title { margin-block: -0.2em; margin-inline: 0; font: var(--t-page-title); color: var(--ink); min-width: 0; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  padding-block: 0.2em; }   /* room inside the cut for the marks above and below a Persian line, which reach past its line box */
.bng-head__actions { display: flex; align-items: center; gap: var(--s-2); margin-inline-start: var(--s-3); }

/* One row for every list, setting and fact (ژ۴). The line the person came for is the title: a
   setting's NAME (its current value or control sits at the end), a fact's VALUE (its label is the
   caption under it), a person's or a chat's name. One anatomy, one height, one hover. */
.bng-row {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  min-height: var(--row-min);
  padding-block: var(--s-2);
  padding-inline: var(--s-4);
  border-radius: var(--r-row);
  color: var(--ink);
  text-align: start;
  background: transparent;
  border: 0;
  box-sizing: border-box;   /* a row that is an <a> or a <div> is as wide as its column, its padding inside */
  width: 100%;
  font: var(--t-row-title);
  transition: background-color var(--motion-press) var(--ease-state);
}
.bng-row__lead { flex: none; display: grid; place-items: center; min-inline-size: var(--ic); color: var(--ink-3); }   /* an icon, or an avatar as wide as itself */
.bng-row__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--s-2); }
.bng-row__title { font: var(--t-row-title); color: var(--ink); overflow-wrap: anywhere;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden;
  padding-block: 0.2em; margin-block: -0.2em; }   /* two lines, then «…» (ADR-0019); room for the Persian marks inside the cut */
.bng-row__caption { font: var(--t-row-caption); color: var(--ink-3); overflow-wrap: anywhere; }
.bng-row__end { flex: 0 1 auto; min-inline-size: 0; max-inline-size: 50%; display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: var(--s-2); color: var(--ink-2); font: var(--t-row-end); overflow-wrap: anywhere; }   /* a long end wraps within half the row (ADR-0019) */
button.bng-row, a.bng-row, .bng-row--action { cursor: pointer; }
button.bng-row:hover, a.bng-row:hover, .bng-row--action:hover { background: var(--surface-2); }
button.bng-row:active, a.bng-row:active, .bng-row--action:active { background: var(--surface-3); }
.bng-row[aria-current='page'], .bng-row[aria-selected='true'] { background: var(--brand-soft); }
/* the tint is a hue a grey screen loses (ژ۱۳): the title's weight says it too */
.bng-row[aria-current='page'] .bng-row__title, .bng-row[aria-selected='true'] .bng-row__title { font-weight: 700; }
/* ink-3 on brand-soft falls to 3.3 in dark; the caption steps up to ink-2, measured on brand-soft. */
.bng-row[aria-current='page'] .bng-row__caption, .bng-row[aria-selected='true'] .bng-row__caption { color: var(--ink-2); }

/* In place (ژ۲۲): a fact is edited on its own row - the row becomes the field with save and cancel
   beside it, focus moves into the field, Escape cancels, Enter saves, and focus returns to the row. */
.bng-row--editing { background: var(--surface-2); }
.bng-row--editing .bng-field { flex: 1; min-width: 0; }

/* The side panel (ژ۲۲, ژ۲۵): detail beside the list, part of the page - non-modal, never an overlay.
   It arrives from the inline end over `pane` and leaves faster; it takes focus on open and Escape
   returns focus to what opened it. */
.bng-panel {
  inline-size: var(--panel-w, 360px);
  max-inline-size: 100%;
  flex: none;
  background: var(--surface);
  border-inline-start: 1px solid var(--line);
  overflow: auto;
  transition: transform var(--motion-pane) var(--ease-enter), opacity var(--motion-pane) var(--ease-enter);
}
/* Open and closed differ only in transform, opacity and flow. Closed, the panel leaves the flow at
   once (its parent is the positioning context) and travels out by transform, so its neighbour takes
   the width in ONE reflow at the moment of the press - the person's own input, which is not a shift
   under the reader - and no width is ever animated. Opening does the same in reverse: the width is
   reserved in the press's frame and the panel travels in. A product toggles data-state, not [hidden],
   so the move runs both ways and reverses mid-way (ن۹); visibility follows the travel so a closed
   panel takes no focus. */
.bng-panel[data-state='closed'] {
  position: absolute; inset-block: 0; inset-inline-end: 0;
  transform: translateX(100%); opacity: 0; visibility: hidden;
  transition: transform var(--motion-pane-exit) var(--ease-exit), opacity var(--motion-pane-exit) var(--ease-exit), visibility var(--motion-pane-exit) step-end;
}
.bng-panel[data-state='closed']:dir(rtl) { transform: translateX(-100%); }

/* A choice of two or three values, inline in its row (ژ۲۱): a radio group drawn as joined segments.
   Four or more values are a select. */
.bng-segmented { display: inline-flex; padding: var(--s-2); gap: var(--s-2); border-radius: var(--r-ctl); background: var(--surface-2); }
.bng-segmented__opt { position: relative; }
.bng-segmented__opt::before { content: ''; position: absolute; inset-inline: 0; inset-block: calc((32px - var(--tap-min)) / 2); }   /* the paint is 32, the hit box the tap minimum */
.bng-segmented__opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.bng-segmented__opt span {
  display: inline-flex; align-items: center; min-height: 32px; padding-inline: var(--s-4);
  border-radius: var(--r-ctl); font: var(--t-segment); color: var(--ink-2); cursor: pointer;
  transition: background-color var(--motion-press) var(--ease-state), color var(--motion-press) var(--ease-state);
}
/* The chosen option is told by its edge and its weight, not by a fill alone: surface on surface-2 is
   barely a step in dark, so the option takes the measured control edge (3:1 on every ground) and bold. */
.bng-segmented__opt input:checked + span { background: var(--surface); color: var(--ink); box-shadow: inset 0 0 0 1px var(--control-edge); font-weight: 700; }
.bng-segmented__opt input:focus-visible + span { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }

/* A menu of choices - the first of the four overlays ژ۲۲ allows, and nothing to read in it. It grows
   from what opened it (set transform-origin there) and is replaced, never stacked. */
.bng-menu {
  min-inline-size: 200px;
  max-inline-size: 320px;
  padding: var(--s-2);
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  transition: transform var(--motion-move) var(--ease-enter), opacity var(--motion-move) var(--ease-enter);
}
.bng-menu[popover] { border: 0; color: var(--ink); }   /* the web core opens it as a popover (ADR-0026): not the platform's frame */
.bng-menu__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  inline-size: 100%;
  min-height: var(--tap-min);
  padding-inline: var(--s-3);
  border: 0;
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ink);
  font: var(--t-menu-item);
  text-align: start;
  cursor: pointer;
}
.bng-menu__item .bng-ic { color: var(--ink-3); }
.bng-menu__item:hover { background: var(--surface-2); }
.bng-menu__item:active { background: var(--surface-3); }
.bng-menu__item--danger, .bng-menu__item--danger .bng-ic { color: var(--danger); }
.bng-menu__sep { height: 1px; margin-block: var(--s-2); background: var(--line); border: 0; }

/* On a phone, a menu of choices rises from the bottom edge as a sheet - still only choices (ژ۲۲).
   After .bng-menu, which it overrides. */
.bng-menu--sheet {
  max-inline-size: none; inline-size: 100%; border-end-start-radius: 0; border-end-end-radius: 0;
  border-start-start-radius: var(--r-sheet); border-start-end-radius: var(--r-sheet);
  padding-block: var(--s-3) var(--s-6);
}

/* Skip link (ژ۱۳; WCAG 2.4.1): the first stop of the keyboard on a page, to the page's main part - the person who walks
   by Tab does not walk the whole bar and menu first. It is seen only while it has the focus. */
.bng-skip { position: absolute; z-index: 60; inset-block-start: var(--s-3); inset-inline-start: var(--s-3);
  padding: var(--s-3) var(--s-4); border-radius: var(--r-ctl); background: var(--brand-fill); color: var(--on-brand); font: var(--t-14b); }
.bng-skip:not(:focus) { clip-path: inset(50%); inline-size: 1px; block-size: 1px; overflow: hidden; white-space: nowrap; padding: 0; }

/* Undo (ژ۱۹): a reversible act is held until the server commits it, or done at once when it has an
   exact reverse, and this bar offers it back for a stated time. It
   is not an overlay - nothing waits behind it - and it says what happened in words (ن۱۰). */
.bng-undo {
  display: inline-flex;
  align-items: center;
  gap: var(--s-4);
  min-height: 48px;
  max-inline-size: 100%;
  box-sizing: border-box;
  padding-inline: var(--s-4) var(--s-2);
  border-radius: var(--r-card);
  background: var(--ink);
  color: var(--surface);
  font: var(--t-notice);
  box-shadow: var(--shadow-2);
  transition: transform var(--motion-move) var(--ease-enter), opacity var(--motion-move) var(--ease-enter);
}
.bng-undo .bng-btn { color: var(--surface); }
.bng-undo .bng-btn:hover { background: color-mix(in srgb, var(--surface) 14%, transparent); }
/* The web core's bar (<bng-undo>): one in the page, fixed at the foot of the window and as wide as it, so the bar sits in its
   middle and never takes a click from what is behind it (`--undo-lift` raises it above a floating button); it comes in on the move time and goes out on it. */
bng-undo { position: fixed; inset-inline: 0; inset-block-end: calc(var(--s-4) + var(--undo-lift, 0px)); z-index: 20; display: flex; justify-content: center; padding-inline: var(--s-4); pointer-events: none; }
bng-undo > .bng-undo { pointer-events: auto; opacity: 0; transform: translateY(var(--s-3)); }
bng-undo > .bng-undo[data-shown] { opacity: 1; transform: none; }

/* An irreversible act confirmed in place (ژ۱۹): the first press arms the control - it says what
   will happen - and only a second press commits; leaving it disarms it. */
/* `surface` on `danger`: danger is walked to 4.5 against surface in each mode, and the pair is symmetric. */
.bng-btn--armed { background: var(--danger); color: var(--surface); }
.bng-menu__item.bng-btn--armed { background: var(--danger); color: var(--surface); }   /* a menu item armed in place (armed.md): the same fill, its own shape */
.bng-btn--armed .bng-ic { color: var(--surface); }

/* Confirm - the one dialog (ژ۲۲): only for what cannot be confirmed in place or undone, or an
   identity re-check. A <dialog> opened with showModal(), so the page behind is inert. The buttons sit
   together at the end, cancel first, the act last. */
.bng-confirm {
  inline-size: min(400px, calc(100vw - 32px));
  padding: var(--s-6);
  border: 0;
  border-radius: var(--r-sheet);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-2);
}
.bng-confirm::backdrop { background: var(--scrim); }
.bng-confirm__title { margin: 0 0 var(--s-2); font: var(--t-confirm-title); }
.bng-confirm__body { margin: 0 0 var(--s-6); font: var(--t-confirm-body); color: var(--ink-2); }
.bng-confirm__actions { display: flex; justify-content: flex-end; gap: var(--s-2); }

/* The reading measure (ژ۲۵): no line of prose is wider, whatever the screen. */
.bng-measure { max-inline-size: var(--measure); }
/* The frame of the Iranian face (internal/atlas/register.md, section 4, h1; ADR-0011): a jadval of one to three hairlines
   round a text, their number its weight, and a tasmeh between the text and its margin - a band two gereh high of the
   core's octagon chain (m-1), only the tiles' inner lines seen. Both are drawn in the face's `frame` role; a face
   without one - the calm face - draws neither, and the text stands as it would. The ornament degree is the page's:
   plain (the default) lays the tasmeh down to one jadval line, adorned draws the chain, illuminated only on an
   occasion page (m-10). */
.bng-jadval { padding: var(--gereh, 8px); box-shadow: 0 0 0 1px var(--frame, transparent); }
.bng-jadval--2 { box-shadow: 0 0 0 1px var(--frame, transparent), 0 0 0 calc(var(--gereh, 8px) / 2) var(--bg), 0 0 0 calc(var(--gereh, 8px) / 2 + 1px) var(--frame, transparent); }
.bng-jadval--3 { box-shadow: 0 0 0 1px var(--frame, transparent), 0 0 0 calc(var(--gereh, 8px) / 2) var(--bg), 0 0 0 calc(var(--gereh, 8px) / 2 + 1px) var(--frame, transparent),
  0 0 0 var(--gereh, 8px) var(--bg), 0 0 0 calc(var(--gereh, 8px) + 1px) var(--frame, transparent); }
.bng-tasmeh { block-size: 1px; background: var(--frame, transparent); }
:root:is([data-ornament="adorned"], [data-ornament="illuminated"]) .bng-tasmeh, .bng-tasmeh--adorned {
  block-size: calc(2 * var(--gereh, 8px)); background: var(--frame, transparent);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4.686 0.5 L11.314 0.5 L15.5 4.686 L15.5 11.314 L11.314 15.5 L4.686 15.5 L0.5 11.314 L0.5 4.686 Z' fill='none' stroke='currentColor' stroke-width='1'/%3E%3C/svg%3E") repeat-x center / calc(2 * var(--gereh, 8px)) 100%; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'%3E%3Cpath d='M4.686 0.5 L11.314 0.5 L15.5 4.686 L15.5 11.314 L11.314 15.5 L4.686 15.5 L0.5 11.314 L0.5 4.686 Z' fill='none' stroke='currentColor' stroke-width='1'/%3E%3C/svg%3E") repeat-x center / calc(2 * var(--gereh, 8px)) 100%; }
/* The opening and the close of a long work (h1, ad-7, ad-8): a sarloh carries the title over a ground of the core's
   eight-point shamseh {8/3} grown from the ring's four knots (m-1), and a taraqimeh closes the work with its maker,
   date and version beside the same shamseh, closed (h-2). Never {8/2}, two squares, which is the hizb mark. */
.bng-sarloh { padding: calc(2 * var(--gereh, 8px)) var(--gereh, 8px); box-shadow: inset 0 calc(-1 * var(--gereh, 8px)) 0 -7px var(--frame, transparent); }
.bng-sarloh::before, .bng-taraqimeh::before { content: ""; display: block; inline-size: calc(3 * var(--gereh, 8px)); block-size: calc(3 * var(--gereh, 8px));
  background: var(--frame, transparent); -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='none' stroke='currentColor' stroke-width='1'/%3E%3Cpath d='M12.00 1.00 L19.78 19.78 L1.00 12.00 L19.78 4.22 L12.00 23.00 L4.22 4.22 L23.00 12.00 L4.22 19.78 Z' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='11' fill='none' stroke='currentColor' stroke-width='1'/%3E%3Cpath d='M12.00 1.00 L19.78 19.78 L1.00 12.00 L19.78 4.22 L12.00 23.00 L4.22 4.22 L23.00 12.00 L4.22 19.78 Z' fill='none' stroke='currentColor' stroke-width='1.2' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat; }
.bng-sarloh::before { margin-block-end: var(--gereh, 8px); }
.bng-taraqimeh { display: flex; align-items: center; gap: var(--gereh, 8px); font: var(--t-12); color: var(--ink-2); }
/* قر-۲ «بهتر»: a phrase goes to the next line whole when it fits there, and breaks inside itself only when it is
   wider than the line - so a title, a button or a notice breaks at the end of a phrase before inside one */
.bng-phrase { display: inline-block; max-inline-size: 100%; }


/* ============================================================
   Data and choice (the parts the products' onboarding pages ask for): table, tabs, the Jalali calendar,
   count badge and tag, progress and steps, rating scale, file drop, avatar, tooltip and inline notice.
   ============================================================ */

/* A table: data whose columns are compared (a list of like things is rows). The head stays in view as the body
   scrolls; a number column ends where its digits end, in Persian digits of one width (ن۷). On a narrow screen the
   wrap scrolls sideways, and takes focus so a keyboard can scroll it too. */
.bng-table-wrap { max-inline-size: 100%; overflow-x: auto; }
.bng-table { inline-size: 100%; border-collapse: collapse; font: var(--t-table-cell); color: var(--ink); }
.bng-table__caption { caption-side: top; text-align: start; padding-block-end: var(--s-2); font: var(--t-label); color: var(--ink-2); }
.bng-table th {
  position: sticky;
  inset-block-start: 0;
  padding-block: var(--s-2);
  padding-inline: var(--s-3);
  border-block-end: 1px solid var(--line-strong);
  background: var(--surface);
  font: var(--t-table-head);
  color: var(--ink-2);
  text-align: start;
  vertical-align: bottom;
}
.bng-table td { padding-block: var(--s-2); padding-inline: var(--s-3); border-block-end: 1px solid var(--line); vertical-align: top; }
.bng-table__num { text-align: end; font-feature-settings: 'tnum'; white-space: nowrap; }
.bng-table tbody tr { transition: background-color var(--motion-press) var(--ease-state); }
.bng-table tbody tr:hover { background: var(--surface-2); }
.bng-table tbody tr[aria-selected='true'] { background: var(--brand-soft); font-weight: 700; }   /* weight as well as tint: grey keeps it (ژ۱۳) */
.bng-table__sort {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: var(--tap-min);   /* a control, not a small target: the tap minimum (size.tap-min) */
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.bng-table__sort .bng-ic { color: var(--ink-3); }

/* Tabs: views of one thing, side by side (ژ۲۱). The chosen tab is told by its ink and a bar under it - never by a
   weight, which would move its neighbours (ژ۲۴). More tabs than fit scroll, they do not wrap. */
.bng-tabs { display: flex; gap: var(--s-2); box-shadow: inset 0 -1px 0 var(--line); overflow-x: auto; }   /* the line inside, so the chosen tab's bar covers it without overflowing downwards */
.bng-tabs__tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: var(--tap-min);
  padding-inline: var(--s-4);
  border: 0;
  border-radius: var(--r-ctl) var(--r-ctl) 0 0;
  background: transparent;
  color: var(--ink-2);
  font: var(--t-tab);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--motion-press) var(--ease-state), color var(--motion-press) var(--ease-state);
}
.bng-tabs__tab:hover { background: var(--surface-2); color: var(--ink); }
.bng-tabs__tab:focus-visible { outline-offset: calc(var(--focus-ring) * -1); }   /* inside: the row scrolls, and a ring outside the first and last tab would be cut by it */
.bng-tabs__tab[aria-selected='true'] { color: var(--ink); }
.bng-tabs__tab[aria-selected='true']::after {
  content: '';
  position: absolute;
  inset-inline: var(--s-2);
  inset-block-end: 0;
  block-size: 3px;
  border-radius: var(--r-pill);
  background: var(--brand-ink);
}

/* The Jalali calendar: a menu of days that opens from a date field (ژ۲۲, the first overlay), Saturday first. A day is a
   control (r-ctl, ن۴); today is framed, the chosen day filled. */
bng-date { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-2); }   /* the web core's date: its field, then its calendar */
bng-date > bng-field { align-self: stretch; }
.bng-calendar {
  display: inline-grid;
  max-inline-size: 100%;
  box-sizing: border-box;
  gap: var(--s-2);
  padding: var(--s-3);
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}
.bng-calendar__head { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); font: var(--t-row-title); color: var(--ink); }
.bng-calendar__grid { display: grid; grid-template-columns: repeat(7, minmax(var(--target-min), var(--tap-min))); gap: var(--s-2); }   /* a day narrows toward target-min only where seven of tap-min do not fit; its height stays tap-min */
/* Under 360 the calendar would be wider than the screen (WCAG 1.4.10): the days close their gaps and the edge narrows,
   so seven days of tap-min and the edge are 288, the width of a 320 screen inside its 16 margins. A day never goes
   under tap-min. */
@media (width < 360px) {
  .bng-calendar { padding-inline: var(--s-2); }
  .bng-calendar__grid { column-gap: 0; }
}
.bng-calendar__weekday { display: grid; place-items: center; min-block-size: var(--target-min); font: var(--t-calendar-head); color: var(--ink-3); }
.bng-calendar__day {
  display: grid;
  place-items: center;
  inline-size: 100%;
  block-size: var(--tap-min);
  padding: 0;
  border: 0;
  border-radius: var(--r-ctl);
  background: transparent;
  color: var(--ink);
  font: var(--t-calendar-day);
  font-feature-settings: 'tnum';
  cursor: pointer;
  transition: background-color var(--motion-press) var(--ease-state);
}
.bng-calendar__day:hover { background: var(--surface-2); }
.bng-calendar__day[aria-current='date'] { box-shadow: inset 0 0 0 1px var(--control-edge); }
.bng-calendar__day[aria-pressed='true'] { background: var(--brand-fill); color: var(--on-brand); }
.bng-calendar__day:disabled { color: var(--ink-3); cursor: not-allowed; }

/* A count, and a tag. A count is a pill of the brand (ن۶: it asks for attention) or muted; a tag names a state or a
   kind, with a dot and a word (ن۸) - never the colour alone. */
.bng-badge {
  display: inline-grid;
  place-items: center;
  min-inline-size: 20px;
  block-size: 20px;
  padding-inline: var(--s-2);
  border-radius: var(--r-pill);
  background: var(--brand-fill);
  color: var(--on-brand);
  font: var(--t-badge);
  font-feature-settings: 'tnum';
}
.bng-badge--muted { background: var(--surface-3); color: var(--ink); }
.bng-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-block-size: var(--target-min);
  padding-inline: var(--s-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  color: var(--ink);
  font: var(--t-tag);
}
.bng-tag__dot { inline-size: 8px; block-size: 8px; flex: none; border-radius: 50%; background: var(--ink-3); }
.bng-tag--success .bng-tag__dot { background: var(--success); }
.bng-tag--warn .bng-tag__dot { background: var(--warn); }
.bng-tag--danger .bng-tag__dot { background: var(--danger); }

/* A known wait is the loader's own ring, filled (ن۲): --progress from 0 to 1, drawn clockwise in either direction.
   Steps are a line through round nodes (ن۳): done filled, the current one ringed (ن۱). */
.bng-progress {
  inline-size: 16px;
  block-size: 16px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(currentColor calc(var(--progress, 0) * 1turn), color-mix(in srgb, currentColor 30%, transparent) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), currentColor calc(100% - 2.5px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), currentColor calc(100% - 2.5px));
}
.bng-steps { display: flex; margin: 0; padding: 0; list-style: none; }
.bng-steps__step {
  position: relative;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  text-align: center;
  font: var(--t-step);
  color: var(--ink-2);
}
.bng-steps__step::before {   /* the line from the step before */
  content: '';
  position: absolute;
  inset-block-start: 5px;
  inset-inline-start: -50%;
  inline-size: 100%;
  block-size: 2px;
  background: var(--control-edge);
}
.bng-steps__step:first-child::before { content: none; }
.bng-steps__node { position: relative; inline-size: 12px; block-size: 12px; border-radius: 50%; border: 2px solid var(--control-edge); background: var(--surface); }
.bng-steps__step--done::before, .bng-steps__step[aria-current='step']::before { background: var(--brand-fill); }
.bng-steps__step--done .bng-steps__node { border-color: var(--brand-fill); background: var(--brand-fill); }
.bng-steps__step[aria-current='step'] { color: var(--ink); font: var(--t-step-current); }
.bng-steps__step[aria-current='step'] .bng-steps__node { border-color: var(--brand-fill); box-shadow: 0 0 0 3px var(--brand-soft); }

/* A rating scale: one of a few ordered values, every one visible, the ends named in words (ژ۱۴). */
.bng-rating { display: grid; gap: var(--s-2); }
.bng-rating__scale { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(var(--tap-min), 1fr); gap: var(--s-2); }
.bng-rating__opt { position: relative; }
.bng-rating__opt input { position: absolute; opacity: 0; inline-size: 0; block-size: 0; }
.bng-rating__opt span {
  display: grid;
  place-items: center;
  min-block-size: var(--tap-min);
  border: 1px solid var(--control-edge);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
  font: var(--t-segment);
  font-feature-settings: 'tnum';
  cursor: pointer;
  transition: background-color var(--motion-press) var(--ease-state), color var(--motion-press) var(--ease-state);
}
.bng-rating__opt span:hover { background: var(--surface-2); }
.bng-rating__opt input:checked + span { border-color: var(--brand-fill); background: var(--brand-fill); color: var(--on-brand); }
.bng-rating__opt input:focus-visible + span { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }
.bng-rating__anchors { display: flex; justify-content: space-between; gap: var(--s-4); font: var(--t-help); color: var(--ink-3); }

/* A file drop: a label that holds the file input, so a click, a key and a drop all choose a file. A file on its way is
   a bng-row with the progress ring at its start. */
.bng-upload {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-6);
  border: 1.5px dashed var(--control-edge);
  border-radius: var(--r-card);
  background: var(--surface);
  color: var(--ink-2);
  font: var(--t-value);
  text-align: center;
  cursor: pointer;
  transition: background-color var(--motion-press) var(--ease-state), border-color var(--motion-press) var(--ease-state);
}
.bng-upload input { position: absolute; opacity: 0; inline-size: 0; block-size: 0; }
.bng-upload .bng-ic { color: var(--brand-ink); }
.bng-upload:hover, .bng-upload--over { border-color: var(--brand-ink); background: var(--brand-soft); }
.bng-upload:has(input:focus-visible) { outline: var(--focus-ring) solid var(--brand-ink); outline-offset: var(--focus-gap); }
.bng-upload__hint { font: var(--t-help); color: var(--ink-3); }
.bng-upload:hover .bng-upload__hint, .bng-upload--over .bng-upload__hint { color: var(--ink-2); }   /* ink-3 is not measured on brand-soft */

/* An avatar is a circle - not a control (ن۴). Without a photo, the name's first letter on one of the seven fixed
   pairs a0-a6, the same pair for the same person every time; the letter only decorates, the name is always beside
   it. Chosen, it takes the ring (ن۱); present, a dot at its inline end with a word elsewhere (ن۸, ژ۲۹). */
.bng-avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  inline-size: var(--avatar-list, 40px);
  block-size: var(--avatar-list, 40px);
  flex: none;
  border-radius: 50%;
  background: linear-gradient(to bottom, var(--a0-from), var(--a0-to));
  color: var(--on-fill);
  font: var(--t-avatar);
}
.bng-avatar img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; border-radius: 50%; object-fit: cover; }   /* over the letter, which stays beneath until it comes */
.bng-avatar--1 { background: linear-gradient(to bottom, var(--a1-from), var(--a1-to)); }
.bng-avatar--2 { background: linear-gradient(to bottom, var(--a2-from), var(--a2-to)); }
.bng-avatar--3 { background: linear-gradient(to bottom, var(--a3-from), var(--a3-to)); }
.bng-avatar--4 { background: linear-gradient(to bottom, var(--a4-from), var(--a4-to)); }
.bng-avatar--5 { background: linear-gradient(to bottom, var(--a5-from), var(--a5-to)); }
.bng-avatar--6 { background: linear-gradient(to bottom, var(--a6-from), var(--a6-to)); }
.bng-avatar[aria-current='true'] { box-shadow: 0 0 0 var(--focus-gap) var(--surface), 0 0 0 calc(var(--focus-gap) + var(--focus-ring)) var(--brand-ink); }
.bng-avatar__presence {
  position: absolute;
  inset-inline-end: 0;
  inset-block-end: 0;
  inline-size: 10px;
  block-size: 10px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 2px var(--surface);
}

/* A tooltip gives a name, nothing more (ژ۲۲): no link, no button, no sentence to read. It opens on hover and focus,
   stays while the pointer is over it, and Escape closes it (WCAG 1.4.13); the product sets data-state. */
.bng-tooltip {
  position: absolute;
  z-index: 2;
  max-inline-size: 240px;
  padding-block: var(--s-2);
  padding-inline: var(--s-2);
  border-radius: var(--r-thumb);
  background: var(--ink);
  color: var(--surface);
  font: var(--t-tooltip);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--motion-press) var(--ease-state), visibility var(--motion-press) step-end;
}
.bng-tooltip[data-state='open'] { opacity: 1; visibility: visible; transition: opacity var(--motion-press) var(--ease-state); }

/* An inline notice: a message that belongs to a part of the page, in its place (ژ۲۸) - not a toast over the work.
   Its kind is told by its icon and its first word (ن۸); the bar at its inline start repeats it in colour. */
.bng-notice {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line-strong);
  border-inline-start: 3px solid var(--brand-ink);
  border-radius: var(--r-ctl);
  background: var(--surface);
  color: var(--ink);
  font: var(--t-notice);
}
.bng-notice > .bng-ic { color: var(--brand-ink); }
.bng-notice__body { flex: 1 1 12em; min-inline-size: 0; display: flex; flex-direction: column; gap: var(--s-2); overflow-wrap: anywhere; }
.bng-notice > .bng-btn { margin-inline-start: auto; }   /* its act: beside the words where there is room, under them where there is not (ADR-0019) */
.bng-notice__title { font: var(--t-state-title); }
.bng-notice--success { border-inline-start-color: var(--success); }
.bng-notice--success > .bng-ic { color: var(--success); }
.bng-notice--warn { border-inline-start-color: var(--warn); }
.bng-notice--warn > .bng-ic { color: var(--warn); }
.bng-notice--danger { border-inline-start-color: var(--danger); }
.bng-notice--danger > .bng-ic { color: var(--danger); }

@media (prefers-reduced-motion: reduce) {
  .bng-panel, .bng-menu, .bng-undo { transition: opacity var(--motion-fade-reduced) linear; }
}

/* Phase 3, the variants version 1 adds to the components already here (internal/plan/components.md, the mapping) */
.bng-btn--fab { position: fixed; inset-inline-end: var(--s-5); inset-block-end: var(--s-5); inline-size: 56px; block-size: 56px; border-radius: var(--r-card);
  background: var(--brand-fill); color: var(--on-brand); box-shadow: var(--shadow-2); z-index: 20; }
.bng-btn--fab:hover:not(:disabled):not([aria-disabled='true']) { background: color-mix(in srgb, var(--brand-fill), var(--brand-strong)); }   /* a filled button's hover, not an icon button's */
.bng-btn--fab:active:not(:disabled):not([aria-disabled='true']) { background: var(--brand-strong); }
.bng-btn[aria-pressed='true'] { background: var(--brand-soft); color: var(--ink); font-weight: 700; --ic-fill: currentColor; }   /* a two-state icon fills its marked part when on (signature S3) */
.bng-btn--chip[aria-pressed='false'] { background: transparent; box-shadow: inset 0 0 0 1px var(--line-strong); }   /* a filter off: its edge only, so on and off differ by more than the tick */
/* a filter on: a tick before its words, drawn here so no product has to (ژ۱۳: on is said by shape and weight, not colour);
   a tick is not mirrored in right-to-left text */
.bng-btn--chip[aria-pressed='true']::after {
  content: '';
  order: -1;
  inline-size: 0.3em;
  block-size: 0.6em;
  margin-block-end: 0.15em;
  border-right: 0.14em solid currentColor;   /* bng: allow - a drawn tick reads the same in either direction */
  border-bottom: 0.14em solid currentColor;
  transform: rotate(45deg);
}
.bng-btn--copy[data-state='copied'] { color: var(--success); }   /* the icon turns to a tick and «رونوشت برداشته شد» is said in words beside it */
.bng-calendar__day--range { background: var(--brand-soft); }
.bng-calendar__day--edge { background: var(--brand-fill); color: var(--on-brand); font-weight: 700; }
.bng-tag__remove { display: inline-grid; place-items: center; inline-size: var(--target-min); block-size: var(--target-min); margin-inline-start: var(--s-2); padding: 0; border: 0;
  border-radius: var(--r-ctl);   /* a button, even of one mark, is never a circle (ن۴) */ background: transparent; color: var(--ink-2); cursor: pointer; }
.bng-tag__remove:hover { background: var(--surface-3); color: var(--ink); }
.bng-notice--page { border-radius: 0; inline-size: 100%; }
.bng-field__reveal, .bng-field__clear { margin-inline-start: auto; }
.bng-field__box input[type='search']::-webkit-search-cancel-button { display: none; }   /* the field's own clear button, not a second one from the browser */
.bng-avatar-group { display: inline-flex; }
.bng-avatar-group > * + * { margin-inline-start: -8px; box-shadow: 0 0 0 2px var(--surface); }

/* Phase 3, batch 2: acting and moving (internal/plan/components.md) */
.bng-btngroup { display: inline-flex; }
.bng-btngroup > .bng-btn { border-radius: 0; }
.bng-btngroup > .bng-btn:first-child { border-start-start-radius: var(--r-ctl); border-end-start-radius: var(--r-ctl); }
.bng-btngroup > .bng-btn:last-child { border-start-end-radius: var(--r-ctl); border-end-end-radius: var(--r-ctl); }
.bng-btngroup__split > .bng-btn + .bng-btn { border-inline-start: 1px solid var(--line); }
.bng-toolbar { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--s-2); min-block-size: var(--tap-min); overflow-x: auto; }
.bng-navbar { display: flex; gap: var(--s-2); border-block-end: 1px solid var(--line); overflow-x: auto; }
.bng-navbar__item { position: relative; display: inline-flex; align-items: center; min-block-size: var(--tap-min); padding-inline: var(--s-4);
  font: var(--t-tab); color: var(--ink-2); text-decoration: none; }
.bng-navbar__item:hover { background: var(--surface-2); color: var(--ink); }
.bng-navbar__item[aria-current='page'] { color: var(--ink); font-weight: 700; box-shadow: inset 0 -3px 0 var(--brand-ink); }
.bng-drawer { inline-size: 320px; max-inline-size: 85vw; padding: var(--s-3); background: var(--surface); }
.bng-bottomnav { display: flex; justify-content: space-around; min-block-size: 64px; background: var(--surface); border-block-start: 1px solid var(--line); }
.bng-bottomnav__item { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s-2);
  font: var(--t-label); color: var(--ink-2); text-decoration: none; }
.bng-bottomnav__item[aria-current='page'] { color: var(--ink); font-weight: 700; box-shadow: inset 0 3px 0 var(--brand-ink); }
.bng-command { inline-size: min(560px, 100%); padding: var(--s-4); background: var(--surface); border-radius: var(--r-sheet); box-shadow: var(--shadow-2); }
.bng-command .bng-combo__list { position: static; box-shadow: none; margin-block-start: var(--s-2); }
.bng-menubar { display: flex; gap: var(--s-2); min-block-size: var(--tap-min); align-items: center; }
.bng-refresh { display: flex; justify-content: center; padding-block: var(--s-3); color: var(--ink-3); }

/* Phase 3, batch 3: entering data (internal/plan/components.md) */
.bng-slider--range { position: relative; }
.bng-combo__chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.bng-swatches { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.bng-swatches__opt { inline-size: var(--tap-min); block-size: var(--tap-min); padding: 0; border: 0; border-radius: var(--r-ctl); background: var(--swatch, var(--surface-3)); cursor: pointer; }   /* a control: the tap minimum each way */
.bng-swatches__opt[aria-checked='true'] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--ink); }
.bng-transfer { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: var(--s-4); align-items: start; }
@media (width < 600px) { .bng-transfer { grid-template-columns: minmax(0, 1fr); } .bng-transfer__moves { flex-direction: row; justify-content: center; } }   /* one list above the other on a narrow screen */
.bng-transfer__list { display: flex; flex-direction: column; gap: var(--s-2); margin: 0; padding: var(--s-3); border: 1px solid var(--line); border-radius: var(--r-card); }
.bng-transfer__moves { display: flex; flex-direction: column; gap: var(--s-2); align-self: center; }
.bng-time input { font-variant-numeric: tabular-nums; }
.bng-time__dial { position: relative; inline-size: 240px; block-size: 240px; border-radius: var(--r-pill); background: var(--surface-2); }
.bng-time__hour { position: absolute; inline-size: var(--tap-min); block-size: var(--tap-min); border-radius: var(--r-ctl); display: grid; place-items: center; font: var(--t-value); color: var(--ink); }
.bng-time__hour[aria-checked='true'] { background: var(--brand-fill); color: var(--on-brand); font-weight: 700; }
.bng-cropper { position: relative; display: grid; place-items: center; min-block-size: 200px; background: var(--surface-3); border-radius: var(--r-card); overflow: hidden; }
.bng-cropper__frame { position: relative; inline-size: min(60%, 160px); aspect-ratio: 1; box-shadow: 0 0 0 2px var(--on-brand), 0 0 0 999px var(--scrim); }
.bng-cropper > svg { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; }   /* the picture under the frame */

/* Phase 3, batch 4: reading and comparing (internal/plan/components.md) */
.bng-stat { display: flex; flex-direction: column; gap: var(--s-2); }
.bng-stat__value { font: var(--t-28b); color: var(--ink); font-variant-numeric: tabular-nums; }
.bng-stat__label { font: var(--t-label); color: var(--ink-2); }
.bng-stat__change { display: inline-flex; align-items: center; gap: var(--s-2); font: var(--t-label); color: var(--ink-2); }
.bng-timeline { margin: 0; padding: 0; list-style: none; border-inline-start: 2px solid var(--line-strong); }
.bng-timeline__event { position: relative; padding-inline-start: var(--s-5); padding-block-end: var(--s-5); font: var(--t-value); color: var(--ink); }
.bng-timeline__node { position: absolute; inset-inline-start: -6px; inset-block-start: 7px; inline-size: 10px; block-size: 10px; border-radius: var(--r-pill);
  background: var(--surface); box-shadow: inset 0 0 0 2px var(--line-strong); }
.bng-timeline__event:last-child .bng-timeline__node { background: var(--brand-ink); box-shadow: none; }
.bng-chart { margin: 0; }
.bng-chart svg { inline-size: 100%; block-size: auto; font-family: inherit; }
.bng-chart__legend { font: var(--t-label); color: var(--ink-2); margin-block-start: var(--s-2); }
.bng-chart__table { margin-block-start: var(--s-3); }
.bng-chart__table > summary { display: inline-flex; align-items: center; min-block-size: var(--tap-min); font: var(--t-label); color: var(--brand-ink); cursor: pointer; }
.bng-codeblock { position: relative; background: var(--surface-2); border-radius: var(--r-card); }
.bng-codeblock pre { margin: 0; padding: var(--s-4); overflow-x: auto; font: var(--t-13); font-family: var(--font-mono); }
.bng-codeblock__copy { position: absolute; inset-block-start: var(--s-2); inset-inline-end: var(--s-2); }
.bng-qr { display: inline-flex; flex-direction: column; gap: var(--s-2); margin: 0; }
.bng-qr .bng-link { display: inline-block; min-block-size: var(--target-min); }   /* a link standing alone is a target of its own (WCAG 2.5.8) */
.bng-qr svg { inline-size: 160px; block-size: 160px; padding: var(--s-4); background: var(--paper); }

/* Phase 3, batch 5: the rest of version 1 (internal/plan/components.md) */
.bng-row__grip { flex: none; display: grid; place-items: center; inline-size: var(--target-min); block-size: var(--target-min); color: var(--ink-3); cursor: grab; }
.bng-table--grid td:focus-within, .bng-table--grid td[aria-selected='true'] { box-shadow: inset 0 0 0 2px var(--brand-ink); }
.bng-sheet { inset-inline: 0; inset-block-end: 0; border-start-start-radius: var(--r-sheet); border-start-end-radius: var(--r-sheet); background: var(--surface); padding: var(--s-4); }
.bng-msg { max-inline-size: 75%; margin-block: var(--s-2); padding: var(--s-3) var(--s-4); background: var(--surface-2); border-radius: var(--r-card); font: var(--t-16); color: var(--ink); }
.bng-msg p { margin: 0; white-space: pre-wrap; }   /* the lines the writer broke with Shift+Enter */
.bng-msg--own { margin-inline-start: auto; background: var(--brand-soft); }
.bng-msg__meta { display: inline-flex; align-items: center; gap: var(--s-2); font: var(--t-12); color: var(--ink-3); }
.bng-composer textarea { max-block-size: calc(5 * 1.5em); resize: none; }
.bng-recorder { position: relative; display: inline-flex; align-items: center; gap: var(--s-3); font: var(--t-value); color: var(--ink); }
.bng-recorder__note {   /* a refusal (no microphone): over the button, so it takes no width from what is beside it, and goes by itself */
  position: absolute; inset-block-end: calc(100% + var(--s-2)); inset-inline-end: 0; z-index: 1;
  inline-size: max-content; max-inline-size: min(20rem, calc(100vw - 2 * var(--s-4)));
  padding: var(--s-2) var(--s-3); border-radius: var(--r-card); background: var(--ink); color: var(--surface);
  font: var(--t-notice); box-shadow: var(--shadow-2); text-wrap: balance;
}
.bng-recorder > .bng-progress {   /* while it records: the loader's ring around the button, filling toward the longest recording (ن۲) */
  position: absolute; inset-inline-start: -4px; inset-block-start: 50%; translate: 0 -50%;
  inline-size: calc(var(--tap-min) + 8px); block-size: calc(var(--tap-min) + 8px); color: var(--brand-ink); pointer-events: none;
}
bng-wave { display: inline-flex; align-items: center; gap: var(--s-2); }   /* the web core's player: its button, then its wave */
.bng-wave { display: flex; align-items: center; gap: var(--s-2); block-size: 32px; }
.bng-wave i { inline-size: 3px; border-radius: var(--r-pill); background: var(--line-strong); }
.bng-wave i[data-played] { background: var(--brand-ink); }
.bng-player { background: var(--viewer-bg); border-radius: var(--r-card); overflow: hidden; color: var(--on-scrim); }
.bng-player > svg { display: block; inline-size: 100%; block-size: auto; aspect-ratio: 16 / 9; }
.bng-player__bar { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2); }
.bng-player__bar .bng-slider { flex: 1; }
.bng-viewer { background: var(--viewer-bg); color: var(--on-scrim); }
.bng-viewer__bar { display: flex; align-items: center; gap: var(--s-2); padding: var(--s-2); }
.bng-carousel { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: var(--s-3); font: var(--t-value); color: var(--ink); }
.bng-carousel > svg { inline-size: min(100%, 16rem); block-size: auto; border-radius: var(--r-card); }
.bng-carousel > [aria-live] { flex-basis: 100%; text-align: center; }
.bng-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); gap: var(--s-2); }
.bng-map { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 1fr); gap: var(--s-3); }
.bng-map__canvas { min-block-size: 200px; background: var(--surface-3); border-radius: var(--r-card); }
.bng-map__list { margin: 0; padding-inline-start: var(--s-5); font: var(--t-value); color: var(--ink); }
.bng-dash { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--measure-min)), 1fr)); gap: var(--s-4); }   /* one column where a card is wider than the page */
.bng-dash__tile { min-inline-size: 0; }
.bng-editor { display: flex; flex-direction: column; gap: var(--s-2); }
.bng-editor__surface { min-block-size: 8rem; padding: var(--s-3); background: var(--surface); border-radius: var(--r-ctl); box-shadow: inset 0 0 0 1px var(--control-edge); font: var(--t-16); color: var(--ink); }
.bng-builder { display: flex; flex-direction: column; gap: var(--s-2); align-items: flex-start; }
.bng-builder__rule { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); padding: var(--s-2) var(--s-3); background: var(--surface-2); border-radius: var(--r-ctl); font: var(--t-value); color: var(--ink); }

/* ============================================================
   Phase 3, the tier-A components new to version 1 (internal/plan/components.md): link, breadcrumbs, pagination,
   tree, combobox, slider, form, description list, popover, accordion and disclosure, card. Each reads only the
   shared roles and tokens; a state is never colour alone (ژ۱۳).
   ============================================================ */
/* link: underlined always - a link is never told by colour alone */
.bng-link { color: var(--brand-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.bng-link:hover { text-decoration-thickness: 2px; }

/* breadcrumbs: where the page sits; the current page is the last, bold, not a link */
.bng-crumbs { font: var(--t-label); color: var(--ink-2); }
.bng-crumbs ol { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); margin: 0; padding: 0; list-style: none; }
.bng-crumbs li + li::before { content: '/'; margin-inline-end: var(--s-2); color: var(--ink-3); }
.bng-crumbs a { color: var(--ink-2); text-decoration: underline; text-underline-offset: 0.2em; }
.bng-crumbs [aria-current='page'] { color: var(--ink); font-weight: 700; }

/* pagination: pages by number, the current one filled and bold; previous and next mirror with the reading */
.bng-pager { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); font: var(--t-value); }
.bng-pager__item { display: inline-grid; place-items: center; min-inline-size: var(--tap-min); min-block-size: var(--tap-min); padding-inline: var(--s-2);
  border-radius: var(--r-ctl); color: var(--ink-2); text-decoration: none; }
.bng-pager__item:hover { background: var(--surface-2); color: var(--ink); }
.bng-pager__item[aria-current='page'] { background: var(--surface-3); color: var(--ink); font-weight: 700; }
.bng-pager__gap { color: var(--ink-3); padding-inline: var(--s-2); }

/* tree: nested rows that open and close; the open state is the chevron's turn and the shown group, not colour */
.bng-tree, .bng-tree [role='group'] { margin: 0; padding: 0; list-style: none; }
.bng-tree [role='group'] { padding-inline-start: var(--s-6); }
.bng-tree__item > .bng-tree__row { display: flex; align-items: center; gap: var(--s-2); min-block-size: var(--tap-min); padding-inline: var(--s-2);
  border-radius: var(--r-row); font: var(--t-row-title); color: var(--ink); cursor: pointer; }
.bng-tree__row:hover { background: var(--surface-2); }
.bng-tree__item[aria-selected='true'] > .bng-tree__row { background: var(--brand-soft); font-weight: 700; }
.bng-tree__item[aria-expanded] > .bng-tree__row .bng-ic { transition: transform var(--motion-move) var(--ease-state); }
.bng-tree__item[aria-expanded='true'] > .bng-tree__row .bng-ic { transform: rotate(90deg); }
.bng-tree__item[aria-expanded='false'] > [role='group'] { display: none; }

/* combobox: a field that suggests; the list is a listbox under the field, the active option outlined, the chosen bold */
.bng-combo { position: relative; }
.bng-combo__list { position: absolute; inset-inline: 0; inset-block-start: calc(100% + var(--s-2)); z-index: 20; margin: 0; padding: var(--s-2);
  list-style: none; background: var(--surface); border-radius: var(--r-card); box-shadow: var(--shadow-2); max-block-size: 18rem; overflow-y: auto; }
.bng-combo__opt { display: flex; align-items: center; min-block-size: var(--tap-min); padding-inline: var(--s-3); border-radius: var(--r-row);
  font: var(--t-menu-item); color: var(--ink); cursor: pointer; }
.bng-combo__opt[data-active] { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--line-strong); }
.bng-combo__opt[aria-selected='true'] { font-weight: 700; }

/* slider: the platform's range, in the brand; its value is always said in words beside it */
.bng-slider { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: var(--s-3); }
.bng-slider input[type='range'] { inline-size: 100%; min-block-size: var(--tap-min); accent-color: var(--brand-fill); }
.bng-slider output { font: var(--t-value); color: var(--ink); min-inline-size: 4ch; text-align: end; }

/* form: one column of fields, groups apart by twice the gap within them (ژ۳۰), the actions at its end */
bng-form { display: block; }   /* the web core's element around the native form (ADR-0026) */
.bng-form { display: flex; flex-direction: column; gap: var(--s-5); max-inline-size: var(--measure); }
.bng-form__group { display: flex; flex-direction: column; gap: var(--s-5); padding-block-start: var(--s-7); }
.bng-form__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); padding-block-start: var(--s-5); }

/* description list: a fact's name beside its value; side by side where there is room, stacked where not */
.bng-dl { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: var(--s-3) var(--s-5); margin: 0; }
.bng-dl dt { font: var(--t-label); color: var(--ink-2); }
.bng-dl dd { margin: 0; font: var(--t-value); color: var(--ink); }

/* popover: a small surface tied to what opened it; never covers what it explains, dismissed by Escape */
.bng-popover { max-inline-size: 20rem; padding: var(--s-4); background: var(--surface); color: var(--ink); border: 0; border-radius: var(--r-card);
  box-shadow: var(--shadow-2); font: var(--t-value); }

/* accordion and disclosure: details and summary; open is the chevron's turn and the shown body */
.bng-accordion { border-block-start: 1px solid var(--line); }
.bng-accordion__item { border-block-end: 1px solid var(--line); }
.bng-accordion__item > summary { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); min-block-size: var(--tap-min);
  padding-inline: var(--s-2); font: var(--t-row-title); color: var(--ink); cursor: pointer; list-style: none; }
.bng-accordion__item > summary::-webkit-details-marker { display: none; }
.bng-accordion__item > summary .bng-ic { transition: transform var(--motion-move) var(--ease-state); }
.bng-accordion__item[open] > summary .bng-ic { transform: rotate(180deg); }
.bng-accordion__body { padding: 0 var(--s-2) var(--s-4); font: var(--t-value); color: var(--ink-2); }

/* card: a surface that holds one thing; when it is a link, the whole card is the target, its title the name */
.bng-card { position: relative; padding: var(--s-5); background: var(--surface); border-radius: var(--r-card); color: var(--ink); }
.bng-card__title { margin: 0 0 var(--s-2); font: var(--t-state-title); }
.bng-card__body { margin: 0; font: var(--t-value); color: var(--ink-2); }
.bng-card__link { display: inline-block; min-block-size: var(--target-min); color: inherit; text-decoration: none; }   /* its own box a target too, beside the whole card (WCAG 2.5.8) */
.bng-card__link::after { content: ''; position: absolute; inset: 0; border-radius: inherit; }
.bng-card:has(.bng-card__link:hover) { background: var(--surface-2); }

/* ============================================================
   Forced colours (Windows high contrast, and any forced palette): the person's own colours win (WCAG 3 «Text
   color adjustable», «User settings supported»). The browser replaces every colour with a system one and drops
   backgrounds and shadows, so a state carried by a fill alone would vanish - or, for a box whose tick hides
   in `color: transparent`, show the wrong state. Each such state is drawn again in system colours: an edge, a
   filled mark, an outline. Nothing else changes.
   ============================================================ */
@media (forced-colors: active) {
  .bng-btn { border: 1px solid ButtonText; }
  .bng-btn:disabled, .bng-btn[aria-disabled='true'] { border-color: GrayText; }
  .bng-choice__box { forced-color-adjust: none; background: Canvas; border-color: CanvasText; color: transparent; }
  .bng-choice input:checked + .bng-choice__box { background: Highlight; border-color: Highlight; color: HighlightText; }
  .bng-toggle__track { forced-color-adjust: none; background: Canvas; border: 1px solid CanvasText; }
  .bng-toggle__knob { forced-color-adjust: none; background: CanvasText; box-shadow: none; }
  .bng-toggle input:checked + .bng-toggle__track { background: Highlight; border-color: Highlight; }
  .bng-toggle input:checked + .bng-toggle__track .bng-toggle__knob { background: HighlightText; }
  .bng-segmented__opt input:checked + span { outline: 2px solid Highlight; outline-offset: -2px; }
  .bng-row[aria-current='page'], .bng-row[aria-selected='true'] { outline: 2px solid Highlight; outline-offset: -2px; }
  .bng-field__box { border: 1px solid CanvasText; }
  .bng-spinner { forced-color-adjust: none; color: CanvasText; }
  .bng-skeleton__bar, .bng-skeleton__avatar { forced-color-adjust: none; background: GrayText; }
  /* A surface told from the page by its fill and shadow alone - both dropped here - keeps an edge. */
  .bng-menu, .bng-confirm, .bng-undo, .bng-calendar, .bng-tooltip { border: 1px solid CanvasText; }
  .bng-steps__step::before, .bng-tag__dot, .bng-avatar__presence { forced-color-adjust: none; background: CanvasText; }
  .bng-tabs__tab[aria-selected='true']::after, .bng-steps__step--done .bng-steps__node,
  .bng-steps__step--done::before, .bng-steps__step[aria-current='step']::before { forced-color-adjust: none; background: Highlight; }
  .bng-calendar__day[aria-pressed='true'], .bng-rating__opt input:checked + span, .bng-badge {
    forced-color-adjust: none; background: Highlight; color: HighlightText; border-color: Highlight;
  }
  .bng-calendar__day[aria-current='date'] { outline: 1px solid CanvasText; outline-offset: -1px; }
  .bng-table tbody tr[aria-selected='true'] { outline: 2px solid Highlight; outline-offset: -2px; }
  .bng-progress { forced-color-adjust: none; background: conic-gradient(CanvasText calc(var(--progress, 0) * 1turn), GrayText 0); }
  .bng-avatar { forced-color-adjust: none; background: Canvas; color: CanvasText; border: 1px solid CanvasText; }
  /* what a ring of box-shadow or a fill alone told is drawn again as an outline, the one line the system keeps */
  .bng-avatar[aria-current='true'], .bng-swatches__opt[aria-checked='true'] { outline: 2px solid Highlight; outline-offset: 2px; }
  .bng-combo__opt[data-active], .bng-tree__item[aria-selected='true'] > .bng-tree__row { outline: 2px solid Highlight; outline-offset: -2px; }
  .bng-swatches__opt { forced-color-adjust: none; border: 1px solid CanvasText; }   /* its colour is what it shows, so the system leaves it */
}
