/* created by oran */
/* arabic */
@font-face {
  font-family: 'Aref Ruqaa';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/arefruqaa-WwkYxPW1E165rajQKDulKDwNQNAY2e_7.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Aref Ruqaa';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/arefruqaa-WwkYxPW1E165rajQKDulKDwNQNsY2e_7.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Aref Ruqaa';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/arefruqaa-WwkYxPW1E165rajQKDulKDwNQNUY2Q.woff2') 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;
}
/* arabic */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscQyyS4J0.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscSCyS4J0.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscRiyS.woff2') 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;
}
/* arabic */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscQyyS4J0.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscSCyS4J0.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscRiyS.woff2') 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;
}
/* arabic */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscQyyS4J0.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscSCyS4J0.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscRiyS.woff2') 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;
}
/* arabic */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscQyyS4J0.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscSCyS4J0.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscRiyS.woff2') 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;
}
/* arabic */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscQyyS4J0.woff2') format('woff2');
  unicode-range:
    U+0600-06FF, U+0750-077F, U+0870-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E, U+2010-2011,
    U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC, U+102E0-102FB, U+10E60-10E7E,
    U+10EC2-10EC7, U+10EC9-10EEE, U+10EF0-10EFF, U+1EE00-1EE03, U+1EE05-1EE1F, U+1EE21-1EE22,
    U+1EE24, U+1EE27, U+1EE29-1EE32, U+1EE34-1EE37, U+1EE39, U+1EE3B, U+1EE42, U+1EE47, U+1EE49,
    U+1EE4B, U+1EE4D-1EE4F, U+1EE51-1EE52, U+1EE54, U+1EE57, U+1EE59, U+1EE5B, U+1EE5D, U+1EE5F,
    U+1EE61-1EE62, U+1EE64, U+1EE67-1EE6A, U+1EE6C-1EE72, U+1EE74-1EE77, U+1EE79-1EE7C, U+1EE7E,
    U+1EE80-1EE89, U+1EE8B-1EE9B, U+1EEA1-1EEA3, U+1EEA5-1EEA9, U+1EEAB-1EEBB, U+1EEF0-1EEF1;
}
/* latin-ext */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscSCyS4J0.woff2') format('woff2');
  unicode-range:
    U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329,
    U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F,
    U+A720-A7FF;
}
/* latin */
@font-face {
  font-family: 'Cairo';
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url('fonts/cairo-SLXVc1nY6HkvangtZmpQdkhzfH5lkSscRiyS.woff2') 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;
}

html,
body {
  margin: 0;
  padding: 0;
  background: linear-gradient(180deg, #112b52 0%, #0f274d 100%);
}

html.dark-mode,
html.dark-mode body {
  background: linear-gradient(180deg, #0f1d36 0%, #0b1529 100%);
}

#app-shell {
  position: fixed;
  inset: 0;
  z-index: 9000;
  pointer-events: none;
  background: linear-gradient(180deg, #112b52 0%, #0f274d 100%);
}

html.dark-mode #app-shell {
  background: linear-gradient(180deg, #0f1d36 0%, #0b1529 100%);
}

/* The navigation block — .ui-nav: the primary gradient, the header's top
       radius, full width. */
#app-shell .shell-nav {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: linear-gradient(135deg, #0f274d 0%, #091a36 100%);
  border-radius: 14px 14px 0 0;
}

html.dark-mode #app-shell .shell-nav {
  background: linear-gradient(135deg, #16294a 0%, #0b1529 100%);
}

/* The header band — .ui-nav-band: the centred column of logo, title and
       identity, at the container width. */
#app-shell .shell-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  padding: 10px max(16px, env(safe-area-inset-right, 0px)) 12px
    max(16px, env(safe-area-inset-left, 0px));
}

#app-shell .shell-logo {
  width: 76px;
  height: 76px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
  overflow: hidden;
  flex-shrink: 0;
}

#app-shell .shell-logo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

#app-shell .shell-title {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 1100px;
  margin: 0;
  color: #fff;
  text-align: center;
  font-family: 'Cairo', sans-serif;
  font-size: 20px;
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.3px;
}

/* Reserves the height of the header's identity row (the name and the
       status slot, see UiNavBar / ui.css .ui-nav-identity / .ui-nav-status),
       so the band is the same height as the frame's and nothing shifts when
       the shell is swapped out. 32px is the status slot's own reserved height
       (the offline pill's height); the button itself is hidden: nobody is
       signed in yet. */
#app-shell .shell-identity {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  max-width: 100%;
  min-height: 32px;
}

#app-shell .shell-signout {
  visibility: hidden;
  min-height: 27px;
  min-width: 0;
  padding: 3px 10px;
  font-family: 'Cairo', sans-serif;
  font-size: 11px;
  background: transparent;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.6);
  border-radius: 6px;
}

/* Reserves the tab strip's place — .ui-nav-tabs: a white bar at the
       container width, so the real tabs appear in the same space. */
#app-shell .shell-tabs {
  width: 100%;
  max-width: 1280px;
  min-height: 52px;
  margin: 16px auto;
  border-radius: 14px;
  background: #ffffff;
  border: 1px solid #e2e8f0;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
}

html.dark-mode #app-shell .shell-tabs {
  background: #0f1d36;
  border-color: #2a3f63;
}

/* The frame's own compact steps (ui.css .ui-nav-band / .ui-nav-title /
       .ui-nav-logo), so the shell follows the phone layout too. */
@media (max-width: 768px) {
  #app-shell .shell-header {
    padding: 8px max(12px, env(safe-area-inset-right, 0px)) 10px
      max(12px, env(safe-area-inset-left, 0px));
  }

  #app-shell .shell-title {
    font-size: 17px;
  }

  #app-shell .shell-tabs {
    min-height: 36px;
    margin: 12px auto;
  }
}

@media (max-width: 480px) {
  #app-shell .shell-title {
    font-size: 14px;
    letter-spacing: 0;
  }

  #app-shell .shell-logo {
    width: 60px;
    height: 60px;
  }
}

/* app: styles/variables.css */
/* ========================================
   CSS VARIABLES & DESIGN TOKENS
   المتغيرات الأساسية للتصميم
======================================== */

:root {
  /* Brand Colors - الحفاظ على الألوان الأصلية */
  --primary: #0f274d;
  --primary-dark: #091a36;
  --gold: #caa854;
  --gold-light: #f4d489;
  --green: #238b5a;
  --red: #c94b42;

  /* Surface Colors - تعديل الأبيض ليكون أريح للعين */
  --white: #ffffff;
  --card: #f5f7fb;
  /* بدلاً من #f7f7f7 - لون أفتح وأريح */
  --border: #e2e8f0;
  /* بدلاً من #dcdcdc - أفتح وأكثر احترافية */
  --text: #1e293b;
  /* بدلاً من #1d2433 - أريح للقراءة */

  /* Heading and label text. The redesign coloured titles with --primary,
       but --primary is a dark surface colour, so those titles vanish in
       .dark-mode. Light keeps --primary; dark takes the light --text. It is
       declared in both themes so the dark value is not lost to the alias. */
  --heading-text: var(--primary);

  /* Body background */
  --body-bg-start: #112b52;
  --body-bg-end: #0f274d;

  /* Modal & surface backgrounds */
  --modal-bg: #f7f7f7;
  --modal-header-from: #ffffff;
  --modal-header-to: #fafafa;
  --modal-border: #dfdfdf;
  --modal-title-color: #10254a;

  /* Muted text */
  --text-muted: #64748b;

  /* Subtle surface tints */
  --surface-subtle: #fafcff;
  --surface-warning: #fffbeb;
  --warning-text: #92400e;

  /* Status / countdown tints. These were hardcoded literals with no
       .dark-mode override, so countdown chips and status pills stayed bright
       islands on a dark page (report 07 §5.4). The light values are
       byte-identical to the literals they replace, so light mode is
       unchanged. */
  --status-warning-bg: #fef3c7;
  --status-warning-fg: #92400e;
  --status-danger-bg: #fee2e2;
  --status-danger-fg: #991b1b;
  --status-info-bg: #ecfeff;
  --status-info-fg: #155e75;
  --status-neutral-bg: #1f2937;
  --status-neutral-fg: #ffffff;
  /* The "ok" state chip (ticket 98-3c): the one tone the Settings row chips
       were missing — an active author. Light values are the prototype's own
       chip-ok tint. */
  --status-ok-bg: #e6f4ec;
  --status-ok-fg: #1b6b45;

  /* Tints the screens need (ticket 300): gold washes, white washes for text
       and lines on the navy header, the modal scrim, a placeholder grey, the
       alternate row and WhatsApp's green. Both themes declare all nine. */
  --gold-a08: rgba(202, 168, 84, 0.08);
  --gold-a15: rgba(202, 168, 84, 0.15);
  --gold-a40: rgba(202, 168, 84, 0.4);
  --on-dark-a10: rgba(255, 255, 255, 0.1);
  --on-dark-a60: rgba(255, 255, 255, 0.6);
  --scrim: rgba(0, 0, 0, 0.45);
  --placeholder: #94a3b8;
  --row-alt: #f8fafc;
  --whatsapp: #25d366;

  /* Login-page gradient. auth.css:18 was written against these two names
       but they were never defined anywhere, so that `background` shorthand
       was invalid and the login page rendered with no background. They
       track the body background so the two stay in step. */
  --bg-gradient-start: var(--body-bg-start);
  --bg-gradient-end: var(--body-bg-end);

  /* Secondary surface — device cards and the Client-Contacts form panel
       in SettingsTab. Referenced but never defined; those panels rendered
       fully transparent. */
  --bg-secondary: #eef2f8;

  /* Alias of --text, kept because client.css:645 reads it (it has a
       fallback, so this only makes the intent explicit). */
  --text-primary: var(--text);

  /* Shadows - أخف وأكثر نعومة */
  --shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
  --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.08);

  /* The desktop/tablet scale — the owner's 80% browser-zoom reference.
       Phones (≤768px) reset it to 1 in mobile.css, so they keep today's sizes. */
  --ui-scale: 0.8;

  /* Text size multiplier — controlled by «حجم الخط» in Settings.
       Default 1 = today's sizes. Small 0.86, large 1.14, xlarge 1.29. */
  --ui-text-step: 1;

  /* Combined text scale: screen scale × text step. Only text uses this.
       Spacing, padding and other sizes keep --ui-scale. */
  --ui-text-scale: calc(var(--ui-scale) * var(--ui-text-step));

  /* The floor for desktop type: only the two smallest steps land on it
       (2xs 8px, xs 8.8px). 0 on phones, so today's small sizes survive. */
  --ui-text-min: 10px;

  /* Spacing Scale - مصغرة للديسكتوب */
  --space-xs: calc(4px * var(--ui-scale));
  --space-sm: calc(8px * var(--ui-scale));
  --space-md: calc(12px * var(--ui-scale));
  --space-lg: calc(16px * var(--ui-scale));
  --space-xl: calc(20px * var(--ui-scale));
  --space-2xl: calc(24px * var(--ui-scale));

  /* Font Sizes — today's px x 0.8 on desktop, today's px on a phone.
       The floor lifts only the two smallest steps (2xs 8px, xs 8.8px), so
       the hierarchy the review found collapsed keeps its order.
       --ui-text-min is 0 on a phone, so the floor never applies there.
       Uses --ui-text-scale (screen scale × text step) so «حجم الخط» works. */
  --font-2xs: max(var(--ui-text-min), calc(10px * var(--ui-text-scale)));
  /* 10px */
  --font-xs: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  /* 11px */
  --font-sm: max(var(--ui-text-min), calc(13px * var(--ui-text-scale)));
  /* 13px */
  --font-base: max(var(--ui-text-min), calc(14px * var(--ui-text-scale)));
  /* 14px */
  --font-md: max(var(--ui-text-min), calc(15px * var(--ui-text-scale)));
  /* 15px */
  --font-lg: max(var(--ui-text-min), calc(17px * var(--ui-text-scale)));
  /* 17px */
  --font-xl: max(var(--ui-text-min), calc(20px * var(--ui-text-scale)));
  /* 20px */
  --font-2xl: max(var(--ui-text-min), calc(24px * var(--ui-text-scale)));
  /* 24px */

  /* Border Radius - أنعم قليلاً */
  --radius-sm: calc(6px * var(--ui-scale));
  --radius-md: calc(10px * var(--ui-scale));
  --radius-lg: calc(14px * var(--ui-scale));
  --radius-xl: calc(18px * var(--ui-scale));
  --radius-2xl: calc(22px * var(--ui-scale));
  --radius-full: 999px;

  /* Container limits - للديسكتوب */
  --container-max: 1280px;

  /* Safe area insets (iOS notch / Dynamic Island / home indicator).
       Resolve to 0px on devices/browsers without safe areas (desktop,
       Android, older Safari), so these are safe to use unconditionally —
       no media query needed. Requires viewport-fit=cover in index.html. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}

/* Dark Mode - the office navy and gold */
.dark-mode {
  --primary: #16294a;
  --primary-dark: #0b1529;
  --gold: #caa854;
  --gold-light: #f4d489;
  --green: #2d7a5a;
  --red: #c94b42;
  --white: #0f1d36;
  --card: #16284a;
  --border: #2a3f63;
  --text: #e8edf5;
  --heading-text: var(--text);

  /* surface tokens — dark overrides */
  --body-bg-start: #0f1d36;
  --body-bg-end: #0b1529;
  --modal-bg: #16284a;
  --modal-header-from: #1b3056;
  --modal-header-to: #16284a;
  --modal-border: #2a3f63;
  --modal-title-color: #e8edf5;
  --surface-subtle: #12233f;
  --surface-warning: #2a2a1e;
  --warning-text: #f4d489;
  --text-muted: #a3b0c4;
  --bg-secondary: #12233f;

  /* Status / countdown tints — dark variants. */
  --status-warning-bg: #3a3418;
  --status-warning-fg: #f4d489;
  --status-danger-bg: #3a1f1f;
  --status-danger-fg: #f0a5a0;
  --status-info-bg: #16323a;
  --status-info-fg: #8fd6e0;
  --status-neutral-bg: #0b1529;
  --status-neutral-fg: #e8edf5;
  --status-ok-bg: #17351f;
  --status-ok-fg: #8fd6a8;

  /* The same nine tints. Seven carry the light value; the placeholder and
       the alternate row are darker, to sit on the navy card. */
  --gold-a08: rgba(202, 168, 84, 0.08);
  --gold-a15: rgba(202, 168, 84, 0.15);
  --gold-a40: rgba(202, 168, 84, 0.4);
  --on-dark-a10: rgba(255, 255, 255, 0.1);
  --on-dark-a60: rgba(255, 255, 255, 0.6);
  --scrim: rgba(0, 0, 0, 0.45);
  --placeholder: #7d8ba3;
  --row-alt: #12233f;
  --whatsapp: #25d366;
}

/* body background in dark mode is handled via --body-bg-start/end tokens in variables.css */

.dark-mode .main-card,
.dark-mode .modal-content {
  background: var(--card);
  border-color: var(--border);
}

.dark-mode .input,
.dark-mode .custom-select,
.dark-mode textarea.input {
  background: var(--surface-subtle);
  border-color: var(--border);
  color: var(--text);
}

.dark-mode .input::placeholder {
  color: var(--placeholder);
}

.dark-mode .btn-light {
  background: var(--surface-subtle);
  color: var(--text);
  border-color: var(--border);
}

.dark-mode .btn-light:hover {
  background: var(--border);
}

.dark-mode table {
  background: var(--card);
}

.dark-mode tbody td {
  border-bottom-color: var(--border);
}

.dark-mode tbody tr {
  background: var(--card);
}

.dark-mode tbody tr:nth-child(even) {
  background: var(--row-alt);
}

.dark-mode tbody tr:hover {
  background: var(--gold-a08);
}

.dark-mode .dashboard-card {
  background: var(--card);
}

.dark-mode .static-field {
  background: var(--surface-subtle);
  border-color: var(--border);
  color: var(--text);
}

.dark-mode .empty-state h2 {
  color: var(--text-muted);
}

.dark-mode .filter-checkbox {
  background: var(--surface-subtle);
}

.dark-mode .filter-checkbox:hover {
  background: var(--gold-a08);
}

/* Light neutral surfaces that were hardcoded to a light-mode-only
   background with no dark override — same "light button floating on
   a dark page" issue table rows had above, just on tab/badge
   surfaces instead of table rows. The Dashboard's sub-tabs left this
   rule: they are transparent tabs now (ticket 98-2a). */
.dark-mode .client-tabs button {
  background: var(--surface-subtle);
}

/* app: styles/reset.css */
/* ========================================
   RESET & GLOBAL BASE STYLES
   إعادة الضبط والأنماط الأساسية
======================================== */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html {
  direction: rtl;
  scroll-behavior: smooth;
  scroll-padding-top: 20px;
  /* "none" (not "contain") is required to actually stop the elastic
       rubber-band bounce itself, not just scroll chaining. Reliably
       supported on iOS Safari 16+. */
  overscroll-behavior-y: none;
  /* Matches body's background. If Safari still shows any bounce
       sliver beyond body's box, this is what's revealed behind it —
       previously unset (default white), which was the reported flash. */
  background: linear-gradient(180deg, var(--body-bg-start) 0%, var(--body-bg-end) 100%);
  /* Prevent Safari from auto-bumping font size on orientation change */
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: 'Cairo', sans-serif;
  background: linear-gradient(180deg, var(--body-bg-start) 0%, var(--body-bg-end) 100%);
  color: var(--text);
  min-height: 100vh;
  /* 100dvh accounts for Safari's collapsing/expanding address bar —
       100vh alone is locked to the largest possible viewport, leaving a
       gap (or forcing a jump) as the toolbar shows/hides. Falls back to
       100vh on browsers without dvh support. */
  min-height: 100dvh;
  overflow-x: hidden;
  overscroll-behavior-y: none;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  background: radial-gradient(circle at top right, var(--on-dark-a10), transparent 30%);
  pointer-events: none;
  z-index: -1;
}

a {
  text-decoration: none;
}

button,
input,
select,
textarea {
  font-family: 'Cairo', sans-serif;
  -webkit-tap-highlight-color: transparent;
}

button {
  user-select: none;
  transition: all 0.2s ease;
}

/* button:hover and button:active transforms are handled
   per-component (.btn, .tab-item, etc.) to avoid conflicts */

/* ========================================
   SCROLLBAR
======================================== */

::-webkit-scrollbar {
  width: 8px;
  height: 10px;
}

::-webkit-scrollbar-track {
  background: var(--border);
}

::-webkit-scrollbar-thumb {
  background: var(--gold-a40);
  border-radius: var(--radius-full);
}

::-webkit-scrollbar-thumb:hover {
  background: var(--gold-a40);
}

/* ========================================
   APP WRAPPER
======================================== */

.app {
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
}

/* ========================================
   PAGE ANIMATION
======================================== */

.fade-page {
  animation: fadePage 0.22s ease;
}

@keyframes fadePage {
  from {
    opacity: 0;
    transform: translateY(8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ========================================
   EMPTY STATE
======================================== */

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(14px * var(--ui-scale));
  padding: calc(48px * var(--ui-scale)) calc(20px * var(--ui-scale));
  text-align: center;
  animation: fadePage 0.25s ease;
}

.empty-icon {
  width: calc(72px * var(--ui-scale));
  height: calc(72px * var(--ui-scale));
  border-radius: 50%;
  background: var(--gold-a15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: max(var(--ui-text-min), calc(36px * var(--ui-text-scale)));
}

.empty-state h2 {
  color: var(--text-muted);
  font-size: var(--font-xl);
}

/* ========================================
   PAGE CONTENT
======================================== */

.page-content {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* ========================================
   KEYBOARD FOCUS
   There was no global focus style, so a keyboard user could not see where
   they were — including on the clickable dashboard cards, which only
   became reachable once Card.jsx started forwarding onClick to
   role="button" + tabIndex. Uses :focus-visible, so mouse and touch users
   see no change. Component-level rules (e.g. .agent-panel button:focus-visible)
   are more specific and still win.
======================================== */

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ========================================
   BADGE / STATUS
======================================== */

.badge {
  display: inline-block;
  padding: calc(4px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-full);
  font-size: var(--font-sm);
  font-weight: 700;
}

/* The badge types the app renders by hand. Without these rules every type
   rendered as bare text, so one type looked exactly like another — and the
   hand-written
   `<span className="badge badge-success">✓ مستلم</span>` in MuhadreenTab
   had no background at all. */
.badge-success {
  background: var(--green);
  color: var(--status-neutral-fg);
}

.badge-warning {
  background: var(--surface-warning);
  color: var(--warning-text);
}

.badge-info {
  background: var(--primary);
  color: var(--status-neutral-fg);
}

/* ========================================
   COUNTDOWN BADGES
======================================== */

.countdown-text {
  padding: calc(3px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-full);
  font-size: var(--font-xs);
  font-weight: 700;
  width: fit-content;
}

.countdown-yellow {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}

.countdown-red {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

.countdown-black {
  background: var(--status-neutral-bg);
  color: var(--status-neutral-fg);
}

.countdown-normal {
  background: var(--status-info-bg);
  color: var(--status-info-fg);
}

/* ========================================
   GLOBAL SEARCH RESULTS
======================================== */

.global-results {
  display: flex;
  flex-direction: column;
  gap: calc(10px * var(--ui-scale));
  margin-top: calc(14px * var(--ui-scale));
}

.global-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: calc(12px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
}

/* ========================================
   COMPLETION CELL (muhadreen table)
======================================== */

.completion-cell {
  text-align: center;
  vertical-align: middle;
  font-weight: 700;
}

/* ========================================
   DASHBOARD OPERATIONS (inside dashboard)
======================================== */

.dashboard-operations-wrapper {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

.dashboard-operations-list {
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
}

/* ========================================
   PRINT STYLES
======================================== */

@media print {
  body {
    background: var(--white) !important;
  }

  button {
    display: none !important;
  }

  .card {
    box-shadow: none !important;
    border: 1px solid var(--border);
  }

  table {
    width: 100%;
    border-collapse: collapse;
  }

  th,
  td {
    border: 1px solid var(--border);
    padding: 8px;
    font-size: 11px;
  }
}
/* app: styles/layout.css */
/* ========================================
   LAYOUT — HEADER / NAVIGATION / PAGE CONTAINER
   التخطيط العام للصفحة
======================================== */

/* ========================================
   APP FRAME — the navigation and its one header action
   Ticket 97. The band and the tab strip are the shared UiNavBar block. The
   sign-out is the one control the block has no slot for, so the frame keeps
   it in a fixed place in the band's corner — the band's own content (logo,
   title, identity) is centred, so the corner stays clear at every width.
======================================== */

.app-nav {
  position: relative;
}

.app-header-actions {
  position: absolute;
  /* The sign-out sits in the band's corner; the band's top padding now
       carries --safe-top (ui.css .ui-nav-band), so this offset must carry it
       too or the control would stay under the status bar. 0px on a device
       without a safe area, so desktop is unchanged (ticket uifix, item 1). */
  top: max(12px, calc(var(--safe-top) + 12px));
  inset-inline-start: calc(16px * var(--ui-scale));
  z-index: 2;
}

/* The same quiet account action the app header carried before: transparent
   with a thin translucent outline, visibly secondary to the office title.
   Two classes, so it still wins over the mobile .btn sizing. */
.app-signout.btn {
  min-height: calc(27px * var(--ui-scale));
  min-width: 0;
  padding: calc(3px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-size: var(--font-xs);
  background: transparent;
  color: var(--status-neutral-fg);
  border: 1px solid var(--on-dark-a60);
  box-shadow: none;
}

.app-signout.btn:hover {
  background: var(--on-dark-a10);
  border-color: var(--on-dark-a60);
}

@media (max-width: 768px) {
  .app-header-actions {
    /* The compact step resets the offset, so it carries the safe-area
           term too (ticket uifix, item 1). */
    top: max(8px, calc(var(--safe-top) + 8px));
    inset-inline-start: 12px;
  }
}

@media (max-width: 480px) {
  .app-signout.btn {
    padding: 3px 8px;
  }
}

/* ========================================
   DIGITAL CLOCK
   The clock's base rule lives in clock.css; only its glass overlay is here.
======================================== */

.digital-clock::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(135deg, var(--on-dark-a10), transparent);
  pointer-events: none;
}

/* ========================================
   PAGE CONTAINER
======================================== */

.page-container {
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-lg) var(--space-xl) calc(40px * var(--ui-scale));
  padding-left: calc(max(20px, var(--safe-left)) * var(--ui-scale));
  padding-right: calc(max(20px, var(--safe-right)) * var(--ui-scale));
  display: flex;
  flex-direction: column;
  gap: calc(16px * var(--ui-scale));
}

.page-container > * {
  animation: fadePage 0.2s ease;
}

/* ========================================
   PAGE HEADER (title + actions row)
======================================== */

.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(12px * var(--ui-scale));
  flex-wrap: wrap;
  margin-bottom: calc(4px * var(--ui-scale));
}

.page-header-title {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--ui-scale));
}

.page-header-title span {
  font-size: var(--font-lg);
}

.page-header-title h1 {
  font-size: var(--font-xl);
  color: var(--heading-text);
  font-weight: 800;
}

.page-header-actions {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
}

/* ========================================
   ACTION GROUP
======================================== */

.action-group {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  flex-wrap: wrap;
}

/* ========================================
   OFFLINE INDICATOR
   شريط يظهر فقط عند انقطاع الإنترنت

   Ticket 97 (follow-up): the indicator is rendered in the frame's
   navigation status slot (UiNavBar's `status`, styles/ui.css
   `.ui-nav-status`), which reserves its place — so its base rule is now
   static (no fixed positioning of its own). Its text, chrome and the rules
   for when it shows are untouched.

   On every screen WITHOUT the frame it is still the fixed pill it was
   before the ticket: the same position rules, restored under the
   `.offline-indicator--floating` modifier (the wrapper App.jsx renders it
   in). The in-slot rendering keeps the static base rule.

   Clickability (ticket 97, round 4): the controls the indicator carries
   (the «التعديلات» button) must work in both renderings. The floating
   surface is `pointer-events: none` (so the pill never blocks what is under
   it); the slot carries no `pointer-events` rule (it is in normal flow and
   overlays nothing). The controls get `pointer-events: auto` explicitly.
======================================== */

.offline-indicator {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  background: var(--surface-warning);
  border: 1px solid var(--gold);
  color: var(--warning-text);
  font-weight: 700;
  font-size: var(--font-xs);
  padding: calc(6px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border-radius: calc(999px * var(--ui-scale));
  box-shadow: var(--shadow-lg);
  white-space: nowrap;
}

/* The fixed pill the indicator was before the ticket — every position rule
   it had, unchanged, so a frameless screen shows it exactly where it always
   did. `pointer-events: none` is the floating surface's one job: the pill
   must never block a click on whatever lies under it. The pill inside this
   wrapper inherits it; the controls it carries get their own
   `pointer-events` back below. */
.offline-indicator--floating {
  position: fixed;
  top: max(8px, calc(var(--safe-top) + 8px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 9100;
  pointer-events: none;
}

/* The indicator may carry controls, and they must be clickable in BOTH
   renderings. In the frame's slot the pill is in the normal flow (it overlays
   nothing), so the base rule above carries no `pointer-events` at all — the
   controls inherit `auto` there. Inside the floating pill the surface is
   `pointer-events: none`, so the controls need it back explicitly.

   Today no interactive descendant sits inside the indicator (the pending
   notice moved to the page's content area, ticket fx-pending). The list below
   keeps any link or control a later ticket adds inside the indicator working
   too. (The modals it opens are portaled to <body> — Modal.jsx:213 — so they
   are never inside this element and need no rule here.) */
.offline-indicator button,
.offline-indicator a[href],
.offline-indicator input,
.offline-indicator select,
.offline-indicator textarea,
.offline-indicator [role='button'] {
  pointer-events: auto;
}

.offline-indicator-dot {
  width: calc(8px * var(--ui-scale));
  height: calc(8px * var(--ui-scale));
  border-radius: 50%;
  background: var(--gold);
  flex-shrink: 0;
}

/* ========================================
   APP UPDATE PROMPT
   شريط يظهر عند توفر نسخة جديدة من التطبيق
   The service worker has activated a new build; this is the one tap that
   reloads into it. Fixed above everything so it is seen on any route.
======================================== */

.app-update-prompt {
  position: fixed;
  top: max(8px, calc(var(--safe-top) + 8px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 9200;
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  background: var(--gold);
  border: 1px solid var(--gold-light);
  color: var(--primary-dark);
  font-weight: 700;
  font-size: var(--font-xs);
  padding: calc(8px * var(--ui-scale)) calc(16px * var(--ui-scale));
  border-radius: calc(999px * var(--ui-scale));
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  white-space: nowrap;
}

.app-update-prompt:hover {
  background: var(--gold-light);
}

/* app: styles/buttons.css */
/* ========================================
   BUTTONS
   الأزرار وعناصر التفاعل
======================================== */

.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(5px * var(--ui-scale));
  min-width: calc(64px * var(--ui-scale));
  min-height: calc(32px * var(--ui-scale));
  padding: calc(5px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border: none;
  outline: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: var(--font-sm);
  font-weight: 700;
  letter-spacing: 0.2px;
  box-shadow: var(--shadow);
  transition: all 0.18s ease;
}

.btn::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--on-dark-a10);
  opacity: 0;
  transition: 0.18s;
}

.btn:hover {
  transform: translateY(-1px);
  filter: brightness(1.02);
}

.btn:hover::after {
  opacity: 1;
}

.btn:active {
  transform: scale(0.96);
}

/* ========================================
   BUTTON VARIANTS
======================================== */

.btn-light {
  background: var(--white);
  color: var(--primary);
  border: 1px solid var(--border);
  box-shadow: none;
}

/* WhatsApp brand green, joined to the kit button. The compound selector
   outranks the kit's ghost variant, so the brand colour wins wherever the
   marker class is used. */
.ui-btn.btn-whatsapp {
  background: var(--whatsapp);
  color: var(--status-neutral-fg);
  border-color: transparent;
}

/* ========================================
   VISUALLY-DISABLED ACTION BUTTON
   Used when a button should appear inactive
   but still fire onClick (e.g. to show a
   toast explaining why the action is not
   available). Unlike HTML [disabled], this
   does not block pointer events.
======================================== */

.btn-action-disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.btn-action-disabled:hover {
  transform: none !important;
  filter: none !important;
}

.btn-action-disabled::after {
  display: none !important;
}

.btn-action-disabled:active {
  transform: none !important;
}

/* ========================================
   MAIN CARD
======================================== */

.main-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  padding: calc(12px * var(--ui-scale));
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--on-dark-a60);
  box-shadow: var(--shadow);
  transition: box-shadow 0.18s ease;
}

.main-card:hover {
  box-shadow: var(--shadow-lg);
}

.main-card:not(:last-child) {
  margin-bottom: calc(12px * var(--ui-scale));
}

.main-card > *:last-child {
  margin-bottom: 0;
}

.main-card::before {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: calc(3px * var(--ui-scale));
  background: linear-gradient(90deg, var(--gold), var(--gold-light));
}
/* app: styles/inputs.css */
/* ========================================
   INPUTS & FORMS
   حقول الإدخال والنماذج
======================================== */

.input {
  width: 100%;
  height: calc(36px * var(--ui-scale));
  padding: 0 calc(10px * var(--ui-scale));
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  outline: none;
  background: var(--white);
  color: var(--text);
  font-size: var(--font-sm);
  font-weight: 500;
  transition: all 0.18s ease;
}

.input:hover {
  border-color: var(--gold-a40);
}

.input:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold-a08);
}

.input::placeholder {
  color: var(--text-muted);
}

/* ========================================
   INPUT LABEL
======================================== */

.input-label {
  display: block;
  margin-bottom: calc(5px * var(--ui-scale));
  margin-top: calc(2px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--heading-text);
}

/* ========================================
   CUSTOM SELECT
======================================== */

.custom-select {
  width: 100%;
  height: calc(36px * var(--ui-scale));
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--white);
  padding: 0 calc(10px * var(--ui-scale));
  font-size: var(--font-sm);
  font-weight: 500;
  color: var(--text);
  outline: none;
  transition: all 0.18s ease;
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  background-image:
    linear-gradient(45deg, transparent 50%, var(--text-muted) 50%),
    linear-gradient(135deg, var(--text-muted) 50%, transparent 50%);
  background-position:
    calc(100% - 14px) 16px,
    calc(100% - 8px) 16px;
  background-size:
    5px 5px,
    5px 5px;
  background-repeat: no-repeat;
}

.custom-select:focus {
  border-color: var(--gold);
  box-shadow: 0 0 0 2px var(--gold-a08);
}

.custom-select option {
  background: var(--white);
  color: var(--text);
  font-size: var(--font-sm);
}

/* ========================================
   SEARCH WRAPPER
======================================== */

.search-wrapper {
  display: flex;
  align-items: stretch;
  gap: calc(8px * var(--ui-scale));
  width: 100%;
  flex: 1;
}

.search-wrapper .ui-field-input {
  width: 100%;
  flex: 1;
  min-width: calc(200px * var(--ui-scale));
}

.search-wrapper .ui-field-input::placeholder {
  color: var(--text-muted);
  opacity: 1;
}

.search-wrapper .btn {
  min-width: calc(80px * var(--ui-scale));
}

/* ========================================
   STATIC FIELD (read-only display)
======================================== */

.static-field {
  min-height: calc(34px * var(--ui-scale));
  display: flex;
  align-items: center;
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  font-weight: 600;
  font-size: var(--font-sm);
  word-break: break-word;
  line-height: 1.5;
  color: var(--text);
}
/* app: styles/modals.css */
/* ========================================
   MODALS — النوافذ المنبثقة
======================================== */

.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 9400;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: calc(30px * var(--ui-scale));
  padding-bottom: calc(30px * var(--ui-scale));
  overflow-y: auto;
  background: var(--scrim);
  backdrop-filter: blur(4px);
  animation: fadeOverlay 0.22s ease;
  /* Ensure it's never accidentally hidden */
  visibility: visible;
  opacity: 1;
}

@keyframes fadeOverlay {
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
}

/* The dialog frame (the chosen prototype's .modal): a head, a body that
   scrolls inside while the page behind stays locked, and an actions row. */
.modal-content {
  position: relative;
  z-index: 9100;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: calc(820px * var(--ui-scale));
  max-height: 90vh;
  max-height: 90dvh;
  overflow: hidden;
  padding: 0;
  border-radius: var(--radius-xl);
  background: var(--modal-bg);
  border: 1px solid var(--on-dark-a60);
  box-shadow: var(--shadow-lg);
  animation: modalIn 0.22s ease;
}

@keyframes modalIn {
  from {
    opacity: 0;
    transform: translateY(-16px) scale(0.98);
  }

  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-shrink: 0;
  padding: calc(16px * var(--ui-scale)) calc(20px * var(--ui-scale));
  border-bottom: 1px solid var(--modal-border);
  background: linear-gradient(180deg, var(--modal-header-from), var(--modal-header-to));
  position: sticky;
  top: 0;
  z-index: 2;
}

.modal-title {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  font-size: var(--font-lg);
  font-weight: 800;
  color: var(--modal-title-color);
}

/* The close control is the kit's icon button, grown to a 44px touch target
   (its accessible name is the button's own label). */
.modal-close.ui-btn--icon {
  min-width: 44px;
  min-height: 44px;
}

.modal-body {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-lg) var(--space-xl);
}

.modal-body .input {
  width: 100%;
}

.modal-body .btn {
  min-width: calc(100px * var(--ui-scale));
}

/* The form stack a dialog's UiFormField blocks sit in. */
.modal-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* A field with its own trailing control (the duration calculator). */
.modal-date-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-sm);
}

.modal-date-row .ui-field {
  flex: 1;
}

.modal-date-row .ui-btn--icon {
  min-height: 40px;
}

/* Three equal quick-pick controls. */
.modal-quick-row {
  display: flex;
  gap: var(--space-sm);
}

.modal-quick-row .ui-btn {
  flex: 1;
}

/* The actions row the frame renders when a dialog gives it one. */
.modal-foot {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  flex-shrink: 0;
  padding: 14px var(--space-xl);
  border-top: 1px solid var(--modal-border);
  background: var(--card);
}

/* ========================================
   CONFIRM MODAL
======================================== */

.confirm-text {
  margin-bottom: calc(16px * var(--ui-scale));
  text-align: center;
  color: var(--text-muted);
  font-size: var(--font-lg);
  line-height: 1.8;
}

/* ========================================
   GLOBAL SEARCH & CHANGE LOG (ticket 98-7b)
   The two dialog screens that moved onto the kit's blocks. Colours and sizes
   come only from variables.css, so the .dark-mode tokens carry both screens.
======================================== */

/* The Change Log's two filters sit on one wrapping row above the list. */
.change-log-filters {
  display: flex;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
}

/* Each filter takes an equal share of the row, and stacks on a narrow screen
   (the row wraps) instead of squeezing the select. */
.change-log-filter {
  flex: 1 1 220px;
}

/* The client an entry was about: the quiet line above the entry's own body. */
.change-log-client {
  font-size: var(--font-xs);
  color: var(--text-muted);
}

/* «تحميل المزيد» keeps its own centred row under the list. */
.change-log-more {
  margin-top: var(--space-md);
  text-align: center;
}

/* app: styles/toast.css */
/* ========================================
   TOAST NOTIFICATIONS — إشعارات النظام
======================================== */

.toast-wrapper {
  position: fixed;
  top: max(16px, calc(var(--safe-top) + 12px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 9500;
  pointer-events: none;
}

.toast-box {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  width: auto;
  max-width: calc(380px * var(--ui-scale));
  min-width: calc(200px * var(--ui-scale));
  padding: calc(9px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border-radius: var(--radius-md);
  color: var(--status-neutral-fg);
  font-size: var(--font-sm);
  font-weight: 600;
  backdrop-filter: blur(12px);
  border: 1px solid var(--on-dark-a10);
  box-shadow: var(--shadow-lg);
  animation: toastShow 0.2s ease;
  pointer-events: auto;
}

.toast-box span {
  line-height: 1.4;
}

.toast-box.success {
  background: var(--green);
}

.toast-box.error {
  background: var(--red);
}

.toast-box.warning {
  background: var(--gold);
  color: var(--primary-dark);
}

@keyframes toastShow {
  from {
    opacity: 0;
    transform: translateY(-8px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}
/* app: styles/settings.css */
/* ========================================
   SETTINGS PANEL STYLES — v4
   Card-based SaaS design (Notion / Linear style)
======================================== */

/* ════════════════════════════════════════
   CARD GROUPS (ticket #212)
   مجموعات بطاقات الإعدادات — كل مجموعة لوحة معنونة، والبطاقات
   شبكة البطاقات نفسها داخلها
════════════════════════════════════════ */
.settings-group {
  margin-top: calc(16px * var(--ui-scale));
}

.settings-cards-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(calc(260px * var(--ui-scale)), 1fr));
  gap: calc(12px * var(--ui-scale));
}

.settings-category-card {
  display: flex;
  align-items: center;
  gap: calc(14px * var(--ui-scale));
  padding: calc(16px * var(--ui-scale)) calc(18px * var(--ui-scale));
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 12px);
  cursor: pointer;
  text-align: right;
  transition:
    box-shadow 0.2s ease,
    border-color 0.2s ease,
    transform 0.15s ease;
  position: relative;
  width: 100%;
  box-shadow: var(--shadow);
}
.settings-category-card:hover {
  border-color: var(--gold);
  box-shadow: var(--shadow-lg);
  transform: translateY(-1px);
}
.settings-category-card:active {
  transform: translateY(0);
  box-shadow: var(--shadow);
}

.settings-card-icon-wrap {
  flex-shrink: 0;
  width: calc(42px * var(--ui-scale));
  height: calc(42px * var(--ui-scale));
  border-radius: var(--radius-md, 10px);
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold);
}

.settings-card-body {
  flex: 1;
  min-width: 0;
}
.settings-card-title {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--primary);
  margin-bottom: calc(2px * var(--ui-scale));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.settings-card-desc {
  display: block;
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  color: var(--text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.settings-card-badge {
  flex-shrink: 0;
  min-width: calc(20px * var(--ui-scale));
  height: calc(20px * var(--ui-scale));
  padding: 0 calc(6px * var(--ui-scale));
  border-radius: calc(10px * var(--ui-scale));
  background: var(--gold);
  color: var(--status-neutral-fg);
  font-size: var(--font-2xs);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.settings-card-arrow {
  flex-shrink: 0;
  color: var(--text-muted);
  transition: transform 0.2s;
}
.settings-category-card:hover .settings-card-arrow {
  transform: translateX(-3px);
  color: var(--gold);
}

/* ════════════════════════════════════════
   BROADCAST SECTION (ticket 98-3a)
   قسم إرسال تنبيه للفريق
════════════════════════════════════════ */
.settings-broadcast-counter {
  text-align: left;
  font-size: var(--font-xs);
  color: var(--text-muted);
}
.settings-broadcast-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}
.settings-broadcast-modes {
  display: flex;
  gap: calc(14px * var(--ui-scale));
}
.settings-broadcast-list {
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--ui-scale));
}
.settings-broadcast-option {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  font-size: var(--font-sm);
  color: var(--text);
}
.settings-broadcast-note {
  margin: 0;
  font-size: var(--font-xs);
  color: var(--text-muted);
}
.settings-broadcast-actions {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--ui-scale));
  margin-top: calc(12px * var(--ui-scale));
}
.settings-broadcast-result {
  font-size: var(--font-sm);
  color: var(--green);
}

/* The one action a section keeps outside its group (ticket 98-3a): the
   reset-password control and the cleanup control. */
.settings-section-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin-top: var(--space-md);
}

/* ════════════════════════════════════════
   MODAL CONTENT
════════════════════════════════════════ */
.settings-modal-body {
  padding: calc(4px * var(--ui-scale)) 0 calc(8px * var(--ui-scale));
  display: flex;
  flex-direction: column;
  gap: calc(4px * var(--ui-scale));
}

.settings-modal-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(10px * var(--ui-scale)) 0;
  border-bottom: 1px solid var(--border);
  gap: calc(16px * var(--ui-scale));
}
.settings-modal-row:last-child {
  border-bottom: none;
}
.settings-modal-row-label {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  font-size: var(--font-sm, 13px);
  font-weight: 500;
  color: var(--text);
}
.settings-row-hint {
  font-size: var(--font-2xs);
  color: var(--text-muted);
  font-weight: 400;
}
.settings-modal-row-control {
  flex-shrink: 0;
}

.settings-modal-divider {
  height: 1px;
  background: var(--border);
  margin: calc(8px * var(--ui-scale)) 0;
}

.settings-hint-text {
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  color: var(--text-muted);
  line-height: 1.7;
  margin: calc(6px * var(--ui-scale)) 0 0;
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
  background: var(--surface-subtle);
  border-radius: var(--radius-sm, 6px);
  border-right: 3px solid var(--gold);
}

.settings-action-group {
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  margin-top: calc(8px * var(--ui-scale));
}

.settings-full-btn {
  width: 100%;
  justify-content: center;
}

/* ════════════════════════════════════════
   SECTION LISTS (ticket 98-3b)
   قوائم الأقسام — صفوف النموذج الأولي
════════════════════════════════════════ */

/* The prototype's rows, as one plain list. The surface is the section's own
   group (the kit's card), so no second frame is written here. */
.settings-list {
  display: flex;
  flex-direction: column;
  margin: 0;
  padding: 0;
  list-style: none;
}
.settings-list-row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-sm);
  padding: calc(10px * var(--ui-scale)) 0;
  border-bottom: 1px solid var(--border);
  text-align: right;
}
.settings-list-row:last-child {
  border-bottom: none;
}
/* The row's own block: a long error message or device name wraps inside it
   instead of widening the page. */
.settings-list-main {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}
.settings-list-title {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--heading-text);
}
.settings-list-meta {
  font-size: var(--font-xs);
  color: var(--text-muted);
}
.settings-list-actions {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-inline-start: auto;
}
/* The prototype's `.chip` states, painted with the app's status tokens. */
.settings-list-chip {
  display: inline-flex;
  align-items: center;
  gap: calc(5px * var(--ui-scale));
  border-radius: var(--radius-full);
  padding: calc(2px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
  white-space: nowrap;
}
.settings-list-chip.is-warn {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}
.settings-list-chip.is-danger {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}
.settings-list-chip.is-info {
  background: var(--status-info-bg);
  color: var(--status-info-fg);
}
/* An active author (ticket 98-3c) — the fourth state, on its own token pair
   so dark mode follows like the other three. */
.settings-list-chip.is-ok {
  background: var(--status-ok-bg);
  color: var(--status-ok-fg);
}
/* The log entry's stack: monospace and never wider than its row. */
.settings-list-stack {
  font-family: monospace;
  font-size: var(--font-2xs);
  color: var(--text-muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* «التغييرات المعلقة» (ticket 98-3c): the refresh control's own row, then
   the prototype's rows and their four states. */
.settings-pending {
  display: block;
  margin-top: var(--space-lg);
}
.settings-pending-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

/* The error-log viewer's own scroll frame, as before. */
.settings-logs {
  max-height: calc(450px * var(--ui-scale));
  overflow-y: auto;
}

/* The unresolved restore rows' own block below the backup controls. */
.settings-unresolved {
  display: block;
  margin-top: var(--space-lg);
}
.settings-unresolved-amount {
  max-width: calc(160px * var(--ui-scale));
}

/* «قراءات تحتاج تصحيحا» (ticket #202): the tick wraps the row's text, so
   the whole line is the target. */
.settings-correction-choice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  flex: 1;
  min-width: 0;
  cursor: pointer;
  text-align: right;
}

/* ── Monitoring Chart ── */
.settings-usage-chart {
  display: flex;
  align-items: flex-end;
  gap: calc(4px * var(--ui-scale));
  height: calc(56px * var(--ui-scale));
  margin: calc(12px * var(--ui-scale)) 0;
  padding: 0 calc(2px * var(--ui-scale));
}
.settings-chart-col {
  flex: 1;
  display: flex;
  align-items: flex-end;
  height: 100%;
}
.settings-chart-bar {
  width: 100%;
  background: var(--gold);
  border-radius: calc(3px * var(--ui-scale)) calc(3px * var(--ui-scale)) 0 0;
  min-height: calc(4px * var(--ui-scale));
  transition: height 0.3s ease;
  opacity: 0.85;
}
.settings-chart-bar:hover {
  opacity: 1;
}

/* ── Save All button (ticket 98-3a) ── */
.settings-save-all {
  margin-top: calc(28px * var(--ui-scale));
  text-align: center;
}

/* ════════════════════════════════════════
   TOGGLE SWITCH
════════════════════════════════════════ */
.switch {
  position: relative;
  display: inline-block;
  width: calc(48px * var(--ui-scale));
  height: calc(24px * var(--ui-scale));
}
.switch input {
  opacity: 0;
  width: 0;
  height: 0;
}
.slider {
  position: absolute;
  cursor: pointer;
  inset: 0;
  background: var(--border);
  transition: 0.2s;
  border-radius: calc(34px * var(--ui-scale));
}

.slider:before {
  content: '';
  position: absolute;
  height: calc(18px * var(--ui-scale));
  width: calc(18px * var(--ui-scale));
  left: calc(3px * var(--ui-scale));
  bottom: calc(3px * var(--ui-scale));
  background: var(--status-neutral-fg);
  transition: 0.2s;
  border-radius: 50%;
  box-shadow: var(--shadow);
}
input:checked + .slider {
  background: var(--gold);
}
input:checked + .slider:before {
  transform: translateX(calc(24px * var(--ui-scale)));
}

/* ════════════════════════════════════════
   STATS GRID (reused in modal)
════════════════════════════════════════ */
.stats-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(10px * var(--ui-scale));
  margin-bottom: calc(8px * var(--ui-scale));
}
.stat-card {
  background: var(--surface-subtle);
  border-radius: var(--radius-md, 8px);
  padding: calc(12px * var(--ui-scale));
  text-align: center;
  border: 1px solid var(--border);
}
.stat-card .stat-number {
  font-size: var(--font-xl, 20px);
  font-weight: 800;
  color: var(--gold);
  line-height: 1.2;
}
.stat-card .stat-label {
  font-size: var(--font-xs, 10px);
  color: var(--text-muted);
  margin-top: calc(4px * var(--ui-scale));
}

/* ════════════════════════════════════════
   USERS PANEL (ticket 98-3d)
   لوحة المستخدمين — صفوف النموذج الأولي
════════════════════════════════════════ */

/* The two sections of the Users screen, one under the other. */
.users-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.users-section,
.users-role-defaults {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The one editor box the name/Role form, the invite form, the Role defaults
   editor and the Exceptions editor share. */
.users-editor-box {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg-secondary);
}

.users-editor-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The Permission catalogue as tick boxes, shared by both editors. */
.users-perm-list {
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--ui-scale));
}

.users-perm-option {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  font-size: var(--font-sm);
  cursor: pointer;
}

.users-perm-option.is-locked {
  cursor: default;
}

/* The permission's name takes the free space beside its tick box. */
.users-perm-label {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* A box that differs from the Role: «+» added, «−» removed. */
.users-perm-added {
  color: var(--green);
  font-weight: 700;
}

.users-perm-removed {
  color: var(--red);
  font-weight: 700;
}

/* The delete dialog's content: the person, what is removed, what stays, the
   typed-email field and the two controls. The size is set once here and the
   lines inherit it. */
.users-delete {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  font-size: var(--font-sm);
}

.users-delete-list {
  margin: 0;
  padding-inline-start: calc(20px * var(--ui-scale));
}

.users-delete-warning {
  margin: 0;
  color: var(--red);
}

/* ════════════════════════════════════════
   DARK MODE
════════════════════════════════════════ */
/* The card, the stat card and the labels now read the theme tokens, so their
   dark overrides are gone. The hint box keeps its own wash. */
.dark-mode .settings-hint-text {
  background: var(--on-dark-a10);
}

/* ════════════════════════════════════════
   MOBILE
════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Two columns on a phone (ticket 98-3a): the cards stay side by side down
       to the narrow step, and the section titles and descriptions wrap inside
       their own card instead of being cut off. */
  .settings-cards-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .settings-category-card {
    min-height: 44px;
  }
  .settings-card-title,
  .settings-card-desc {
    white-space: normal;
    overflow: visible;
  }
  .stats-grid {
    grid-template-columns: 1fr 1fr;
  }
  .settings-modal-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
}

/* One column at the narrow step (ticket 98-3a). */
@media (max-width: 360px) {
  .settings-cards-grid {
    grid-template-columns: 1fr;
  }
}

/* app: styles/clock.css */
/* ========================================
   CLOCK STYLES
======================================== */

.digital-clock {
  position: fixed;
  top: max(12px, calc(var(--safe-top) + 8px));
  left: max(16px, calc(var(--safe-left) + 8px));
  z-index: 9000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-width: calc(90px * var(--ui-scale));
  padding: calc(6px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: linear-gradient(135deg, var(--primary-dark), var(--primary));
  color: var(--status-neutral-fg);
  font-size: var(--font-sm);
  font-weight: 800;
  letter-spacing: 1px;
  direction: ltr;
  user-select: none;
  backdrop-filter: blur(10px);
  border: 1px solid var(--on-dark-a10);
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  transition: all 0.18s ease;
}

.digital-clock:hover {
  opacity: 0.85;
  transform: scale(0.98);
}

.digital-clock-time {
  font-size: max(var(--ui-text-min), calc(13px * var(--ui-text-scale)));
  font-weight: 700;
  letter-spacing: 1px;
  direction: ltr;
  color: var(--status-neutral-fg);
  white-space: nowrap;
}

.digital-clock-date {
  font-size: max(var(--ui-text-min), calc(9px * var(--ui-text-scale)));
  font-weight: 500;
  opacity: 0.75;
  direction: ltr;
  color: var(--status-neutral-fg);
}

/* Date Calculator Modal - Small */
.calculator-modal .modal-content {
  max-width: calc(320px * var(--ui-scale));
}

.calculator-container {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

.calculator-input {
  margin-bottom: calc(4px * var(--ui-scale));
}

.calculator-input-label {
  display: block;
  margin-bottom: calc(4px * var(--ui-scale));
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  font-weight: 700;
  color: var(--heading-text);
}

.calculator-quick {
  display: flex;
  gap: calc(8px * var(--ui-scale));
  justify-content: center;
}

.calculator-quick-btn {
  background: var(--surface-subtle);
  border: none;
  border-radius: calc(6px * var(--ui-scale));
  padding: calc(4px * var(--ui-scale)) calc(12px * var(--ui-scale));
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  font-weight: 600;
  cursor: pointer;
  transition: 0.18s;
  color: var(--primary);
}

.calculator-quick-btn:hover {
  background: var(--gold);
  color: var(--primary-dark);
  transform: translateY(-1px);
}

.calculator-result {
  background: var(--gold-a15);
  padding: calc(10px * var(--ui-scale));
  border-radius: calc(8px * var(--ui-scale));
  text-align: center;
  border: 1px solid var(--gold);
}

.calculator-result-date {
  font-size: max(var(--ui-text-min), calc(14px * var(--ui-text-scale)));
  font-weight: 800;
  color: var(--gold);
}

.dark-mode .calculator-quick-btn {
  color: var(--text);
}
/* app: styles/ui.css */
/* ========================================
   SHARED UI KIT — ui.css
   حزمة العناصر المشتركة

   The first building blocks of the redesign (ticket 94). Every selector here
   is prefixed "ui-" so nothing that already exists can be restyled by
   accident. Colours, radii, shadows and fonts come only from the tokens in
   variables.css, so light and dark follow automatically and no new colour is
   introduced. Right to left with logical properties (inline-start / end).
   Desktop is spacious, phone is compact.

   Theme-safe text: several tokens flip between themes, so the kit uses them
   deliberately. --text / --text-muted for text on a surface; --white / --card
   for surfaces; --primary / --primary-dark for filled dark surfaces; and
   --status-neutral-fg (light in BOTH themes) for text on a filled surface.
   Using --white as text, or --primary as text on a surface, would disappear
   in dark mode, so neither appears here.
======================================== */

/* ========================================
   SCREEN-READER ONLY
======================================== */

.ui-sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ========================================
   PAGE FRAME
   الإطار العام للصفحة

   The frame takes the current app's own page chrome: the app paints the page
   area with the body gradient (reset.css `body`), and its content column is
   `.page-container` (layout.css) — same max width, same padding, same rhythm.
======================================== */

.ui-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  min-height: 100%;
  background: linear-gradient(180deg, var(--body-bg-start) 0%, var(--body-bg-end) 100%);
  color: var(--text);
}

.ui-page-inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-lg) var(--space-xl) calc(40px * var(--ui-scale));
  padding-inline-start: max(var(--space-xl), var(--safe-left));
  padding-inline-end: max(var(--space-xl), var(--safe-right));
}

.ui-page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
}

.ui-page-title {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  color: var(--status-neutral-fg);
  font-size: var(--font-xl);
  font-weight: 800;
  line-height: 1.3;
}

.ui-page-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.ui-page-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* ========================================
   NAVIGATION BAR
   الترويسة وشريط الملاحة

   Built from the current app's own header and tab bar (Layout.jsx +
   layout.css): a dark primary gradient band with the top radius and the
   centred logo/title/identity of `.main-header`, then the white tab bar of
   `.tabs-container` with the icon above the label, `.tab-item`'s primary text
   and gold active underline. The colours come from the same tokens, so light
   and dark follow.
======================================== */

.ui-nav {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  color: var(--status-neutral-fg);
}

.ui-nav-band {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(6px * var(--ui-scale));
  width: 100%;
  max-width: var(--container-max);
  margin: 0 auto;
  padding: calc(10px * var(--ui-scale)) calc(16px * var(--ui-scale)) calc(12px * var(--ui-scale));
  /* The app runs edge-to-edge (viewport-fit=cover + a translucent status
       bar), so the band's top sits UNDER the status bar / Dynamic Island.
       The old header padded its top the same way (.main-header in layout.css);
       --safe-top is 0px on a device without a safe area, so desktop is
       unchanged. Ticket uifix, item 1. */
  padding-top: max(10px, calc(var(--safe-top) + 10px));
  padding-inline-start: calc(max(16px, var(--safe-left)) * var(--ui-scale));
  padding-inline-end: calc(max(16px, var(--safe-right)) * var(--ui-scale));
}

.ui-nav-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(76px * var(--ui-scale));
  height: calc(76px * var(--ui-scale));
  flex-shrink: 0;
}

.ui-nav-logo-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

.ui-nav-title {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  max-width: calc(1100px * var(--ui-scale));
  margin: 0;
  color: var(--status-neutral-fg);
  text-align: center;
  font-size: var(--font-xl);
  font-weight: 800;
  line-height: 1.2;
  letter-spacing: -0.3px;
}

.ui-nav-identity {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  max-width: 100%;
}

/* The signed-in name reads as a handwritten signature, exactly as the app
   header does (layout.css `.header-identity-name`). */
.ui-nav-user {
  font-family: 'Aref Ruqaa', 'Cairo', sans-serif;
  color: var(--status-neutral-fg);
  font-size: var(--font-lg);
  font-weight: 700;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* The `status` slot (ticket 97): when UiNavBar is given a `status` node it
   takes the built-in connectivity mark's place in the identity row. The slot
   holds a fixed height — the height of the offline pill it carries (6px + 6px
   padding, 1px + 1px border, 11px × 1.6 line ≈ 32px, all scaled with the
   tokens) — so the identity row, and with it the band and the tab strip below
   it, do not move or resize when the indicator appears or disappears or its
   counter changes from nothing to a number. The reserve is at every width; the
   narrower steps only shrink the name (`.ui-nav-user` at ≤768), never the
   slot. */
.ui-nav-status {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  min-height: calc(32px * var(--ui-scale));
}

.ui-nav-tabs {
  display: flex;
  align-items: stretch;
  width: 100%;
  max-width: var(--container-max);
  min-height: calc(52px * var(--ui-scale));
  margin: var(--space-lg) auto;
  overflow: hidden;
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
  backdrop-filter: blur(4px);
  box-shadow: var(--shadow);
}

.ui-nav-tab {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 1;
  min-width: 0;
  min-height: calc(52px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(6px * var(--ui-scale));
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--text);
  font-size: var(--font-sm);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: all 0.18s ease;
}

.ui-nav-tab:hover {
  background: color-mix(in srgb, var(--gold) 8%, transparent);
  color: var(--gold);
}

.ui-nav-tab.is-active {
  background: color-mix(in srgb, var(--gold) 10%, transparent);
  color: var(--gold);
  border-bottom: 2px solid var(--gold);
}

.ui-nav-tab-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(3px * var(--ui-scale));
}

.ui-nav-badge {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: calc(16px * var(--ui-scale));
  height: calc(16px * var(--ui-scale));
  padding: 0 calc(4px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--red);
  color: var(--status-neutral-fg);
  font-size: var(--font-2xs);
  font-weight: 700;
}

/* ========================================
   IDENTITY BAR
   شريط هوية الموكل والقضية

   A quiet dark band in the app's own language: the same primary gradient the
   header band carries (client.css `.client-header-band`), with the same gold
   accent.
======================================== */

.ui-identity {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding: calc(10px * var(--ui-scale)) var(--space-xl);
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  color: var(--status-neutral-fg);
  border-bottom: 2px solid var(--gold);
}

.ui-identity-name {
  font-size: var(--font-lg);
  font-weight: 800;
  color: var(--status-neutral-fg);
}

.ui-identity-sep {
  width: 1px;
  height: calc(15px * var(--ui-scale));
  background: var(--gold);
}

.ui-identity-fact {
  display: inline-flex;
  align-items: center;
  gap: calc(5px * var(--ui-scale));
  font-size: var(--font-sm);
  color: var(--gold-light);
}

.ui-identity-fact b {
  color: var(--status-neutral-fg);
  font-weight: 800;
}

.ui-identity-subject {
  flex: 1 1 calc(240px * var(--ui-scale));
  min-width: calc(120px * var(--ui-scale));
  font-size: var(--font-sm);
  color: var(--gold-light);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Compact (phone) form (ticket 95): the name and the case number stay on
   the bar, and the year, the court and the case subject sit behind a
   disclosure that opens on a tap. The desktop form above is untouched. */
.ui-identity--compact {
  align-items: center;
  gap: var(--space-sm);
}

.ui-identity--compact .ui-identity-name {
  font-size: var(--font-md);
}

.ui-identity-toggle {
  display: inline-flex;
  align-items: center;
  gap: calc(5px * var(--ui-scale));
  min-height: 44px;
  padding: 0 var(--space-md);
  border: 1px solid var(--gold);
  border-radius: var(--radius-full);
  background: color-mix(in srgb, var(--gold) 16%, transparent);
  color: var(--gold-light);
  font-size: var(--font-sm);
  font-weight: 700;
  cursor: pointer;
  transition: background 0.18s ease;
}

.ui-identity-toggle:hover {
  background: color-mix(in srgb, var(--gold) 26%, transparent);
}

.ui-identity-toggle .ui-identity-fact b {
  color: var(--status-neutral-fg);
}

.ui-identity-chevron {
  transition: transform 0.18s ease;
}

.ui-identity-chevron.is-open {
  transform: rotate(180deg);
}

.ui-identity-more {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
  flex-basis: 100%;
}

.ui-identity-more .ui-identity-subject {
  flex-basis: 100%;
  white-space: normal;
}

/* ========================================
   CARD
   البطاقة

   The app's card surface: `--card` (buttons.css `.main-card`, dashboard.css
   `.dashboard-card`), the same 12px padding and radius, and the same gold
   hairline across the top.
======================================== */

.ui-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-md);
  border-radius: var(--radius-lg);
  background: var(--card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

.ui-card::before {
  content: '';
  position: absolute;
  top: 0;
  inset-inline: 0;
  height: calc(3px * var(--ui-scale));
  background: linear-gradient(90deg, var(--gold), var(--gold-light));
}

.ui-card-title {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin: 0;
  padding-inline-start: calc(9px * var(--ui-scale));
  border-inline-start: 3px solid var(--gold);
  color: var(--text);
  font-size: var(--font-md);
  font-weight: 800;
  line-height: 1.4;
}

.ui-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* ========================================
   TABLE SHELL
   هيكل الجدول — نوع الخلية ونظام الألوان من الجداول الحالية
   (table.css `table`, `thead th`, `tbody td`), وعمود الإجراءات يبقى مثبّتاً
   على الهاتف.
======================================== */

.ui-table-shell {
  position: relative;
  width: 100%;
  overflow-x: auto;
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
}

.ui-table {
  width: 100%;
  min-width: calc(650px * var(--ui-scale));
  border-collapse: collapse;
  background: var(--white);
  color: var(--text);
}

.ui-table thead th {
  padding: calc(8px * var(--ui-scale));
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--status-neutral-fg);
  font-size: var(--font-xs);
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.2px;
  white-space: nowrap;
}

.ui-table tbody td {
  padding: calc(7px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-bottom: 1px solid var(--border);
  font-size: var(--font-xs);
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  vertical-align: middle;
}

/* The compact body text an opt-in screen asks for (ticket 96a round 2): the
   denser --font-2xs the Sessions and Archive tables had before they moved
   onto the shell. Two classes (the shell modifier + .ui-table) outrank both
   `.ui-table tbody td` (0,1,2) and table.css `tbody td` (0,0,2); a shell
   without the modifier is untouched. At 768px and below the readable rule
   further down wins back --font-sm for a screen that also asks for it. */
.ui-table-shell--compact .ui-table tbody td {
  font-size: var(--font-2xs);
}

.ui-table tbody tr:last-child td {
  border-bottom: none;
}

.ui-table tbody tr:nth-child(even) {
  background: var(--surface-subtle);
}

.ui-table tbody tr:hover {
  background: color-mix(in srgb, var(--gold) 4%, transparent);
}

.ui-table-cell-strong {
  font-weight: 700;
  color: var(--text);
}

.ui-table-cell-muted {
  color: var(--text-muted);
}

/* Ticket 305: a date in a list table never breaks inside itself. */
.ui-table .ui-col-date {
  white-space: nowrap;
}

.ui-table-actions {
  display: flex;
  gap: calc(6px * var(--ui-scale));
  align-items: center;
  flex-wrap: nowrap;
}

/* ========================================
   FORM FIELD
   حقل النموذج — علامة الإلزامي والخطأ بجواره
======================================== */

.ui-field {
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--ui-scale));
  min-width: 0;
}

.ui-field-label {
  display: inline-flex;
  align-items: center;
  gap: calc(4px * var(--ui-scale));
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--text);
}

.ui-field-req {
  color: var(--status-danger-fg);
  font-weight: 800;
}

.ui-field-input {
  width: 100%;
  min-height: calc(40px * var(--ui-scale));
  padding: calc(9px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  color: var(--text);
  font-size: var(--font-base);
  font-weight: 500;
  outline: none;
  transition: all 0.15s ease;
}

.ui-field-input:focus {
  border-color: var(--gold);
  background: var(--white);
}

.ui-field-input[aria-invalid='true'] {
  border-color: var(--red);
  background: var(--status-danger-bg);
}

/* fx-visual: the field placeholder reads the muted token, so it stays legible
   in both themes. */
.ui-field-input::placeholder {
  color: var(--text-muted);
}

.ui-field-error {
  display: inline-flex;
  align-items: center;
  gap: calc(5px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--status-danger-fg);
}

.ui-field-help {
  font-size: var(--font-xs);
  color: var(--text-muted);
}

/* ========================================
   STATE BLOCK
   الحالات: عادي / فارغ / تحميل / خطأ
======================================== */

.ui-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  padding: calc(38px * var(--ui-scale)) var(--space-2xl);
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
  text-align: center;
}

.ui-state-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(60px * var(--ui-scale));
  height: calc(60px * var(--ui-scale));
  border-radius: 50%;
  background: var(--surface-subtle);
  border: 1px dashed var(--border);
  color: var(--text-muted);
}

.ui-state-icon.is-error {
  background: var(--status-danger-bg);
  border-style: solid;
  border-color: var(--red);
  color: var(--status-danger-fg);
}

.ui-state-title {
  margin: 0;
  color: var(--text);
  font-size: var(--font-lg);
  font-weight: 800;
}

.ui-state-text {
  max-width: calc(420px * var(--ui-scale));
  margin: 0;
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: 1.7;
}

.ui-state-reason {
  max-width: calc(420px * var(--ui-scale));
  margin: 0;
  padding: calc(6px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
  font-size: var(--font-xs);
  font-weight: 700;
  direction: ltr;
  overflow-wrap: anywhere;
}

.ui-state-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
  justify-content: center;
}

.ui-state-skeleton {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  width: 100%;
}

.ui-skel-row {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: calc(11px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-bottom: 1px solid var(--border);
}

.ui-skel-row:last-child {
  border-bottom: none;
}

.ui-skel {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--card) 25%, var(--surface-subtle) 50%, var(--card) 75%);
  background-size: 200% 100%;
  animation: ui-shimmer 1.3s infinite;
}

.ui-skel-dot {
  width: calc(34px * var(--ui-scale));
  height: calc(34px * var(--ui-scale));
  border-radius: 50%;
  flex-shrink: 0;
}

.ui-skel-grow {
  flex: 1;
  height: calc(12px * var(--ui-scale));
}

.ui-skel-chip {
  width: calc(64px * var(--ui-scale));
  height: calc(16px * var(--ui-scale));
  border-radius: var(--radius-full);
  flex-shrink: 0;
}

@keyframes ui-shimmer {
  to {
    background-position: -200% 0;
  }
}

/* ========================================
   CONFIRMATION BLOCK
   كتلة التأكيد — تسمّي السجل المطلوب حذفه
======================================== */

.ui-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--red);
  box-shadow: var(--shadow);
}

.ui-confirm-title {
  margin: 0;
  color: var(--text);
  font-size: var(--font-lg);
  font-weight: 800;
}

.ui-confirm-text {
  margin: 0;
  color: var(--text);
  font-size: var(--font-sm);
  line-height: 1.8;
}

.ui-confirm-record {
  color: var(--status-danger-fg);
  font-weight: 800;
  overflow-wrap: anywhere;
}

.ui-confirm-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* ========================================
   STATUS MARKS
   علامة التقويم، الاتصال، وحالة الحفظ
======================================== */

.ui-mark {
  display: inline-flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  font-size: var(--font-sm);
  font-weight: 700;
}

.ui-mark-dot {
  width: calc(8px * var(--ui-scale));
  height: calc(8px * var(--ui-scale));
  border-radius: 50%;
  flex-shrink: 0;
}

.ui-mark.is-ok {
  color: var(--green);
}

.ui-mark.is-ok .ui-mark-dot {
  background: var(--green);
}

.ui-mark.is-pending {
  color: var(--warning-text);
}

.ui-mark.is-pending .ui-mark-dot {
  background: var(--gold);
}

.ui-mark.is-problem {
  color: var(--status-danger-fg);
}

.ui-mark.is-problem .ui-mark-dot {
  background: var(--red);
}

/* A quiet state that is neither good nor bad. Kept muted so it never reads
   as a warning. */
.ui-mark.is-neutral {
  color: var(--text-muted);
}

.ui-mark.is-neutral .ui-mark-dot {
  background: var(--text-muted);
}

/* The registered Calendar mark's icon-only form (ticket 184): a small calendar
   icon where the dot and the words used to be. It keeps the is-ok colour and
   carries no text, so its accessible name (aria-label/title) is the meaning.
   The icon is 15px, so it never raises a table row's height. */
.ui-mark--icon {
  display: inline-flex;
  align-items: center;
  color: var(--green);
  line-height: 0;
}

.ui-conn {
  display: inline-flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
}

.ui-conn-dot {
  width: calc(9px * var(--ui-scale));
  height: calc(9px * var(--ui-scale));
  border-radius: 50%;
  flex-shrink: 0;
}

.ui-conn.is-online {
  color: var(--green);
}

.ui-conn.is-online .ui-conn-dot {
  background: var(--green);
}

.ui-conn.is-offline {
  color: var(--red);
}

.ui-conn.is-offline .ui-conn-dot {
  background: var(--red);
}

.ui-save {
  display: inline-flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  font-size: var(--font-sm);
  font-weight: 700;
  flex-wrap: wrap;
}

.ui-save.is-saving {
  color: var(--text-muted);
}

.ui-save.is-saved {
  color: var(--green);
}

.ui-save.is-failed {
  color: var(--status-danger-fg);
}

.ui-save-spin {
  width: calc(15px * var(--ui-scale));
  height: calc(15px * var(--ui-scale));
  border-radius: 50%;
  border: 2.5px solid var(--border);
  border-top-color: var(--gold);
  animation: ui-spin 0.8s linear infinite;
  flex-shrink: 0;
}

@keyframes ui-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ========================================
   PENDING WORK
   عدّاد الأعمال المعلّقة وقائمتها

   The counter beside the connectivity mark and the list it opens. The list
   carries the three kinds of unfinished work — a refused change, a clash and
   a draft — each with its own tint, and the two row actions.
======================================== */

.ui-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: calc(18px * var(--ui-scale));
  height: calc(18px * var(--ui-scale));
  padding: 0 calc(5px * var(--ui-scale));
  border: none;
  border-radius: var(--radius-full);
  background: var(--red);
  color: var(--status-neutral-fg);
  font-size: var(--font-2xs);
  font-weight: 700;
  cursor: pointer;
}

.ui-pending-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-pending-item {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--font-sm);
}

.ui-pending-kind {
  padding: calc(2px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--surface-warning);
  color: var(--warning-text);
  font-size: var(--font-2xs);
  font-weight: 700;
  white-space: nowrap;
}

.ui-pending-kind.is-conflict {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

.ui-pending-kind.is-draft {
  background: var(--status-info-bg);
  color: var(--status-info-fg);
}

.ui-pending-kind.is-unknown {
  background: var(--card);
  color: var(--text-muted);
}

.ui-pending-what {
  color: var(--text);
  font-weight: 700;
}

.ui-pending-when {
  color: var(--text-muted);
  font-size: var(--font-xs);
}

.ui-pending-why {
  flex: 1 1 100%;
  color: var(--text-muted);
  font-size: var(--font-xs);
}

.ui-pending-actions {
  display: inline-flex;
  gap: var(--space-xs);
  margin-inline-start: auto;
}

.ui-pending-empty {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--font-sm);
}

/* ========================================
   DRAFT LIST
   قائمة المسودات
======================================== */

.ui-drafts {
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--ui-scale));
  margin-bottom: calc(8px * var(--ui-scale));
}

.ui-draft-row {
  display: flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
}

.ui-draft-summary {
  flex: 1;
  color: var(--text);
  font-size: var(--font-sm);
}

/* ========================================
   CONFLICT VIEW
   شاشة التعارض — نسختي ونسخة الخادم جنب بعض
======================================== */

.ui-conflict {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--gold);
  box-shadow: var(--shadow);
}

.ui-conflict-title {
  margin: 0;
  color: var(--text);
  font-size: var(--font-lg);
  font-weight: 800;
}

.ui-conflict-meta {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--font-sm);
}

.ui-conflict-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  overflow: hidden;
  border-radius: var(--radius-md);
  background: var(--border);
  border: 1px solid var(--border);
}

.ui-conflict-head {
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  background: var(--card);
  color: var(--text);
  font-size: var(--font-xs);
  font-weight: 800;
  text-align: center;
}

.ui-conflict-cell {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
  background: var(--white);
  color: var(--text);
  font-size: var(--font-sm);
  overflow-wrap: anywhere;
}

.ui-conflict-cell.is-different {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

.ui-conflict-label {
  color: var(--text-muted);
  font-size: var(--font-2xs);
  font-weight: 700;
}

.ui-conflict-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* Ticket 166: each choice carries its consequence line under the label, so
   the line is read as part of the choice. The two choices share the row and
   their lines wrap inside the button; the second-class selector is needed to
   outrank `.ui-btn` (0,1,0) for the layout properties. */
.ui-conflict-actions .ui-conflict-choice {
  flex: 1 1 0;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  text-align: start;
  gap: calc(2px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
}

.ui-conflict-choice-label {
  font-weight: 800;
}

.ui-conflict-choice-consequence {
  font-weight: 400;
  font-size: var(--font-2xs);
  line-height: 1.6;
  overflow-wrap: anywhere;
}

/* ========================================
   REVIEW CHOICE
   قرار محتاج مراجعة
======================================== */

.ui-review {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-lg);
  border-radius: var(--radius-lg);
  background: var(--white);
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--red);
  box-shadow: var(--shadow);
}

.ui-review-text {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: 1.7;
}

.ui-review-decision {
  margin: 0;
  padding: calc(8px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  color: var(--text);
  font-size: var(--font-sm);
  overflow-wrap: anywhere;
}

/* ========================================
   BUTTONS
   الأزرار — بمقاسات أزرار التطبيق الحالية (buttons.css `.btn`)

   Same height, padding, radius and type as the app's buttons. The variants map
   onto the app's own: gold = `.btn-primary`, danger = `.btn-danger`,
   ghost = `.btn-light`. The app's soft button shadow is left out: the kit
   introduces no colour value of its own (see the stylesheet audit), and every
   shadow token here is heavier than that one.
======================================== */

.ui-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(5px * var(--ui-scale));
  min-height: calc(32px * var(--ui-scale));
  min-width: calc(64px * var(--ui-scale));
  padding: calc(5px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font-size: var(--font-sm);
  font-weight: 700;
  letter-spacing: 0.2px;
  cursor: pointer;
  transition: all 0.18s ease;
}

.ui-btn:hover {
  filter: brightness(1.02);
}

.ui-btn--gold {
  background: var(--gold);
  color: var(--primary-dark);
}

.ui-btn--primary {
  background: var(--primary);
  color: var(--status-neutral-fg);
}

.ui-btn--ghost {
  background: var(--white);
  color: var(--text);
  border-color: var(--border);
}

.ui-btn--danger {
  background: var(--red);
  color: var(--status-neutral-fg);
}

.ui-btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}

.ui-btn--icon {
  min-width: calc(32px * var(--ui-scale));
  min-height: calc(32px * var(--ui-scale));
  padding: 0;
}

/* ========================================
   STICKY TOAST CLOSE
   زر إغلاق التنبيه — على الإشعار الذي يبقى حتى يُغلق

   Ticket 166: a notice the conflict flow raises stays on screen until the
   User closes it, so it carries this control. It reuses the kit's button,
   stripped to fit the toast, and grows to a 44px touch target on a phone.
======================================== */

.ui-toast-close {
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  background: transparent;
  border: none;
  color: currentColor;
  box-shadow: none;
}

.ui-toast-close:hover {
  background: transparent;
  filter: brightness(1.15);
}

/* ========================================
   GALLERY
   معرض العناصر — للمدير فقط

   The gallery sits on the app's own page background (the body gradient) and
   its head is the app header's band, so the owner compares like with like.
======================================== */

.ui-gallery {
  min-height: 100vh;
  background: linear-gradient(180deg, var(--body-bg-start) 0%, var(--body-bg-end) 100%);
  color: var(--status-neutral-fg);
}

.ui-gallery-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding: calc(10px * var(--ui-scale)) calc(16px * var(--ui-scale)) calc(12px * var(--ui-scale));
  padding-inline-start: calc(max(16px, var(--safe-left)) * var(--ui-scale));
  padding-inline-end: calc(max(16px, var(--safe-right)) * var(--ui-scale));
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  color: var(--status-neutral-fg);
}

.ui-gallery-head h1 {
  margin: 0;
  font-size: var(--font-xl);
  font-weight: 800;
}

.ui-gallery-toggle {
  display: inline-flex;
  gap: var(--space-xs);
}

.ui-gallery-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
  max-width: var(--container-max);
  margin: 0 auto;
  padding: var(--space-2xl) var(--space-xl) calc(60px * var(--ui-scale));
}

.ui-gallery-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.ui-gallery-section > h2 {
  margin: 0;
  padding-inline-start: calc(10px * var(--ui-scale));
  border-inline-start: 4px solid var(--gold);
  color: var(--status-neutral-fg);
  font-size: var(--font-lg);
  font-weight: 800;
}

.ui-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(280px * var(--ui-scale)), 1fr));
  gap: var(--space-lg);
  align-items: start;
}

.ui-gallery-demo {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ui-gallery-caption {
  color: var(--gold-light);
  font-size: var(--font-xs);
  font-weight: 700;
  text-align: center;
}

/* The gallery's column-class demo (ticket 96a round 2): a column may carry
   its own class, which the shell puts on that column's <th> and <td>. Here it
   right-aligns the demo's first column, the way the Archive's name column is
   aligned on a phone. The two-class selector is needed to outrank
   `.ui-table thead th` / `.ui-table tbody td` (0,1,2). */
.ui-table th.ui-gallery-col-right,
.ui-table td.ui-gallery-col-right {
  text-align: right;
}

/* The gallery's row-class demo (ticket 96b): a row may carry its own class,
   which the shell puts on its <tr>. Here it tints the demo's first row, the
   way the Muhadreen tab tints a highlighted row. The cell selector outranks
   nothing it competes with — the row stripes are set on <tr>, and this tint
   is on the cells, so it shows through. */
.ui-gallery-row-marked td {
  background: var(--surface-warning);
}

/* The gallery's shell-class demo (ticket 96c): a screen may hand the shell
   its own class, which the shell puts on its root — the way the Client
   Profile's sessions and expert tables keep their table-wide rules after
   moving off the old `.table-wrapper`. Here it tints the demo's frame border,
   the way a screen class recolours its own table box. The two-class selector
   outranks the shell's own `.ui-table-shell` border. */
.ui-table-shell.ui-gallery-shell-class {
  border-color: var(--gold);
}

.ui-gallery-note {
  padding: calc(10px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--surface-warning);
  border: 1px solid var(--gold);
  color: var(--warning-text);
  font-size: var(--font-sm);
  font-weight: 700;
}

.ui-gallery-refused {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  min-height: 60vh;
  padding: var(--space-2xl);
  text-align: center;
}

.ui-gallery-refused h1 {
  margin: 0;
  color: var(--status-neutral-fg);
  font-size: var(--font-xl);
  font-weight: 800;
}

.ui-gallery-refused p {
  margin: 0;
  color: var(--text-muted);
  font-size: var(--font-sm);
}

/* ========================================
   PHONE — COMPACT
   الهاتف: مضغوط. تُطبَّق القواعد على العرض الحقيقي (media query) وعلى معاينة
   الهاتف داخل المعرض (.ui-gallery-phone) حتى تُرى الحالة المضغوطة على شاشة
   كبيرة أيضاً.
======================================== */

@media (max-width: 768px) {
  .ui-page-inner {
    gap: var(--space-md);
    padding: 10px 12px 36px;
    padding-inline-start: max(12px, var(--safe-left));
    padding-inline-end: max(12px, var(--safe-right));
  }

  .ui-nav-band {
    padding: 8px 12px 10px;
    /* The compact step resets the band's padding, so it must carry the
           safe-area term too (ticket uifix, item 1). */
    padding-top: max(8px, calc(var(--safe-top) + 8px));
    padding-inline-start: max(12px, var(--safe-left));
    padding-inline-end: max(12px, var(--safe-right));
  }

  .ui-nav-title {
    font-size: var(--font-lg);
  }

  /* Ticket uifix (item 2): the tabs are laid out in TWO rows of equal-width
       cells, so the labels can never run into each other. The column count is
       half the number of visible tabs, rounded up — UiNavBar passes it as the
       --ui-nav-tab-columns custom property (navTabsLayout.js), because
       Permissions hide some tabs. A label that does not fit its cell wraps
       (white-space: normal) instead of being cut, and the cell grows with it. */
  .ui-nav-tabs {
    display: grid;
    grid-template-columns: repeat(var(--ui-nav-tab-columns, 1), minmax(0, 1fr));
    align-items: stretch;
    min-height: 0;
    margin: var(--space-md) auto;
  }

  .ui-nav-tab {
    min-height: 44px;
    padding: 4px;
    gap: 3px;
    white-space: normal;
    font-size: var(--font-xs);
  }

  .ui-nav-tab-inner {
    gap: 2px;
  }

  .ui-nav-user {
    font-size: var(--font-md);
  }

  .ui-identity {
    gap: var(--space-sm);
    padding: 8px var(--space-md);
  }

  .ui-identity-subject {
    flex-basis: 100%;
    white-space: normal;
  }

  .ui-field-input {
    min-height: 44px;
    font-size: 16px;
  }

  .ui-state {
    padding: 28px var(--space-lg);
  }

  /* The counter's list: the row actions drop to their own line so the
       item's name and reason stay readable on a narrow screen. */
  .ui-pending-actions {
    flex: 1 1 100%;
    margin-inline-start: 0;
  }

  /* The two conflict columns stay side by side, just tighter. */
  .ui-conflict,
  .ui-review {
    padding: var(--space-md);
  }

  .ui-conflict-cell,
  .ui-conflict-head {
    padding: 6px 8px;
  }

  /* On a phone the two choices stack: each takes the full row, so their
       consequence lines never run into each other and nothing scrolls
       sideways. */
  .ui-conflict-actions .ui-conflict-choice {
    flex-basis: 100%;
  }

  .ui-draft-summary {
    font-size: var(--font-xs);
  }

  /* The last "actions" column is pinned to the inline-end edge with an
       opaque background, and its targets grow to 44px, so no row action is
       ever hidden off-screen on a phone. */
  .ui-table-shell .ui-table-actions {
    position: sticky;
    inset-inline-end: 0;
    background: var(--white);
    box-shadow: var(--shadow);
    z-index: 3;
  }

  .ui-table-shell thead .ui-table-actions {
    z-index: 6;
    background: var(--primary);
  }

  .ui-table-shell tbody tr:nth-child(even) .ui-table-actions {
    background: var(--surface-subtle);
  }

  .ui-table-shell .ui-btn--icon {
    min-width: 44px;
    min-height: 44px;
  }

  /* The readable phone body text (--font-sm) the old `.table-wrapper tbody
       td` gave at 768px and below. Only a shell that opts in with
       `readableOnPhone` gets it, so the two screens already on the shell keep
       their own look. Same specificity as the compact rule above (0,2,2) but
       later in the file, so it wins there; it also outranks table.css
       `tbody td` (0,0,2) and `.ui-table tbody td` (0,1,2). */
  .ui-table-shell--readable .ui-table tbody td {
    font-size: var(--font-sm);
  }

  /* Every control in the pinned actions cell grows to a 44px touch target.
       The app's own Button keeps its class (.btn) and its changesData
       behaviour — only its box grows. This raises the height of every action
       button (table.css `table .btn` 28px, 0,1,1) to 44; their width already
       comes from `table .btn`'s 50px floor, so it is left alone. The extra
       session-row/view-row class outranks table.css
       `.session-actions-column .session-actions-row .btn` /
       `.session-view-row .btn` (both 0,3,0) and raises those icon-only
       targets — 28px wide, 30px tall — to 44 as well. */
  .ui-table-shell .ui-table-actions .btn {
    min-height: 44px;
  }

  .ui-table-shell .ui-table-actions .session-actions-row .btn,
  .ui-table-shell .ui-table-actions .session-view-row .btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Sessions two-row layout (edit + delete, then view) is kept; the
       column widens so two 44px targets fit side by side without the row
       overflowing the pinned cell. */
  .ui-table-shell .ui-table-actions .session-actions-column {
    min-width: 92px;
  }

  /* The Admin screen's own two-row actions layout (Done+View / Edit+Delete)
       shrinks its icon-only buttons — admin.css
       `.admin-tab .admin-record-actions .actions-row .btn` sets min-width 0
       and min-height 28px (0,4,0), which outranks the 44px rule above. The
       extra class here (0,5,0) restores the 44px target, and the column is
       widened so two 44px targets fit side by side, exactly as the Sessions
       column above. */
  .ui-table-shell .ui-table-actions .admin-record-actions .actions-row .btn {
    min-width: 44px;
    min-height: 44px;
  }

  .ui-table-shell .ui-table-actions .admin-record-actions {
    min-width: 92px;
  }

  /* The Client Profile's own one-column actions layout (تسجيل, then تعديل,
       then حذف) inside `.client-sessions-actions`, shared by the sessions and
       the expert tables. The screen's own rules give each button the full
       width of the column (client.css / table.css); the column's floor is the
       prototype's 96px (styles/table.css `.client-sessions-actions`), and the
       extra class here (0,4,0) keeps that floor on a phone and grows every
       action to a 44px target. The expert section reuses the very same
       classes, so one rule covers both. */
  .ui-table-shell .ui-table-actions .client-sessions-actions {
    min-width: 96px;
  }

  .ui-table-shell .ui-table-actions .client-sessions-actions .btn {
    min-width: 44px;
    min-height: 44px;
  }
}

/* A narrow-phone step, matching the app's own 480px header step
   (mobile.css `.header-title`, `.header-logo`). */
@media (max-width: 480px) {
  .ui-nav-title {
    font-size: var(--font-base);
    letter-spacing: 0;
  }

  .ui-nav-logo {
    width: 60px;
    height: 60px;
  }
}

/* Same compacting, driven by the gallery's phone toggle instead of the
   viewport, so the compact layout can be shown on a desktop screen. */
.ui-gallery-phone .ui-page-inner {
  gap: var(--space-md);
  padding: 10px 12px 36px;
}

.ui-gallery-phone .ui-nav-band {
  padding: 8px 12px 10px;
}

.ui-gallery-phone .ui-nav-title {
  font-size: var(--font-lg);
}

.ui-gallery-phone .ui-nav-tabs {
  min-height: 0;
  margin: var(--space-md) auto;
}

.ui-gallery-phone .ui-nav-tab {
  min-height: 36px;
  padding: 4px;
  gap: 3px;
  font-size: var(--font-xs);
}

.ui-gallery-phone .ui-nav-tab-inner {
  gap: 2px;
}

.ui-gallery-phone .ui-nav-user {
  font-size: var(--font-md);
}

.ui-gallery-phone .ui-identity {
  gap: var(--space-sm);
  padding: 8px var(--space-md);
}

.ui-gallery-phone .ui-identity-subject {
  flex-basis: 100%;
  white-space: normal;
}

.ui-gallery-phone .ui-field-input {
  min-height: 44px;
  font-size: 16px;
}

.ui-gallery-phone .ui-pending-actions {
  flex: 1 1 100%;
  margin-inline-start: 0;
}

.ui-gallery-phone .ui-conflict,
.ui-gallery-phone .ui-review {
  padding: var(--space-md);
}

.ui-gallery-phone .ui-conflict-cell,
.ui-gallery-phone .ui-conflict-head {
  padding: 6px 8px;
}

.ui-gallery-phone .ui-conflict-actions .ui-conflict-choice {
  flex-basis: 100%;
}

.ui-gallery-phone .ui-draft-summary {
  font-size: var(--font-xs);
}

.ui-gallery-phone .ui-table-shell .ui-table-actions {
  position: sticky;
  inset-inline-end: 0;
  background: var(--white);
  box-shadow: var(--shadow);
  z-index: 3;
}

.ui-gallery-phone .ui-table-shell thead .ui-table-actions {
  z-index: 6;
  background: var(--primary);
}

.ui-gallery-phone .ui-table-shell tbody tr:nth-child(even) .ui-table-actions {
  background: var(--surface-subtle);
}

.ui-gallery-phone .ui-table-shell .ui-btn--icon {
  min-width: 44px;
  min-height: 44px;
}

/* ========================================
   WORDING CHANGE (ticket 168)
   الكلمات المتغيّرة في مقارنة قبل / بعد

   A corrected article's before-and-after: the words that differ carry the
   existing warning tint, and the words the correction removes are struck
   through. Colours come only from variables.css.
======================================== */

.ui-wording-changed {
  background: var(--surface-warning);
  border-radius: var(--radius-sm);
  padding: 0 calc(3px * var(--ui-scale));
  font-weight: 700;
}

.ui-wording-removed {
  text-decoration: line-through;
}

/* ========================================
   REDUCED MOTION
======================================== */

@media (prefers-reduced-motion: reduce) {
  .ui-skel,
  .ui-save-spin {
    animation: none;
  }
}

/* app: styles/auth.css */
/* ========================================
   AUTHENTICATION — صفحات تسجيل الدخول
======================================== */

.login-page {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(16px * var(--ui-scale));
  padding-top: calc(max(16px, var(--safe-top)) * var(--ui-scale));
  padding-bottom: calc(max(16px, var(--safe-bottom)) * var(--ui-scale));
  padding-left: calc(max(16px, var(--safe-left)) * var(--ui-scale));
  padding-right: calc(max(16px, var(--safe-right)) * var(--ui-scale));
  overflow: hidden;
  background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
}

.login-page::before {
  content: '';
  position: absolute;
  width: calc(400px * var(--ui-scale));
  height: calc(400px * var(--ui-scale));
  top: calc(-150px * var(--ui-scale));
  right: calc(-120px * var(--ui-scale));
  border-radius: 50%;
  background: var(--gold-a08);
  filter: blur(30px);
}

.login-page::after {
  content: '';
  position: absolute;
  width: calc(350px * var(--ui-scale));
  height: calc(350px * var(--ui-scale));
  bottom: calc(-150px * var(--ui-scale));
  left: calc(-120px * var(--ui-scale));
  border-radius: 50%;
  background: color-mix(in srgb, var(--primary) 6%, transparent);
  filter: blur(30px);
}

/* ========================================
   LOGIN CARD
======================================== */

.login-card {
  position: relative;
  width: 100%;
  max-width: calc(400px * var(--ui-scale));
  padding: calc(24px * var(--ui-scale)) calc(22px * var(--ui-scale));
  border-radius: var(--radius-2xl);
  text-align: center;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--on-dark-a60);
  box-shadow: var(--shadow-lg);
  backdrop-filter: blur(8px);
}

/* ========================================
   LOGIN LOGO
======================================== */

.login-logo {
  position: relative;
  width: calc(56px * var(--ui-scale));
  height: calc(56px * var(--ui-scale));
  margin: 0 auto calc(10px * var(--ui-scale));
  border-radius: var(--radius-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--status-neutral-fg);
  font-size: max(var(--ui-text-min), calc(28px * var(--ui-text-scale)));
  box-shadow: var(--shadow);
}

.login-logo::after {
  content: '';
  position: absolute;
  inset: -8px;
  border-radius: var(--radius-xl);
  background: var(--gold-a15);
  z-index: -1;
}

/* ========================================
   LOGIN TEXT
======================================== */

.login-top-text {
  color: var(--gold);
  font-size: var(--font-sm);
  font-weight: 700;
  margin-bottom: calc(6px * var(--ui-scale));
}

.login-title {
  font-size: var(--font-2xl);
  font-weight: 800;
  color: var(--heading-text);
  margin-bottom: calc(6px * var(--ui-scale));
}

.login-subtitle {
  font-size: var(--font-sm);
  color: var(--text-muted);
  margin-bottom: calc(20px * var(--ui-scale));
}

/* ========================================
   LOGIN FORM
======================================== */

.login-form {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

/* ========================================
   LOGIN — reason line, forgot-password link and its feedback
======================================== */

/* why the app is asking you to sign in again (authDiagnostics.js) */
.login-reason {
  margin: calc(-8px * var(--ui-scale)) 0 calc(16px * var(--ui-scale));
  padding: calc(10px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--surface-warning);
  color: var(--warning-text);
  font-size: var(--font-sm);
  line-height: 1.7;
  text-align: right;
}

.login-reason p + p {
  margin-top: calc(6px * var(--ui-scale));
}

/* The shared-device tick on the sign-in screen. It is one inline row, the
   shape it has today; the label wraps the box, so the whole row is the
   touch target (44px on a phone, styles/mobile.css). */
.auth-shared-device {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  font-size: var(--font-sm);
  cursor: pointer;
  user-select: none;
}

.auth-shared-device-check {
  width: calc(16px * var(--ui-scale));
  height: calc(16px * var(--ui-scale));
  margin: 0;
}

/* The code screen's two lines above the field (Display Name, then the
   mailbox the code went to) — the inline styles they used to carry. */
.auth-otp-name {
  font-weight: 700;
  margin: 0 0 calc(4px * var(--ui-scale));
}

.auth-otp-sent {
  margin: 0;
}

.login-reset-info {
  margin: 0;
  padding: calc(10px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border-radius: var(--radius-md);
  font-size: var(--font-sm);
  line-height: 1.7;
  text-align: right;
}

.login-reset-success {
  background: var(--status-ok-bg);
  color: var(--green);
}

.login-reset-error {
  background: var(--status-danger-bg);
  color: var(--red);
}

/* ========================================
   AUTH — BOOT SCREEN (prototype 8-6)

   What the User sees while the session and the profile resolve, instead of a
   white page: the app's logo, its name, a quiet progress bar and the wait
   line. Every colour is a token, so dark mode follows.
======================================== */

.auth-boot {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2xl);
  min-height: 100vh;
  min-height: 100dvh;
  padding: calc(16px * var(--ui-scale));
  background: linear-gradient(160deg, var(--body-bg-start) 0%, var(--body-bg-end) 100%);
  color: var(--status-neutral-fg);
  text-align: center;
}

.auth-boot-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(84px * var(--ui-scale));
  height: calc(84px * var(--ui-scale));
  border-radius: var(--radius-2xl);
  background: var(--primary-dark);
  border: 1px solid var(--gold);
  color: var(--gold-light);
  font-size: max(var(--ui-text-min), calc(40px * var(--ui-text-scale)));
  animation: auth-boot-pulse 1.8s ease-in-out infinite;
}

.auth-boot-title {
  font-size: var(--font-xl);
  font-weight: 800;
}

.auth-boot-sub {
  font-size: var(--font-sm);
  opacity: 0.6;
}

.auth-boot-bar {
  width: calc(180px * var(--ui-scale));
  height: calc(4px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--primary-dark);
  overflow: hidden;
}

.auth-boot-bar-fill {
  display: block;
  height: 100%;
  width: 45%;
  border-radius: var(--radius-full);
  background: var(--gold);
  animation: auth-boot-slide 1.4s ease-in-out infinite;
}

@keyframes auth-boot-pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.05);
  }
}

@keyframes auth-boot-slide {
  0% {
    transform: translateX(140px);
  }
  100% {
    transform: translateX(-140px);
  }
}

/* app: styles/dashboard.css */
/* ========================================
   DASHBOARD — لوحة التحكم الرئيسية
======================================== */

.dashboard-page {
  display: flex;
  flex-direction: column;
  gap: calc(14px * var(--ui-scale));
}

.dashboard-content {
  min-width: 0;
}

/* ========================================
   DASHBOARD STAT CARDS GRID
======================================== */

.dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(160px * var(--ui-scale)), 1fr));
  gap: calc(12px * var(--ui-scale));
  margin-top: calc(4px * var(--ui-scale));
  margin-bottom: calc(16px * var(--ui-scale));
  align-items: stretch;
}

/* ========================================
   DASHBOARD CARD
======================================== */

.dashboard-card {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  gap: calc(10px * var(--ui-scale));
  padding: calc(10px * var(--ui-scale));
  border-radius: var(--radius-lg);
  background: var(--card);
  box-shadow: var(--shadow);
  transition: all 0.18s ease;
}

.dashboard-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lg);
}

.dashboard-card::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: calc(2px * var(--ui-scale));
  background: linear-gradient(90deg, var(--gold), var(--gold-light));
}

/* ========================================
   DASHBOARD CARD PARTS
======================================== */

.dashboard-card-top {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--ui-scale));
}

.dashboard-icon {
  position: relative;
  width: calc(44px * var(--ui-scale));
  height: calc(44px * var(--ui-scale));
  min-width: calc(44px * var(--ui-scale));
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--gold);
  background: var(--gold-a08);
}

.dashboard-label {
  font-size: var(--font-xs);
  color: var(--text-muted);
  font-weight: 600;
}

.dashboard-value {
  font-size: var(--font-xl);
  font-weight: 800;
  margin-top: calc(2px * var(--ui-scale));
  color: var(--heading-text);
}

/* ========================================
   DASHBOARD FILTER CARDS
======================================== */

.dashboard-filter-card {
  cursor: pointer;
  transition: 0.2s ease;
  border: 1px solid var(--on-dark-a10);
}

.dashboard-filter-card:hover {
  transform: translateY(-2px);
}

.dashboard-filter-active-all {
  border: 2px solid var(--gold) !important;
  background: var(--gold-a08) !important;
}

.dashboard-filter-active-family {
  border: 2px solid var(--gold) !important;
  background: var(--gold-a08) !important;
}

.dashboard-filter-active-civil {
  border: 2px solid var(--gold) !important;
  background: var(--gold-a08) !important;
}

.dashboard-filter-active-criminal {
  border: 2px solid var(--gold) !important;
  background: var(--gold-a08) !important;
}

/* ========================================
   DASHBOARD INSIGHTS
======================================== */

.dashboard-insights-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(140px * var(--ui-scale)), 1fr));
  gap: calc(10px * var(--ui-scale));
  margin-bottom: calc(16px * var(--ui-scale));
}

.dashboard-insight-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: calc(2px * var(--ui-scale));
  min-height: calc(60px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale));
  text-align: center;
  background: var(--card);
  color: var(--text);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow);
}

.dashboard-insight-number {
  font-size: var(--font-xl);
  font-weight: 900;
  color: var(--heading-text);
}

.dashboard-insight-label {
  font-size: var(--font-xs);
  color: var(--text-muted);
}

/* ========================================
   DASHBOARD STAT CARD (clickable)
======================================== */

.dashboard-stat-warning {
  background: var(--surface-warning) !important;
  border: 1px solid var(--gold) !important;
}

/* ========================================
   DASHBOARD SUMMARY CARDS — the prototype's .kpi look (ticket 98-2a)
   Each card is one native <button> with a white face and a coloured bar at
   its inline start, the number loud and the label muted. Scoped to the
   operations grid, so the Finance subtab's own cards keep their look; the
   report's three count cards join the same look (ticket 98-2b), and the
   Finance view's four money cards do too (ticket 98-2c).
======================================== */

.dashboard-insights-grid--summary .dashboard-insight-card,
.dashboard-report-kpis .dashboard-insight-card,
.finance-kpis .dashboard-insight-card {
  position: relative;
  overflow: hidden;
  align-items: flex-start;
  text-align: start;
  gap: calc(4px * var(--ui-scale));
  padding: calc(16px * var(--ui-scale)) calc(18px * var(--ui-scale));
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: none;
  font: inherit;
  cursor: pointer;
}

.dashboard-insights-grid--summary .dashboard-insight-card::before,
.dashboard-report-kpis .dashboard-insight-card::before,
.finance-kpis .dashboard-insight-card::before {
  content: '';
  position: absolute;
  inset-inline-start: 0;
  top: 0;
  bottom: 0;
  width: calc(4px * var(--ui-scale));
  background: var(--gold);
}

/* A count above zero takes the warning variant: the bar turns the app's red
   (the prototype's k-red), on the same condition as before. The card keeps
   its own white face; the shared amber is only for the Finance cards. */
.dashboard-insights-grid--summary .dashboard-insight-card.dashboard-stat-warning {
  background: var(--white) !important;
  border: 1px solid var(--border) !important;
}

.dashboard-insights-grid--summary .dashboard-insight-card.dashboard-stat-warning::before {
  background: var(--red);
}

.dashboard-insights-grid--summary .dashboard-insight-number,
.dashboard-report-kpis .dashboard-insight-number,
.finance-kpis .dashboard-insight-number {
  font-size: var(--font-2xl);
  font-weight: 800;
  color: var(--heading-text);
  line-height: 1.1;
}

.dashboard-insights-grid--summary .dashboard-insight-label,
.dashboard-report-kpis .dashboard-insight-label,
.finance-kpis .dashboard-insight-label {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--text-muted);
}

/* ========================================
   DASHBOARD REPORT — «تقرير الغد» / «التقرير الأسبوعي» (ticket 98-2b)
   One shared view for both reports: the head, the three count cards (the
   prototype's .kpi look, joined to the summary cards' own rules) and one card
   per list. Colours come from the tokens, so dark mode follows.
======================================== */

.dashboard-report {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.dashboard-report-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: calc(12px * var(--ui-scale));
  padding-bottom: calc(10px * var(--ui-scale));
  border-bottom: 1px solid var(--border);
}

.dashboard-report-heading {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  min-width: 0;
}

.dashboard-report-title {
  margin: 0;
  text-align: start;
  color: var(--text);
  font-size: var(--font-lg);
  font-weight: 800;
}

.dashboard-report-subtitle {
  margin: 0;
  /* --text-muted is 4.44:1 on the light card; the head subtitle takes --text (#213). */
  color: var(--text);
  font-size: var(--font-xs);
}

.dashboard-report-header-actions {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  flex-wrap: wrap;
}

/* The three counts, one per list, in the prototype's .kpi grid. */
.dashboard-report-kpis {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: calc(10px * var(--ui-scale));
}

/* ========================================
   DASHBOARD SUBTABS — the prototype's tab look (ticket 98-2a)
   Visible card tabs in one row, the active one marked with the app's gold
   underline and word — the prototype's .navtab, on the app's own tokens.
   (fx-visual: they were transparent and vanished on the dark page.)
======================================== */

.dashboard-subtabs {
  display: flex;
  align-items: stretch;
  flex-wrap: wrap;
  gap: calc(6px * var(--ui-scale));
  margin-bottom: calc(14px * var(--ui-scale));
}

.dashboard-subtabs button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: calc(7px * var(--ui-scale));
  min-height: 44px;
  padding: 0 calc(13px * var(--ui-scale));
  border: 1px solid var(--border);
  border-bottom: 3px solid transparent;
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--text);
  font-size: var(--font-sm);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  transition: 0.18s;
}

.dashboard-subtabs button:hover {
  color: var(--gold);
  background: color-mix(in srgb, var(--gold) 8%, transparent);
}

.dashboard-subtabs .dashboard-tab-active {
  color: var(--gold);
  border-bottom-color: var(--gold);
}

/* ========================================
   SETTINGS PAGE (inside Dashboard)
   Only the header row is left here; the card title's one home is
   settings.css.
======================================== */

.settings-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: calc(14px * var(--ui-scale));
}

/* ========================================
   FINANCE VIEW — «المالية» (ticket 98-2c)
   The controls, the four money cards and the debtors' card, moved to the
   chosen prototype: one segmented control, the kit's own fields, the
   prototype's .kpi grid and .tablewrap. Token-based, so dark mode follows;
   RTL-safe (flex and logical properties only, no physical left/right).
======================================== */

.finance-view {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.finance-period-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: calc(10px * var(--ui-scale));
}

.finance-period-title {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--heading-text);
}

/* The prototype's .seg: one frame around every preset, the active one filled
   with the app's own gold — the marking the buttons have always had. The
   buttons inside drop their own frame so the group reads as one control. */
.finance-period-seg {
  display: inline-flex;
  flex-wrap: wrap;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.finance-period-seg .ui-btn {
  border: none;
  border-radius: 0;
  min-height: 44px;
}

/* The four money cards, in the prototype's .kpi grid. */
.finance-kpis {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: calc(10px * var(--ui-scale));
}

.finance-fields {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: calc(8px * var(--ui-scale)) calc(12px * var(--ui-scale));
}

/* The kit's field stacks its own label over its control; the Finance fields
   only keep the width they have always had. */
.finance-field {
  min-width: calc(150px * var(--ui-scale));
}

.finance-field-grow {
  flex: 1 1 calc(200px * var(--ui-scale));
}

.finance-scope-note {
  font-size: var(--font-xs);
  color: var(--text-muted);
  line-height: 1.5;
}

/* The «مؤرشف» marker the debtors table has always shown, in the prototype's
   chip shape. Token-based, so dark mode follows. */
.finance-debt-archived {
  display: inline-flex;
  align-items: center;
  margin-inline-start: calc(6px * var(--ui-scale));
  padding: calc(2px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--surface-subtle);
  color: var(--text-muted);
  border: 1px solid var(--border);
  font-size: var(--font-xs);
  font-weight: 700;
}

/* ========================================
   DEBTORS TABLE — المديونيات (ticket uifix, item 5)
   The debtors table is the one table whose rows read as too airy, so its
   rows alone get less vertical padding — the shared `.ui-table tbody td`
   rule (styles/ui.css) is deliberately left alone, because the owner said
   the other tables look acceptable. The font size is unchanged.

   A cell's `height` is a minimum in the table layout, so the row stays at
   least 36px on desktop. The debtors row carries no action (the shell
   renders no actions column for it), so it is not a touch target and the
   44px phone target does not apply here.
======================================== */

.dashboard-debt-table .ui-table tbody td {
  padding-top: calc(3px * var(--ui-scale));
  padding-bottom: calc(3px * var(--ui-scale));
  height: calc(36px * var(--ui-scale));
}

/* ========================================
   DASHBOARD DIALOGS — the two lists the summary cards open (ticket 98-2a)
   Each group and item carries a title line and muted details; long text
   wraps inside and never widens the dialog.
======================================== */

.dashboard-dialog-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.dashboard-dialog-group {
  margin-bottom: 0;
}

.dashboard-dialog-meta {
  font-size: var(--font-sm);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.dashboard-dialog-item {
  padding: calc(6px * var(--ui-scale)) 0;
}

.dashboard-dialog-item--open {
  cursor: pointer;
}

.dashboard-dialog-item-title {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--heading-text);
  margin-bottom: calc(2px * var(--ui-scale));
  overflow-wrap: anywhere;
}

.dashboard-dialog-item-text {
  font-size: var(--font-sm);
  line-height: 1.5;
  color: var(--text-muted);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* app: styles/client.css */
/* ========================================
   CLIENT PAGE — صفحة الموكل
======================================== */

.client-page {
  padding: 0;
  /* The app runs edge-to-edge (viewport-fit=cover + a translucent status
       bar), so on a phone the top of this page sits UNDER the clock /
       dynamic island — which hid the back, edit and save buttons. The
       padding pushes the header down; what shows above it is the app's
       own background (html/body gradient), same as every other screen.
       All four env() values are 0 on desktop, so nothing changes there. */
  padding-top: var(--safe-top);
  padding-bottom: var(--safe-bottom);
  padding-left: var(--safe-left);
  padding-right: var(--safe-right);
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
  min-height: 100vh;
  min-height: 100dvh;
}

/* Desktop only (ticket 306): the page joins the other screens' centred
   column — at most --container-max wide, their side gutter, nothing else
   moved. The query opens above the phone's 768px, so the phone layout is
   untouched. */
@media (min-width: 769px) {
  .client-page {
    max-width: var(--container-max);
    margin: 0 auto;
    padding-left: calc(max(20px, var(--safe-left)) * var(--ui-scale));
    padding-right: calc(max(20px, var(--safe-right)) * var(--ui-scale));
  }
}

/* ========================================
   CLIENT TABS
======================================== */

.client-tabs {
  display: flex;
  gap: calc(6px * var(--ui-scale));
  flex-wrap: wrap;
  margin-bottom: calc(12px * var(--ui-scale));
}

.client-tabs button {
  border: none;
  background: var(--surface-subtle);
  color: var(--text);
  border-radius: var(--radius-sm);
  padding: calc(6px * var(--ui-scale)) calc(12px * var(--ui-scale));
  display: flex;
  align-items: center;
  gap: calc(5px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
  cursor: pointer;
  transition: 0.18s;
}

.client-tabs button.active {
  background: var(--gold);
  color: var(--primary-dark);
}

/* ========================================
   CLIENT INFO GRID (old)
======================================== */

.client-info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(160px * var(--ui-scale)), 1fr));
  gap: calc(10px * var(--ui-scale));
}

.client-info-grid label {
  display: block;
  margin-bottom: calc(4px * var(--ui-scale));
  font-size: var(--font-2xs);
  font-weight: 700;
  color: var(--text-muted);
}

/* ========================================
   CLIENT PAGE HEADER CARD

   The archive page's header card (and its name card) is gone: the band
   «البيانات» and the archived page both render through ClientProfileHeader
   (ticket 98-1d), so nothing renders those classes any more. The action row
   below is shared by both bands and stays.
======================================== */

.client-page-top-header-layout {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: calc(12px * var(--ui-scale));
}

/* ========================================
   CLIENT INFO GRID (new)

   Only the value rule is still rendered (the Finance tab shows a figure
   through it). The grid, the card, the label and the topic block went with
   the archive page's header card (ticket 98-1d).
======================================== */

.client-page-info-value {
  min-height: calc(34px * var(--ui-scale));
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-weight: 700;
  font-size: var(--font-sm);
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  color: var(--text);
  line-height: 1.5;
  word-break: break-word;
  overflow-wrap: break-word;
}

/* ========================================
   CLIENT ARCHIVE
   The tab moved to the chosen prototype (ticket 98-1c): the two messages are
   the prototype's own notes, whose look the Data tab already carries as
   .client-data-notice — so the archive note JOINS that rule rather than
   repeating it. The group's own icon joins the tabs' icon rule below, and
   the group's actions join the tabs' actions rule (ticket 98-1a).
======================================== */

.client-archive-main-content {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

/* ========================================
   SECRETARIES & OPPONENTS SECTION
======================================== */

.client-secretaries-opponents-layout {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

.client-files-list-layout,
.client-notes-list-layout {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.client-notes-grid-spacing {
  gap: calc(6px * var(--ui-scale));
}

/* ========================================
   CLIENT FILES
======================================== */

.client-file-link-style {
  display: flex;
  align-items: center;
  gap: calc(4px * var(--ui-scale));
  color: var(--status-info-fg);
  font-size: var(--font-xs);
  font-weight: 600;
  text-decoration: none;
  word-break: break-all;
}

.google-drive-helper-box-layout {
  padding: calc(8px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--status-info-bg);
  border: 1px solid var(--status-info-bg);
  margin-bottom: calc(12px * var(--ui-scale));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(8px * var(--ui-scale));
}

.google-drive-helper-text {
  font-size: var(--font-xs);
  font-weight: 600;
}

/* ========================================
   CLIENT DRIVE LINK
======================================== */

.client-drive-link-input {
  width: 100%;
  direction: ltr;
  text-align: right;
}

/* ========================================
   CLIENT NOTES
======================================== */

.client-notes-main-layout {
  display: flex;
  flex-direction: column;
  gap: calc(12px * var(--ui-scale));
}

.client-notes-field-label {
  color: var(--heading-text) !important;
  font-size: var(--font-sm) !important;
  font-weight: 700 !important;
  margin-bottom: calc(4px * var(--ui-scale));
  display: block;
}

.client-notes-textarea-style {
  min-height: calc(32px * var(--ui-scale));
  height: calc(32px * var(--ui-scale));
  padding-top: calc(6px * var(--ui-scale));
  font-size: var(--font-sm);
  resize: vertical;
}

.client-notes-content-field {
  font-size: var(--font-sm);
  min-height: calc(32px * var(--ui-scale));
  white-space: pre-wrap;
  line-height: 1.6;
}

.client-notes-actions-spacing {
  margin-top: calc(8px * var(--ui-scale));
}

/* ========================================
   SESSION FIELDS (inside client page)
======================================== */

.session-details-textarea {
  min-height: calc(80px * var(--ui-scale));
  padding-top: calc(8px * var(--ui-scale));
}

.session-decision-textarea {
  min-height: calc(60px * var(--ui-scale));
  padding-top: calc(8px * var(--ui-scale));
}

.session-deadline-info-text {
  margin-bottom: calc(10px * var(--ui-scale));
  opacity: 0.7;
  font-size: var(--font-xs);
}

/* ========================================
   ARCHIVED STAMP
======================================== */

.archived-stamp {
  position: fixed;
  top: calc(140px * var(--ui-scale));
  left: calc(16px * var(--ui-scale));
  z-index: 20;
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(90px * var(--ui-scale));
  height: calc(90px * var(--ui-scale));
  border-radius: 50%;
  border: 4px solid var(--red);
  color: var(--red);
  font-size: max(var(--ui-text-min), calc(18px * var(--ui-text-scale)));
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 2px;
  transform: rotate(-18deg);
  background: var(--on-dark-a60);
  backdrop-filter: blur(4px);
}

.archive-status-badge {
  width: fit-content;
  margin: auto;
  padding: calc(4px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-sm);
  font-size: var(--font-xs);
  font-weight: 700;
}

.archive-status-out {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

/* ========================================
   CLIENT SESSIONS TABLE - تحسين الأعمدة
======================================== */

/* NOTE: table layout is OWNED BY table.css — see its "CLIENT SESSIONS TABLE
   COLUMNS" section, which sets `table-layout: auto` for this same selector.
   The duplicate `table-layout: fixed` here never applied (table.css loads
   later, equal specificity), so it was removed (report 07 §5.1).

   Ticket 96c: the table now renders through UiTableShell, and its class
   (`client-sessions-table`) moved from the old `.table-wrapper` onto the
   shell's root (the shell's new `className` prop). The per-column width and
   alignment rules below are re-aimed from `th/td:nth-child(n)` to each
   column's own class (from CLIENT_SESSION_COLUMNS), header and cell both —
   the shell puts that class on both. The actions column is not a data
   column, so it is aimed at the shell's own `.ui-table-actions` class. */

.client-sessions-table table {
  width: 100%;
}

.client-sessions-table th.client-session-role-column,
.client-sessions-table td.client-session-role-column {
  width: 8%;
}

.client-sessions-table th.client-session-date-column,
.client-sessions-table td.client-session-date-column {
  width: 10%;
}

.client-sessions-table th.client-session-statement-column,
.client-sessions-table td.client-session-statement-column {
  width: 32%;
}

.client-sessions-table th.client-session-decision-column,
.client-sessions-table td.client-session-decision-column {
  width: 25%;
}

.client-sessions-table th.client-session-next-column,
.client-sessions-table td.client-session-next-column {
  width: 10%;
}

/* The actions column takes its width from its content with a minimum — the
   one column layout and its 96px floor live on `.client-sessions-actions`
   in styles/table.css (shared with the expert table) — never from a
   percentage of the table (ticket 95c). */

.client-sessions-table .client-sessions-actions .btn {
  /* Full width in the one column, at the prototype's 13px, with no
       `min-width: 0` — a button never shrinks below its own icon and word
       (ticket 95c). */
  width: 100%;
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-size: var(--font-sm);
}

/* البيان والقرار — long text wraps and stays right-aligned. The shell's own
   `.ui-table tbody td` (0,1,2) sets text-align center, so the column class
   is scoped to the cell (0,2,1) to outrank it. */
.client-sessions-table td.client-session-statement-column {
  white-space: normal;
  word-wrap: break-word;
  text-align: right;
}

.client-sessions-table td.client-session-decision-column {
  white-space: normal;
  word-wrap: break-word;
  text-align: right;
  /* The prototype's maximum width on «القرار» (ticket 95c). */
  max-width: calc(340px * var(--ui-scale));
}

/* تاريخ الجلسة والجلسة التالية — one line each, never wrapped, so the two
   short cells keep their date readable (ticket 95c). */
.client-sessions-table td.client-session-date-column,
.client-sessions-table td.client-session-next-column {
  white-space: nowrap;
}

/* The Client Profile tab's title line: the tab's name with the count of the
   rows shown beside it (tickets 95c, 98-1a). One pair of classes serves the
   Sessions, Notes and Files tabs — the layout is the prototype's `.page-head
   h2` (icon + title + count on one line). The count is scoped to the head so
   it outranks the layout.css `.page-header-title span` size (0,1,1). */
.client-tab-head {
  display: flex;
  align-items: center;
  gap: calc(9px * var(--ui-scale));
}

.client-tab-head .client-tab-count {
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--text-muted);
}

/* The prototype's one line telling the User the table scrolls sideways
   inside its own frame. Hidden above 768px; shown on a phone only
   (styles/mobile.css) — ticket 95c. */
.client-sessions-scroll-hint {
  display: none;
}

/* The "where to register" window (ticket #196): one column of the kit's
   buttons, each full width so a long Arabic label wraps instead of
   scrolling sideways. */
.register-after-add-choices {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.register-after-add-choices .ui-btn {
  width: 100%;
  white-space: normal;
}

/* Phone: every choice is a 44px touch target. */
@media (max-width: 768px) {
  .register-after-add-choices .ui-btn {
    min-height: 44px;
  }
}

/* ========================================
   EXPERT SECTION
   Isolated from the normal sessions styles.
   Uses .expert-* namespace throughout.
======================================== */

/* Section header — collapse toggle + actions aligned */
.expert-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: calc(8px * var(--ui-scale));
  margin-bottom: calc(12px * var(--ui-scale));
}

.expert-header-actions {
  display: flex;
  gap: calc(8px * var(--ui-scale));
  align-items: center;
  flex-wrap: wrap;
}

/* Info cards row — 4 cards, leaves room for future fields */
.expert-info-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(140px * var(--ui-scale)), 1fr));
  gap: calc(10px * var(--ui-scale));
  margin-bottom: calc(16px * var(--ui-scale));
}

.expert-info-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: calc(8px * var(--ui-scale));
  padding: calc(10px * var(--ui-scale)) calc(14px * var(--ui-scale));
  display: flex;
  flex-direction: column;
  gap: calc(4px * var(--ui-scale));
}

.expert-info-label {
  font-size: var(--font-2xs);
  font-weight: 700;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

.expert-info-value {
  font-size: max(var(--ui-text-min), calc(13px * var(--ui-text-scale)));
  font-weight: 600;
  color: var(--text-primary);
  word-break: break-word;
}

/* Expert table — matches client-sessions-table widths.
   Ticket 96c: the table now renders through UiTableShell, and its class
   (`expert-sessions-table`) moved from the old `.table-wrapper` onto the
   shell's root (the shell's new `className` prop). The per-column width
   rules below are re-aimed from `th/td:nth-child(n)` to each column's own
   class (from EXPERT_COLUMNS), header and cell both. The actions column is
   not a data column, so it is aimed at the shell's own `.ui-table-actions`
   class. */
.expert-sessions-table {
  margin-top: 0;
}

.expert-sessions-table table {
  table-layout: fixed;
  width: 100%;
}

/* Column widths mirroring client-sessions-table proportions.

   Ticket 95c round 2: the actions column is a fixed LENGTH, not a
   percentage. In a fixed layout a percentage column does not grow, so at the
   table's 650px floor the old 15% (97.5px) left a content box of 81.5px —
   narrower than the 96px floor of `.client-sessions-actions` — and the
   buttons overflowed into the neighbouring column. The fixed length is that
   floor plus the cell's own 8px + 8px padding = 112px, so the content box is
   always ≥ 96px. The data columns are re-balanced from 85% to 82% so the row
   still fits the 650px floor: 82% of 650px = 533px, + 112px = 645px, and the
   browser distributes the 5px remainder (the same distribution fills the row
   at wider widths, where the remainder is larger). */
.expert-sessions-table th.expert-timing-column,
.expert-sessions-table td.expert-timing-column {
  width: 7%;
}

.expert-sessions-table th.expert-session-date-column,
.expert-sessions-table td.expert-session-date-column {
  width: 11%;
}

.expert-sessions-table th.expert-statement-column,
.expert-sessions-table td.expert-statement-column {
  width: 28%; /* was 30% */
}

.expert-sessions-table th.expert-decision-column,
.expert-sessions-table td.expert-decision-column {
  width: 26%; /* was 27% */
}

.expert-sessions-table th.expert-date-column,
.expert-sessions-table td.expert-date-column {
  width: 10%;
}

.expert-sessions-table th.ui-table-actions,
.expert-sessions-table td.ui-table-actions {
  /* 96px floor + 8px + 8px cell padding */
  width: calc(112px * var(--ui-scale)); /* was 15% */
}

/* Wrap long text in statement / decision columns. The shell's own
   `.ui-table tbody td` (0,1,2) sets text-align center, so the cell class is
   scoped to the root + cell (0,2,1) to outrank it. */
.expert-sessions-table td.expert-text-cell {
  white-space: normal;
  word-wrap: break-word;
  text-align: right;
}

/* The expert table's row actions use the shared one-column layout
   (styles/table.css `.client-sessions-actions`), so the two tables can never
   drift; only the button sizing is its own, matching the sessions table
   exactly — full width, the prototype's 13px, no `min-width: 0` (ticket
   95c). */
.expert-sessions-table .client-sessions-actions .btn {
  width: 100%;
  padding: calc(6px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-size: var(--font-sm);
}

/* Send button — gold variant matching normal sessions */
.expert-sessions-table .send-btn {
  font-weight: 600;
}

/* ========================================
   CLIENT CHANGE LOG (report 09 §3.2)
   Token-based so it follows dark mode — no literals here.
======================================== */

.change-log-list {
  display: flex;
  flex-direction: column;
  gap: calc(10px * var(--ui-scale));
  margin-top: calc(10px * var(--ui-scale));
}

.change-log-time {
  font-size: var(--font-xs);
  color: var(--text-muted);
  direction: ltr;
}

.change-log-summary {
  margin-top: calc(6px * var(--ui-scale));
  font-size: var(--font-base);
  color: var(--text);
  word-break: break-word;
}

.change-log-details {
  margin: calc(8px * var(--ui-scale)) 0 0;
  padding: calc(8px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--bg-secondary);
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: 1.7;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: calc(220px * var(--ui-scale));
  overflow: auto;
}

.change-log-error {
  margin-top: calc(6px * var(--ui-scale));
  font-size: var(--font-sm);
  color: var(--status-danger-fg);
}

/* Suggested degree for records that have no user-entered degree yet.
   Deliberately muted and secondary — the stored degree (the badge above it)
   is authoritative; this is only a hint from the legacy inference. */
.client-degree-hint {
  margin-top: calc(4px * var(--ui-scale));
  font-size: var(--font-xs);
  color: var(--text-muted);
  white-space: nowrap;
}

/* ========================================
   CLIENT PAGE FRAME (ticket 95)
   The page's own top row: the back control, kept on every tab now that the
   header card above the tabs is gone.
======================================== */

.client-page-frame {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
}

/* ========================================
   CLIENT DATA TAB — تبويب «البيانات» (ticket 95)
   Every client and case field the header card used to show or edit, on one
   page. The grouped surfaces and the labelled fields are the shared UiCard
   and UiFormField blocks; this file only lays them out — a stack, and a
   two-column dossier on desktop.
======================================== */

.client-data {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* The edit / save / cancel row. It keeps the class the app's save shortcut
   looks for (App.jsx queries `.client-page-top-header-layout .btn-light`
   / `.btn-success`), but lays out as a plain row. */
.client-page-top-header-layout.client-data-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.client-data-dossier {
  display: grid;
  grid-template-columns: 1.55fr 1fr;
  gap: var(--space-md);
  align-items: start;
}

.client-data-col {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-width: 0;
}

/* ========================================
   CLIENT PROFILE HEADER BAND (ticket 95b)
   The band «البيانات» sits under: the «ملف موكل» kicker over the client's
   name, the case / degree / court chips under it, and the edit / save /
   cancel controls on the same row. Built from the app's own tokens — the same
   navy, gold and gold-light the identity bar uses — never the prototype's
   literal colours.
======================================== */

.client-header-band {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
  color: var(--status-neutral-fg);
  border-bottom: 3px solid var(--gold);
}

.client-header-row {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-md) var(--space-lg);
}

.client-header-back {
  flex: 0 0 auto;
}

.client-header-id {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: calc(5px * var(--ui-scale));
}

.client-header-kicker {
  font-size: var(--font-2xs);
  font-weight: 800;
  letter-spacing: 1.4px;
  color: var(--gold-light);
}

.client-header-name {
  margin: 0;
  font-size: var(--font-2xl);
  font-weight: 900;
  line-height: 1.2;
  color: var(--status-neutral-fg);
  overflow-wrap: anywhere;
}

.client-header-name-input {
  width: 100%;
  min-height: calc(36px * var(--ui-scale));
  padding: 0 var(--space-md);
  border: 1px solid var(--gold);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-lg);
  font-weight: 800;
  outline: none;
}

.client-header-chips {
  display: flex;
  flex-wrap: wrap;
  gap: calc(6px * var(--ui-scale));
}

.client-header-chip {
  font-size: var(--font-xs);
  font-weight: 700;
  border-radius: var(--radius-full);
  padding: calc(3px * var(--ui-scale)) calc(10px * var(--ui-scale));
  background: color-mix(in srgb, var(--status-neutral-fg) 12%, transparent);
  color: var(--status-neutral-fg);
  border: 1px solid color-mix(in srgb, var(--status-neutral-fg) 18%, transparent);
}

.client-header-chip.is-gold {
  background: var(--gold);
  color: var(--primary-dark);
  border-color: var(--gold);
}

/* The band's action row keeps the class the app's save shortcut looks for
   (App.jsx queries `.client-page-top-header-layout .btn-light` /
   `.btn-success`); the band's own rule outranks the shared grid so it lays
   out as a plain row, phone included. */
.client-header-band .client-header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  flex: 0 0 auto;
}

/* ========================================
   CLIENT DATA TAB — the prototype's groups (ticket 95b)
   A group's title carries a gold icon; inside it sit white tiles. Every
   colour comes from variables.css, so light and dark both follow.
======================================== */

.client-data-group-icon {
  color: var(--gold);
  flex: 0 0 auto;
}

/* The notice naming the missing fields — the prototype's line. The Archive
   tab's two archive-number messages are the same line, and so is the pending
   notice (ticket fx-pending), so their own selectors join this rule (ticket
   98-1c) instead of repeating it. */
.client-data-notice,
.client-archive-note,
.pending-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--status-warning-bg);
  border: 1px solid var(--gold);
  color: var(--status-warning-fg);
  border-radius: var(--radius-md);
  font-size: var(--font-sm);
  font-weight: 700;
  line-height: 1.6;
}

/* The pending notice lays its one line and its open control on one row, and
   wraps on a narrow phone instead of scrolling sideways. */
.pending-notice {
  justify-content: space-between;
  flex-wrap: wrap;
}

.client-data-notice-icon,
.client-archive-note-icon {
  flex: 0 0 auto;
  margin-top: 1px;
}

/* The one loud element: القضية رقم N / year, with the degree chip. */
.client-data-case-id {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-sm);
  border-radius: var(--radius-md);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--gold) 14%, transparent),
    color-mix(in srgb, var(--gold) 4%, transparent)
  );
  border: 1px solid color-mix(in srgb, var(--gold) 45%, transparent);
}

.client-data-case-label {
  font-size: var(--font-xs);
  font-weight: 800;
  color: var(--text-muted);
}

.client-data-case-num {
  font-size: var(--font-2xl);
  font-weight: 900;
  line-height: 1;
  color: var(--heading-text);
}

.client-data-case-num.is-empty {
  color: var(--text-muted);
}

.client-data-case-year {
  font-size: var(--font-md);
  font-weight: 700;
  color: var(--text-muted);
}

.client-data-case-spacer {
  flex: 1 1 auto;
}

.client-data-case-input {
  min-height: calc(32px * var(--ui-scale));
  padding: 0 var(--space-sm);
  border: 1px solid var(--gold);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-md);
  font-weight: 700;
  outline: none;
}

.client-data-case-input--num {
  width: calc(120px * var(--ui-scale));
}

.client-data-case-input--year {
  width: calc(90px * var(--ui-scale));
  margin-inline-start: calc(4px * var(--ui-scale));
}

/* Tiles: a small label, a bold value, «غير مُدخل» for a blank field and a
   red dot on a missing one. */
.client-data-tiles {
  display: grid;
  gap: var(--space-sm);
}

.client-data-tiles.is-2 {
  grid-template-columns: 1fr 1fr;
}

.client-data-tiles.is-3 {
  grid-template-columns: repeat(3, 1fr);
}

.client-data-tiles.is-4 {
  grid-template-columns: repeat(4, 1fr);
}

.client-data-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  min-width: 0;
  padding: var(--space-sm) 11px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.client-data-tile-label {
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--text-muted);
}

.client-data-tile-value {
  font-size: var(--font-md);
  font-weight: 700;
  color: var(--text);
  line-height: 1.35;
  word-break: break-word;
}

.client-data-tile-value.is-empty {
  color: var(--text-muted);
  font-weight: 600;
}

.client-data-tile-flag {
  position: absolute;
  top: calc(6px * var(--ui-scale));
  inset-inline-end: calc(8px * var(--ui-scale));
  width: calc(7px * var(--ui-scale));
  height: calc(7px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--red);
}

.client-data-tile-input {
  width: 100%;
  min-height: calc(32px * var(--ui-scale));
  padding: 0 calc(9px * var(--ui-scale));
  border: 1px solid var(--gold);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-base);
  outline: none;
}

/* The place shown prominently, then the hall and the floor as tiles. */
.client-data-loc-hero {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-sm);
  background: var(--white);
  border: 1px solid var(--border);
  border-inline-start: 4px solid var(--gold);
  border-radius: var(--radius-md);
}

.client-data-loc-icon {
  color: var(--gold);
  flex: 0 0 auto;
}

.client-data-loc-value {
  font-size: var(--font-md);
  font-weight: 800;
  color: var(--heading-text);
  overflow-wrap: anywhere;
}

.client-data-loc-value.is-empty {
  color: var(--text-muted);
  font-weight: 600;
}

.client-data-loc-input {
  width: 100%;
  min-height: calc(32px * var(--ui-scale));
  padding: 0 calc(9px * var(--ui-scale));
  border: 1px solid var(--gold);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-md);
  outline: none;
}

/* The phone, with the WhatsApp action and the tel: Call link beside it. */
.client-data-contact {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.client-data-contact-phone {
  font-size: var(--font-lg);
  font-weight: 800;
  color: var(--heading-text);
  direction: ltr;
  letter-spacing: 0.5px;
}

.client-data-contact-phone.is-empty {
  color: var(--text-muted);
  font-weight: 600;
  direction: rtl;
}

.client-data-contact-input {
  min-height: calc(32px * var(--ui-scale));
  padding: 0 calc(9px * var(--ui-scale));
  border: 1px solid var(--gold);
  border-radius: var(--radius-sm);
  background: var(--white);
  color: var(--text);
  font-family: inherit;
  font-size: var(--font-md);
  outline: none;
}

.client-data-contact-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-inline-start: auto;
}

/* The one line beside the number saying why the WhatsApp action is not
   available — no number saved, or a saved number that is not a valid
   WhatsApp number (ticket 95b, item 2). */
.client-data-contact-note {
  flex-basis: 100%;
  font-size: var(--font-sm);
  font-weight: 600;
  color: var(--text-muted);
}

.client-data-call {
  text-decoration: none;
}

/* The Drive link row — reuses the app's own link treatment. */
.client-data-link-icon {
  color: var(--gold);
  flex: 0 0 auto;
}

/* The Drive row with nothing to open — plain text, never a bare anchor
   (ticket 95b, item 1). */
.client-data-link-empty {
  display: flex;
  align-items: center;
  gap: calc(4px * var(--ui-scale));
  font-size: var(--font-md);
  color: var(--text-muted);
}

/* The case subject — prose, or the autocomplete in edit mode. */
.client-data-topic {
  margin: 0;
  font-size: var(--font-md);
  font-weight: 500;
  line-height: 1.95;
  color: var(--text);
  overflow-wrap: anywhere;
}

.client-data-topic.is-empty {
  color: var(--text-muted);
  font-weight: 600;
}

/* ========================================
   CLIENT NOTES & FILES TABS (ticket 98-1a)
   The two tabs moved to the chosen prototype: each item is a group (the
   shared UiCard) with the gold icon in its title, and each group's own
   actions sit in one row. The title line and its count are the shared
   `.client-tab-head` / `.client-tab-count` pair above. Every colour and size
   comes from variables.css. Scoped to these two tabs' own classes only.
   Ticket 98-1c: the «الأرشيف» tab's group icon and its group's actions join
   the two rules below, so the same look is never written twice.
======================================== */

.client-notes-group-icon,
.client-files-group-icon,
.client-secretaries-group-icon,
.client-archive-group-icon {
  color: var(--gold);
  flex: 0 0 auto;
}

/* The file's name is the group's title; it wraps instead of pushing the card
   wider than the page on a narrow phone. */
.client-files-group-name {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* The items are the prototype's groups now, so the list needs the spacing the
   old divider line gave (ticket 98-1a). */
.client-notes-list-layout,
.client-files-list-layout {
  gap: var(--space-sm);
}

/* The group's own actions: one row that keeps each control's icon and word
   and never shrinks them below their content. The 44px phone floor is in
   styles/mobile.css. */
.client-notes-item-actions,
.client-files-item-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.client-notes-item-actions .btn,
.client-files-item-actions .btn,
.client-archive-actions .btn {
  flex: 0 0 auto;
}

/* The Drive group's open row (ticket 98-1a): the whole row opens the link,
   exactly as the card did before. */
.client-files-drive-open {
  display: flex;
  align-items: center;
  gap: calc(4px * var(--ui-scale));
  min-height: calc(32px * var(--ui-scale));
  cursor: pointer;
}

.client-files-drive-empty {
  font-size: var(--font-md);
  color: var(--text-muted);
}

/* ========================================
   CLIENT SECRETARIES & OPPONENTS TAB (ticket 98-1b)
   The tab moved to the chosen prototype: each list is the Sessions tab's own
   title line (the shared .client-tab-head / .client-tab-count pair above),
   each item is a group (the shared UiCard) whose fields are the prototype's
   tiles (.client-data-tiles / .client-data-tile above), and the item's own
   delete control sits in one row. Every colour and size comes from
   variables.css. Scoped to this tab's own classes only.
======================================== */

/* The items are the prototype's groups now, so the list needs the spacing the
   old divider line gave (ticket 98-1b). This is the lists' one rule: their
   layout lives here now that they left the shared gap-0 rule. */
.secretaries-cards-layout,
.opponents-cards-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The item's own actions: one row that keeps the delete control's icon and
   word and never shrinks it below its content. The 44px phone floor is in
   styles/mobile.css. */
.client-secretaries-item-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.client-secretaries-item-actions .btn {
  flex: 0 0 auto;
}

/* app: styles/admin.css */
/* ========================================
   ADMIN PAGE — صفحة الإدارة
======================================== */

/* ========================================
   FILTER LIST & CHECKBOX
======================================== */

.filter-list {
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  max-height: calc(260px * var(--ui-scale));
  overflow-y: auto;
  padding: calc(4px * var(--ui-scale));
}

.filter-checkbox {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-md);
  cursor: pointer;
  background: var(--surface-subtle);
  color: var(--text);
  font-size: var(--font-sm);
  font-weight: 600;
  transition: 0.15s ease;
  border: 1px solid var(--border);
}

.filter-checkbox:hover {
  background: var(--gold-a08);
  border-color: var(--gold-light);
}

.filter-checkbox input {
  width: calc(14px * var(--ui-scale));
  height: calc(14px * var(--ui-scale));
  cursor: pointer;
  accent-color: var(--gold);
}

/* ========================================
   CLIENT SUGGESTIONS DROPDOWN
======================================== */

.admin-client-suggestions {
  position: absolute;
  top: calc(100% + 4px * var(--ui-scale));
  right: 0;
  width: 100%;
  max-height: calc(200px * var(--ui-scale));
  overflow-y: auto;
  border-radius: var(--radius-md);
  background: var(--white);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  z-index: 9000;
}

.admin-client-suggestion-item {
  padding: calc(8px * var(--ui-scale)) calc(12px * var(--ui-scale));
  cursor: pointer;
  font-size: var(--font-sm);
  font-weight: 600;
  transition: 0.15s ease;
  border-bottom: 1px solid var(--border);
}

.admin-client-suggestion-item:hover {
  background: var(--gold-a08);
  color: var(--gold);
}

/* ========================================
   ADMIN TABLE - تحسين الأعمدة
======================================== */

/* NOTE: table layout (table-layout / min-width) is OWNED BY table.css — see
   its "ADMIN TABLE COLUMNS" section, which sets `table-layout: auto` for this
   same selector. This rule used to also declare `table-layout: fixed`; because
   table.css is loaded after admin.css with equal specificity, that value never
   applied and the column widths below were advisory only. The duplicate was
   removed so there is exactly one owner (report 07 §5.1). If the tuned
   proportions are wanted back, change it in table.css, not here. */

.admin-tab table {
  width: 100%;
}

.admin-tab th:nth-child(1),
.admin-tab td:nth-child(1) {
  width: 12%;
}

.admin-tab th:nth-child(2),
.admin-tab td:nth-child(2) {
  width: 10%;
}

.admin-tab th:nth-child(3),
.admin-tab td:nth-child(3) {
  width: 12%;
}

.admin-tab th:nth-child(4),
.admin-tab td:nth-child(4) {
  width: 8%;
}

/* عمود الإجراءات (procedure) - زودنا عرضه */
.admin-tab th:nth-child(5),
.admin-tab td:nth-child(5) {
  width: 27%;
}

.admin-tab th:nth-child(6),
.admin-tab td:nth-child(6) {
  width: 10%;
}

.admin-tab th:nth-child(7),
.admin-tab td:nth-child(7) {
  width: 10%;
}

/* عمود الإجراءات (الأزرار) - قلصناه */
.admin-tab th:nth-child(8),
.admin-tab td:nth-child(8) {
  width: 3%;
}

.admin-tab td:nth-child(5) {
  white-space: normal;
  word-wrap: break-word;
  text-align: right;
}

.admin-tab td:nth-child(8) {
  white-space: normal;
  word-wrap: break-word;
  text-align: right;
}

/* The completion-notes cell keeps its bold text after the Admin table moved
   onto the shared shell (ticket 96b). reset.css `.completion-cell` (0,1,0) set
   font-weight 700 before the move, but the shell's own `.ui-table tbody td`
   (0,1,2) sets 500 and would win; the extra class here (0,2,0) outranks it.
   The shell puts the class on the column's <th> and <td>, from
   ADMIN_COMPLETED_COLUMN.className. */
.admin-tab .completion-cell {
  font-weight: 700;
}

/* ========================================
   ADMIN RECORD ACTIONS
   Layout: Row 1 = Done (conditional) + View  (icon-only)
           Row 2 = Edit + Delete               (icon-only)
======================================== */

.admin-tab .admin-record-actions {
  display: flex;
  flex-direction: column;
  gap: calc(3px * var(--ui-scale));
  width: 100%;
  min-width: calc(68px * var(--ui-scale));
}

.admin-tab .admin-record-actions .actions-row {
  display: flex;
  gap: calc(3px * var(--ui-scale));
  width: 100%;
}

.admin-tab .admin-record-actions .actions-row .btn {
  flex: 1;
  min-width: 0;
  min-height: calc(28px * var(--ui-scale));
  padding: calc(2px * var(--ui-scale)) calc(4px * var(--ui-scale));
  font-size: 0; /* icon-only: suppress accidental text */
}
/* app: styles/operations.css */
/* created by oran */
/* ========================================
   OPERATIONS CENTER — مركز العمليات
   Ticket ops-b2 / ADR 0015: one card per client, one row per operation.
   Colours and sizes come only from variables.css, so light and dark follow.
======================================== */

.operations-center {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-width: 0;
}

.operations-center-head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.operations-center-title {
  margin: 0;
  font-size: var(--font-lg);
  font-weight: 800;
  color: var(--heading-text);
}

.operations-center-sub {
  margin: calc(2px * var(--ui-scale)) 0 0;
  font-size: var(--font-xs);
  /* --text-muted is 4.44:1 on the light card; the head subtitle takes --text (#213). */
  color: var(--text);
}

/* ========================================
   THE CLIENT CARD
======================================== */

.operations-center-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-width: 0;
}

/* The kit's card padding is removed so the header and rows run edge to edge,
   as the prototype draws them. */
.operations-center-group,
.operations-center-group > .ui-card-body {
  padding: 0;
  gap: 0;
}

.operations-center-group-head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--surface-subtle);
  border-bottom: 1px solid var(--border);
  min-width: 0;
}

.operations-center-group-head.is-collapsed {
  border-bottom: none;
}

.operations-center-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(40px * var(--ui-scale));
  height: calc(40px * var(--ui-scale));
  flex-shrink: 0;
  border-radius: var(--radius-full);
  background: var(--primary);
  color: var(--gold-light);
  font-size: var(--font-base);
  font-weight: 800;
}

.operations-center-who {
  flex: 1;
  min-width: 0;
}

.operations-center-who b {
  display: block;
  font-size: var(--font-base);
  font-weight: 800;
  color: var(--heading-text);
  overflow-wrap: anywhere;
}

.operations-center-meta {
  font-size: var(--font-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.operations-center-count {
  display: inline-block;
  padding: calc(2px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-sm);
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
  font-size: var(--font-xs);
  font-weight: 800;
  white-space: nowrap;
}

/* ========================================
   THE OPERATION BLOCK
======================================== */

/* The card's body parts the blocks by a gap and insets them from the card's
   edge, so no block's surface sits on the card's own edge (#214). */
.operations-center-group-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
}

.operations-center-op {
  background: var(--surface-subtle);
  border-radius: var(--radius-md);
  /* The tint alone is faint on the card; a gold start edge marks each block. */
  border-inline-start: 3px solid var(--gold);
  padding: var(--space-sm) var(--space-md);
  min-width: 0;
}

.operations-center-op-main {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

.operations-center-op-top {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
  min-width: 0;
}

.operations-center-kind {
  display: inline-block;
  padding: calc(2px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-full);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-muted);
  font-size: var(--font-xs);
  font-weight: 700;
}

.operations-center-days {
  display: inline-block;
  padding: calc(2px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-sm);
  font-size: var(--font-xs);
  font-weight: 800;
  white-space: nowrap;
}

.operations-center-days.is-red {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

.operations-center-days.is-gold {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}

.operations-center-what {
  font-size: var(--font-sm);
  font-weight: 700;
  color: var(--text);
  overflow-wrap: anywhere;
}

.operations-center-why {
  font-size: var(--font-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* The pending hearing's stored fields, one line each (#216). */
.operations-center-hearing {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  font-size: var(--font-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* ========================================
   THE READING MARKER AND ITS CHANGE
======================================== */

.operations-center-auto {
  display: inline-flex;
  align-items: center;
  padding: calc(2px * var(--ui-scale)) calc(9px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--status-info-bg);
  color: var(--status-info-fg);
  font-size: var(--font-xs);
  font-weight: 700;
}

.operations-center-reading {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
  font-size: var(--font-xs);
  color: var(--text-muted);
  min-width: 0;
}

.operations-center-reading b,
.operations-center-hearing b {
  color: var(--heading-text);
}

.operations-center-link {
  min-height: calc(28px * var(--ui-scale));
  padding: calc(2px * var(--ui-scale)) calc(4px * var(--ui-scale));
  border: none;
  background: transparent;
  color: var(--gold);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: 800;
  text-decoration: underline;
  cursor: pointer;
}

.operations-center-link.is-locked {
  opacity: 0.45;
  cursor: not-allowed;
}

.operations-center-op-actions {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  min-width: 0;
}

/* The kit's disabled look cannot take this selector: ui.css admits only
   ui- selectors. A locked action stays pressable so it can say why. */
.operations-center-op-action.is-locked,
.operations-center-missing-save.is-locked {
  opacity: 0.45;
  cursor: not-allowed;
}

.operations-center-ignores {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-wrap: wrap;
  margin-top: var(--space-xs);
  padding-top: var(--space-xs);
  border-top: 1px dashed var(--border);
}

.operations-center-ignore {
  min-height: calc(32px * var(--ui-scale));
  padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale));
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-muted);
  font-family: inherit;
  font-size: var(--font-xs);
  font-weight: 700;
  cursor: pointer;
}

.operations-center-ignore:hover {
  background: var(--surface-subtle);
  color: var(--heading-text);
}

.operations-center-ignore.is-danger:hover {
  color: var(--red);
}

.operations-center-reason {
  color: var(--status-danger-fg);
  font-size: var(--font-xs);
  font-weight: 700;
}

/* ========================================
   THE CONFIRMATION LINE
======================================== */

.operations-center-undos {
  position: fixed;
  inset-inline: 0;
  bottom: calc(16px * var(--ui-scale));
  z-index: 400;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: 0 var(--space-md);
  pointer-events: none;
}

.operations-center-undo {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  width: 100%;
  max-width: calc(560px * var(--ui-scale));
  min-width: 0;
  padding: calc(10px * var(--ui-scale)) calc(16px * var(--ui-scale));
  border-radius: var(--radius-md);
  background: var(--primary);
  color: var(--status-neutral-fg);
  box-shadow: var(--shadow-lg);
  font-size: var(--font-sm);
  font-weight: 700;
  pointer-events: auto;
}

.operations-center-undo span {
  min-width: 0;
  overflow-wrap: anywhere;
}

.operations-center-undo button {
  min-height: calc(32px * var(--ui-scale));
  padding: 0 calc(4px * var(--ui-scale));
  border: none;
  background: transparent;
  color: var(--gold-light);
  font-family: inherit;
  font-size: var(--font-sm);
  font-weight: 800;
  text-decoration: underline;
  cursor: pointer;
}

/* ========================================
   ops-b5 — THE MISSING CASE FIELDS
======================================== */

.operations-center-missing {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

.operations-center-missing-rows {
  display: flex;
  align-items: flex-end;
  gap: var(--space-sm);
  flex-wrap: wrap;
  min-width: 0;
}

.operations-center-missing-row {
  display: flex;
  flex-direction: column;
  gap: calc(4px * var(--ui-scale));
  flex: 1 1 calc(180px * var(--ui-scale));
  min-width: 0;
}

.operations-center-missing-label {
  font-size: var(--font-xs);
  font-weight: 700;
  color: var(--heading-text);
}

/* app: styles/agent.css */
/* ========================================
   AGENT — السكرتير
   Shared styling for the full-page tab (.agent-page > .agent-panel)
   and the floating widget (.agent-widget-panel > .agent-panel) —
   the panel itself looks identical everywhere it's mounted.

   Colors come from the app's own tokens (variables.css), so light and
   dark mode work without extra rules. NOTE: in dark mode --white is a
   DARK surface color, so it is used here as "surface" and never as a
   text color — text on a filled control takes --status-neutral-fg.

   The panel is a size container: paddings and columns adapt to the
   width it's actually given (full page vs. 420px widget vs. phone)
   rather than to the viewport.
======================================== */

.agent-page {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 140px);
  height: calc(100dvh - 140px);
  padding: var(--space-lg);
}

.agent-panel {
  --ag-surface: var(--white);
  --ag-raised: var(--card);
  --ag-line: var(--border);
  --ag-ink: var(--text);
  --ag-muted: var(--text-muted);
  --ag-accent: var(--gold);
  --ag-icon: var(--primary);
  --ag-link: var(--primary);
  --ag-send-bg: var(--primary);
  --ag-send-fg: var(--status-neutral-fg);

  container-type: inline-size;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  background: var(--ag-surface);
  color: var(--ag-ink);
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow);
  overflow: hidden;
  font-size: var(--font-md);
}

.dark-mode .agent-panel {
  --ag-icon: var(--gold);
  --ag-link: var(--gold-light);
  --ag-send-bg: var(--gold);
  --ag-send-fg: var(--status-neutral-bg);
}

.agent-panel button:focus-visible,
.agent-panel textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* ---- Mark (identity + "working" ring) ---- */

.agent-mark {
  position: relative;
  flex-shrink: 0;
  width: var(--mark-size, 28px);
  height: var(--mark-size, 28px);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--primary);
  color: var(--gold-light);
  box-shadow: inset 0 0 0 1px var(--gold-a40);
}

.agent-mark-working::before {
  content: '';
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  background: conic-gradient(from 0deg, transparent 0 55%, var(--gold) 100%);
  -webkit-mask: radial-gradient(
    farthest-side,
    transparent calc(100% - 2.5px),
    black calc(100% - 2.5px)
  );
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), black calc(100% - 2.5px));
  animation: agentOrbit 1.1s linear infinite;
}

@keyframes agentOrbit {
  to {
    transform: rotate(360deg);
  }
}

.agent-spin {
  animation: agentOrbit 0.9s linear infinite;
}

/* ---- Header ---- */

.agent-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(8px * var(--ui-scale));
  min-height: calc(54px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(14px * var(--ui-scale));
  background: var(--ag-surface);
  border-bottom: 1px solid var(--ag-line);
  flex-shrink: 0;
}

.agent-header-title {
  display: flex;
  align-items: center;
  gap: calc(10px * var(--ui-scale));
  min-width: 0;
}

.agent-header-name {
  font-weight: 800;
  font-size: var(--font-md);
  white-space: nowrap;
}

.agent-context-chip {
  max-width: calc(200px * var(--ui-scale));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: calc(3px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--ag-raised);
  border: 1px solid var(--ag-line);
  color: var(--ag-muted);
  font-size: var(--font-xs);
  font-weight: 600;
}

.agent-header-actions {
  display: flex;
  align-items: center;
  gap: calc(2px * var(--ui-scale));
  flex-shrink: 0;
}

.agent-icon-btn {
  display: grid;
  place-items: center;
  width: calc(36px * var(--ui-scale));
  height: calc(36px * var(--ui-scale));
  border: none;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--ag-muted);
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}

.agent-icon-btn:hover:not(:disabled),
.agent-icon-btn-active {
  background: var(--ag-raised);
  color: var(--ag-ink);
}

.agent-icon-btn:disabled {
  opacity: 0.35;
  cursor: default;
}

/* ---- Body ---- */

.agent-body {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.agent-chat {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.agent-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: calc(20px * var(--ui-scale)) calc(14px * var(--ui-scale)) calc(8px * var(--ui-scale));
}

.agent-thread {
  display: flex;
  flex-direction: column;
  gap: calc(24px * var(--ui-scale));
  max-width: calc(740px * var(--ui-scale));
  min-height: 100%;
  margin-inline: auto;
}

/* ---- Welcome ---- */

.agent-welcome {
  margin-block: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: calc(8px * var(--ui-scale)) 0;
}

.agent-welcome-title {
  margin: calc(14px * var(--ui-scale)) 0 calc(4px * var(--ui-scale));
  font-size: max(var(--ui-text-min), calc(22px * var(--ui-text-scale)));
  font-weight: 800;
  line-height: 1.4;
}

.agent-welcome-sub {
  margin: 0 0 calc(18px * var(--ui-scale));
  color: var(--ag-muted);
  font-size: var(--font-base);
  line-height: 1.8;
}

.agent-starters {
  width: 100%;
  max-width: calc(520px * var(--ui-scale));
  display: flex;
  flex-direction: column;
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.agent-starter {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: calc(12px * var(--ui-scale));
  padding: calc(9px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border: none;
  border-bottom: 1px solid var(--ag-line);
  border-radius: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: background 0.15s ease;
}

.agent-starter:last-child {
  border-bottom: none;
}
.agent-starter:hover {
  background: var(--ag-raised);
}

.agent-starter-icon {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: calc(34px * var(--ui-scale));
  height: calc(34px * var(--ui-scale));
  border-radius: calc(10px * var(--ui-scale));
  background: var(--ag-raised);
  color: var(--ag-icon);
}

.agent-starter-text {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.agent-starter-title {
  font-size: var(--font-base);
  font-weight: 700;
}

.agent-starter-hint {
  color: var(--ag-muted);
  font-size: var(--font-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- Turns ---- */

.agent-turn {
  display: flex;
  align-items: flex-start;
  gap: calc(12px * var(--ui-scale));
}

/* Universal chat convention regardless of text direction: your own
   messages sit on the near/right side. In an RTL flex row,
   flex-start is the right edge. */
.agent-turn-user {
  justify-content: flex-start;
  animation: agentTurnIn 0.2s ease-out;
}

@keyframes agentTurnIn {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.agent-user-bubble {
  max-width: 86%;
  padding: calc(10px * var(--ui-scale)) calc(16px * var(--ui-scale));
  background: var(--ag-raised);
  border: 1px solid var(--ag-line);
  border-radius: calc(18px * var(--ui-scale));
  border-end-start-radius: var(--radius-sm);
  line-height: 1.8;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.agent-turn-agent > .agent-mark {
  margin-top: calc(2px * var(--ui-scale));
}

.agent-turn-content {
  flex: 1;
  min-width: 0;
}

.agent-turn-error .agent-md {
  color: var(--red);
}

.agent-turn-tools {
  display: flex;
  gap: calc(4px * var(--ui-scale));
  margin-top: calc(8px * var(--ui-scale));
  margin-inline-start: calc(-8px * var(--ui-scale));
}

/* shown only for slow replies — where the seconds went */
.agent-turn-perf {
  align-self: center;
  margin-inline-start: calc(6px * var(--ui-scale));
  color: var(--ag-muted);
  font-size: max(var(--ui-text-min), calc(12px * var(--ui-text-scale)));
  font-variant-numeric: tabular-nums;
}

.agent-tool-btn {
  display: inline-flex;
  align-items: center;
  gap: calc(6px * var(--ui-scale));
  padding: calc(4px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border: none;
  border-radius: calc(8px * var(--ui-scale));
  background: transparent;
  color: var(--ag-muted);
  font: inherit;
  font-size: max(var(--ui-text-min), calc(12px * var(--ui-text-scale)));
  cursor: pointer;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}

.agent-tool-btn:hover {
  background: var(--ag-raised);
  color: var(--ag-ink);
}

/* ---- Markdown (reply body) ---- */

.agent-md {
  line-height: 1.9;
  overflow-wrap: anywhere;
}

.agent-md-block {
  animation: agentBlockIn 0.16s ease-out both;
  animation-delay: calc(var(--i, 0) * 20ms);
}

.agent-md-block + .agent-md-block {
  margin-top: 12px;
}

@keyframes agentBlockIn {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.agent-md-p {
  margin: 0;
}
.agent-md strong {
  font-weight: 700;
}

.agent-md-h {
  margin-top: 6px;
  font-weight: 800;
  line-height: 1.5;
}
.agent-md-h1 {
  font-size: 19px;
}
.agent-md-h2 {
  font-size: 17px;
}
.agent-md-h3 {
  font-size: 16px;
  font-weight: 700;
}

.agent-md-inline-code {
  padding: 1px 6px;
  border: 1px solid var(--ag-line);
  border-radius: 6px;
  background: var(--ag-raised);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.88em;
  unicode-bidi: isolate;
}

.agent-md-link {
  color: var(--ag-link);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.agent-md-quote {
  margin: 0;
  padding-inline-start: 14px;
  border-inline-start: 3px solid var(--ag-accent);
  color: var(--ag-muted);
}

.agent-md-code {
  margin: 0;
  padding: 12px 14px;
  overflow-x: auto;
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-md);
  background: var(--ag-raised);
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 1.7;
}

.agent-md-hr {
  margin: 4px 0;
  border: none;
  border-top: 1px solid var(--ag-line);
}

.agent-md-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.agent-md-li {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding-inline-start: calc(var(--depth, 0) * 22px);
}

.agent-md-marker {
  flex: 0 0 auto;
  min-width: 20px;
  text-align: center;
}

.agent-md-marker-dot::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ag-accent);
  transform: translateY(-2px);
}

.agent-md-marker-num {
  color: var(--ag-muted);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.agent-md-li-text {
  min-width: 0;
}

.agent-md-status {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-lg);
  background: var(--ag-raised);
}

.agent-md-status-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: var(--font-base);
  line-height: 1.7;
}

.agent-md-status-row svg {
  flex-shrink: 0;
  margin-top: 4px;
}
.agent-md-status-done svg {
  color: var(--green);
}
.agent-md-status-blocked {
  color: var(--red);
}
.agent-md-status-pending {
  color: var(--ag-muted);
}

/* The app's global table.css styles bare table/thead/th/td/tr (navy
   gradient header with white text, min-width: 650px, zebra rows, and
   dark-mode row colors), so every property it sets is reset explicitly
   here, under a selector strong enough to beat those rules. */
.agent-md-table-wrap {
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-md);
}

.agent-md .agent-md-table {
  width: auto;
  min-width: 0;
  margin: 0;
  border-collapse: collapse;
  border-spacing: 0;
  border-radius: 0;
  overflow: visible;
  background: transparent;
  table-layout: auto;
  font-size: var(--font-base);
  line-height: 1.6;
}

.agent-md .agent-md-table thead {
  position: static;
  background: var(--ag-raised);
}

.agent-md .agent-md-table thead th {
  position: static;
  padding: 9px 14px;
  background: var(--ag-raised);
  color: var(--ag-ink);
  font-size: var(--font-sm);
  font-weight: 700;
  letter-spacing: 0;
  text-align: start;
  white-space: nowrap;
  border-bottom: 1px solid var(--ag-line);
}

.agent-md .agent-md-table tbody tr,
.agent-md .agent-md-table tbody tr:nth-child(even),
.agent-md .agent-md-table tbody tr:hover {
  background: transparent;
}

.agent-md .agent-md-table tbody td,
.agent-md .agent-md-table tbody tr:hover td {
  padding: 9px 14px;
  color: var(--ag-ink);
  font-size: var(--font-base);
  font-weight: 400;
  line-height: 1.6;
  text-align: start;
  vertical-align: top;
  border-bottom: 1px solid var(--ag-line);
  font-variant-numeric: tabular-nums;
}

.agent-md .agent-md-table tbody tr:last-child td {
  border-bottom: none;
}

/* ---- Actions trail ---- */

.agent-trail {
  margin-bottom: calc(10px * var(--ui-scale));
}

.agent-trail-toggle {
  display: inline-flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  padding: calc(4px * var(--ui-scale)) calc(10px * var(--ui-scale)) calc(4px * var(--ui-scale))
    calc(8px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-full);
  background: var(--ag-raised);
  color: var(--ag-muted);
  font: inherit;
  font-size: var(--font-sm);
  font-weight: 600;
  cursor: pointer;
}

.agent-trail-count {
  display: grid;
  place-items: center;
  min-width: calc(20px * var(--ui-scale));
  height: calc(20px * var(--ui-scale));
  padding: 0 calc(6px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-full);
  background: var(--ag-surface);
  color: var(--ag-ink);
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  font-variant-numeric: tabular-nums;
}

.agent-trail-count-failed {
  color: var(--red);
  border-color: var(--red);
}

.agent-trail-count-partial {
  color: var(--warning-text);
  border-color: var(--gold);
}

.agent-trail-chevron {
  transition: transform 0.18s ease;
}
.agent-trail-open .agent-trail-chevron {
  transform: rotate(180deg);
}

.agent-trail-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(6px * var(--ui-scale));
  margin: calc(8px * var(--ui-scale)) 0 0;
  margin-inline-start: calc(10px * var(--ui-scale));
  padding: calc(2px * var(--ui-scale)) 0 0;
  padding-inline-start: calc(12px * var(--ui-scale));
  border-inline-start: 2px solid var(--ag-line);
}

.agent-trail-item {
  display: flex;
  align-items: flex-start;
  gap: calc(8px * var(--ui-scale));
  color: var(--ag-muted);
  font-size: var(--font-sm);
  line-height: 1.6;
}

.agent-trail-item svg {
  flex-shrink: 0;
  margin-top: calc(3px * var(--ui-scale));
  color: var(--green);
}
.agent-trail-item-failed {
  color: var(--red);
}
.agent-trail-item-failed svg {
  color: var(--red);
}
/* Partly done: main step succeeded, a follow-up failed — amber, not red. */
.agent-trail-item-partial {
  color: var(--warning-text);
}
.agent-trail-item-partial svg {
  color: var(--gold);
}

/* ---- Working state + live plan ---- */

.agent-working {
  padding-top: calc(4px * var(--ui-scale));
  color: var(--ag-muted);
}

.agent-shimmer {
  background: linear-gradient(90deg, var(--ag-muted) 0%, var(--ag-ink) 45%, var(--ag-muted) 90%);
  background-size: 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  animation: agentShimmer 1.6s linear infinite;
}

@keyframes agentShimmer {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -200% 0;
  }
}

.agent-plan {
  margin-top: calc(12px * var(--ui-scale));
  padding: calc(12px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-lg);
  background: var(--ag-raised);
}

.agent-plan-progress-text {
  margin-inline-start: auto;
  color: var(--ag-muted);
  font-variant-numeric: tabular-nums;
  direction: ltr;
}

.agent-plan-bar {
  height: calc(4px * var(--ui-scale));
  margin-bottom: calc(12px * var(--ui-scale));
  border-radius: var(--radius-full);
  background: var(--ag-line);
  overflow: hidden;
}

.agent-plan-bar-fill {
  height: 100%;
  border-radius: inherit;
  background: var(--ag-accent);
  transition: width 0.4s ease;
}

.agent-plan-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  margin: 0;
  padding: 0;
}

.agent-plan-row {
  display: flex;
  align-items: flex-start;
  gap: calc(8px * var(--ui-scale));
  color: var(--ag-muted);
  font-size: var(--font-sm);
  line-height: 1.6;
}

.agent-plan-row svg {
  flex-shrink: 0;
  margin-top: calc(2px * var(--ui-scale));
}
.agent-plan-row-done {
  color: var(--ag-ink);
}
.agent-plan-row-done svg {
  color: var(--green);
}
.agent-plan-row-blocked {
  color: var(--red);
}
.agent-plan-row-waiting {
  color: var(--ag-ink);
}
.agent-plan-row-waiting svg {
  color: var(--ag-accent);
}
.agent-plan-row-skipped {
  color: var(--ag-muted);
  text-decoration: line-through;
}
.agent-plan-row-current {
  color: var(--ag-ink);
  font-weight: 600;
}
.agent-plan-row-current svg {
  color: var(--ag-accent);
}

/* ---- Confirmation card ---- */

.agent-confirm {
  margin-top: calc(12px * var(--ui-scale));
  padding: calc(12px * var(--ui-scale)) calc(14px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-lg);
  background: var(--ag-raised);
  font-size: var(--font-sm);
}

.agent-confirm-ask {
  background: var(--surface-warning);
  border-color: var(--gold);
}

.agent-confirm-summary {
  margin: calc(8px * var(--ui-scale)) 0 calc(12px * var(--ui-scale));
  color: var(--ag-ink);
  font-size: var(--font-base);
  line-height: 1.8;
}

.agent-confirm-actions {
  display: flex;
  gap: calc(8px * var(--ui-scale));
}

.agent-confirm-btn {
  min-height: calc(40px * var(--ui-scale));
  padding: 0 calc(24px * var(--ui-scale));
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
  transition:
    filter 0.15s ease,
    background 0.15s ease;
}

.agent-confirm-btn-yes {
  background: var(--ag-send-bg);
  color: var(--ag-send-fg);
}

.agent-confirm-btn-yes:hover {
  filter: brightness(1.12);
}

.agent-confirm-btn-no {
  background: transparent;
  border-color: var(--ag-line);
  color: var(--ag-ink);
}

.agent-confirm-btn-no:hover {
  background: var(--ag-raised);
}

.agent-confirm-destructive {
  border-color: var(--red);
}
.agent-confirm-destructive .ui-card-title {
  color: var(--red);
  border-inline-start-color: var(--red);
}
.agent-confirm-destructive .agent-confirm-btn-yes {
  background: var(--red);
  color: var(--status-neutral-fg);
}

.agent-confirm-running {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  line-height: 1.7;
}

.agent-confirm-done,
.agent-confirm-failed,
.agent-confirm-cancelled {
  line-height: 1.7;
}

.agent-confirm-result {
  display: flex;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
}

.agent-confirm-running,
.agent-confirm-cancelled {
  color: var(--ag-muted);
}
.agent-confirm-done {
  color: var(--green);
  border-color: var(--green);
}
.agent-confirm-failed {
  color: var(--red);
  border-color: var(--red);
}
.agent-confirm-warning {
  color: var(--warning-text);
  background: var(--surface-warning);
  border-color: var(--gold);
  line-height: 1.7;
}
/* Partly done: the main record was saved but a follow-up step failed — amber,
   deliberately distinct from the red full failure. */
.agent-confirm-partial {
  color: var(--warning-text);
  background: var(--surface-warning);
  border-color: var(--gold);
  line-height: 1.7;
}
.agent-confirm svg {
  flex-shrink: 0;
}

/* ---- Change details (which record, old -> new) ---- */

.agent-changes {
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  margin: calc(10px * var(--ui-scale)) 0 calc(12px * var(--ui-scale));
  padding: calc(10px * var(--ui-scale)) calc(12px * var(--ui-scale));
  background: var(--ag-surface);
  border: 1px solid var(--ag-line);
  border-radius: var(--radius-md);
  color: var(--ag-ink);
  font-size: var(--font-sm);
}

.agent-change-target {
  font-weight: 700;
  line-height: 1.6;
}

.agent-change-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: calc(8px * var(--ui-scale));
  margin: 0;
  padding: 0;
}

.agent-change-row {
  display: flex;
  flex-direction: column;
  gap: calc(3px * var(--ui-scale));
  padding-top: calc(8px * var(--ui-scale));
  border-top: 1px dashed var(--ag-line);
}

.agent-change-label {
  color: var(--ag-muted);
  font-size: max(var(--ui-text-min), calc(12px * var(--ui-text-scale)));
  font-weight: 600;
}

.agent-change-values {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: calc(8px * var(--ui-scale));
  line-height: 1.6;
}

.agent-change-old {
  color: var(--ag-muted);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.agent-change-new {
  font-weight: 700;
}
.agent-change-arrow {
  flex-shrink: 0;
  color: var(--ag-muted);
}

.agent-change-tag {
  padding: 1px calc(8px * var(--ui-scale));
  border-radius: var(--radius-full);
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  font-weight: 700;
  white-space: nowrap;
}

.agent-change-tag-new {
  background: var(--status-ok-bg);
  color: var(--green);
}
.agent-change-tag-removed {
  background: var(--status-danger-bg);
  color: var(--red);
}

.agent-change-detail-text {
  margin: calc(2px * var(--ui-scale)) 0 0;
  padding: calc(8px * var(--ui-scale)) calc(10px * var(--ui-scale));
  border-radius: calc(8px * var(--ui-scale));
  background: var(--ag-raised);
  line-height: 1.8;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.agent-change-note {
  color: var(--ag-muted);
  font-size: max(var(--ui-text-min), calc(12px * var(--ui-text-scale)));
  line-height: 1.6;
}

.agent-change-warning {
  display: flex;
  align-items: flex-start;
  gap: calc(6px * var(--ui-scale));
  padding: calc(6px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: calc(8px * var(--ui-scale));
  background: var(--surface-warning);
  color: var(--warning-text);
  line-height: 1.6;
}

.agent-change-warning svg {
  flex-shrink: 0;
  margin-top: calc(3px * var(--ui-scale));
}

.agent-change-warning-danger {
  background: var(--status-danger-bg);
  color: var(--red);
  font-weight: 600;
}

.agent-trail-item-body {
  flex: 1;
  min-width: 0;
}
.agent-trail-item .agent-changes {
  margin: calc(6px * var(--ui-scale)) 0 calc(4px * var(--ui-scale));
}

/* ---- Composer ---- */

.agent-composer-wrap {
  position: relative;
  flex-shrink: 0;
  padding: calc(8px * var(--ui-scale)) calc(14px * var(--ui-scale)) max(12px, var(--safe-bottom));
}

.agent-composer,
.agent-composer-hint {
  max-width: calc(740px * var(--ui-scale));
  margin-inline: auto;
}

.agent-composer {
  display: flex;
  align-items: flex-end;
  gap: calc(8px * var(--ui-scale));
  padding: calc(6px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: calc(24px * var(--ui-scale));
  background: var(--ag-surface);
  box-shadow: var(--shadow);
  transition:
    border-color 0.15s ease,
    box-shadow 0.15s ease;
}

.agent-composer:focus-within {
  border-color: var(--gold);
  box-shadow: 0 0 0 3px var(--gold-a15);
}

/* The composer's own field (the kit's UiFormField): it is the flex item that
   takes the row's free space, so the input inside it never widens the panel. */
.agent-composer-field {
  flex: 1;
}

.agent-composer-input {
  min-width: 0;
  max-height: calc(168px * var(--ui-scale));
  padding: calc(8px * var(--ui-scale)) calc(12px * var(--ui-scale));
  border: none;
  outline: none;
  background: transparent;
  color: inherit;
  font: inherit;
  font-size: var(--font-md);
  line-height: 1.7;
  resize: none;
  overflow-y: auto;
}

.agent-composer-input::placeholder {
  color: var(--ag-muted);
}

/* Focus is shown on the whole composer (:focus-within above). */
.agent-panel .agent-composer-input:focus-visible {
  outline: none;
}

.agent-send {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: calc(38px * var(--ui-scale));
  height: calc(38px * var(--ui-scale));
  border: none;
  border-radius: 50%;
  background: var(--ag-send-bg);
  color: var(--ag-send-fg);
  cursor: pointer;
  transition:
    filter 0.15s ease,
    background 0.15s ease;
}

.agent-send:hover:not(:disabled) {
  filter: brightness(1.15);
}

.agent-send:disabled {
  background: var(--ag-line);
  color: var(--ag-muted);
  cursor: default;
}

.agent-composer-hint {
  display: none;
  margin-top: calc(6px * var(--ui-scale));
  color: var(--ag-muted);
  font-size: max(var(--ui-text-min), calc(11.5px * var(--ui-text-scale)));
  text-align: center;
}

.agent-composer-hint kbd {
  display: inline-block;
  padding: 0 calc(5px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: calc(5px * var(--ui-scale));
  background: var(--ag-raised);
  color: #62728b;
  font: inherit;
  font-size: max(var(--ui-text-min), calc(11px * var(--ui-text-scale)));
  direction: ltr;
  unicode-bidi: isolate;
}

@media (hover: hover) and (pointer: fine) {
  .agent-composer-hint {
    display: block;
  }
}

.agent-jump {
  position: absolute;
  top: calc(-42px * var(--ui-scale));
  inset-inline-start: 50%;
  transform: translateX(50%);
  display: grid;
  place-items: center;
  width: calc(34px * var(--ui-scale));
  height: calc(34px * var(--ui-scale));
  border: 1px solid var(--ag-line);
  border-radius: 50%;
  background: var(--ag-surface);
  color: var(--ag-ink);
  box-shadow: var(--shadow-lg);
  cursor: pointer;
}

@media (max-height: 640px) {
  .agent-welcome-sub {
    display: none;
  }
}

/* ---- Container-width adaptations ---- */

@container (min-width: 640px) {
  .agent-scroll {
    padding: calc(28px * var(--ui-scale)) calc(24px * var(--ui-scale)) calc(8px * var(--ui-scale));
  }
  .agent-composer-wrap {
    padding: calc(8px * var(--ui-scale)) calc(24px * var(--ui-scale)) max(16px, var(--safe-bottom));
  }
  .agent-welcome-title {
    font-size: max(var(--ui-text-min), calc(26px * var(--ui-text-scale)));
  }
  .agent-user-bubble {
    max-width: 74%;
  }
}

@container (max-width: 460px) {
  .agent-context-chip {
    max-width: 120px;
  }
  .agent-md .agent-md-table thead th,
  .agent-md .agent-md-table tbody td,
  .agent-md .agent-md-table tbody tr:hover td {
    padding: 7px 10px;
    font-size: var(--font-sm);
  }
}

/* ========================================
   ACTIVITY LOG (inline layer over the chat — so this section uses the
   app's base tokens, not the panel-scoped --ag-* ones)
======================================== */

.agent-log-layer {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  background: var(--white);
}

.agent-log-panel {
  flex: 1;
  overflow-y: auto;
  padding: calc(12px * var(--ui-scale)) calc(16px * var(--ui-scale)) calc(20px * var(--ui-scale));
}

.agent-log-list {
  list-style: none;
  display: flex;
  flex-direction: column;
  max-width: calc(740px * var(--ui-scale));
  margin: 0 auto;
  padding: 0;
}

.agent-log-list li {
  display: flex;
  align-items: flex-start;
  gap: calc(12px * var(--ui-scale));
  padding: calc(12px * var(--ui-scale)) calc(4px * var(--ui-scale));
  border-bottom: 1px solid var(--border);
}

.agent-log-list li:last-child {
  border-bottom: none;
}

.agent-log-item-body {
  flex: 1;
  min-width: 0;
}

.agent-log-ok svg {
  color: var(--green);
  flex-shrink: 0;
  margin-top: calc(3px * var(--ui-scale));
}
.agent-log-failed svg {
  color: var(--red);
  flex-shrink: 0;
  margin-top: calc(3px * var(--ui-scale));
}

.agent-log-item-summary {
  font-size: var(--font-base);
  line-height: 1.7;
  text-align: right;
}

.agent-log-item-details {
  margin-top: calc(4px * var(--ui-scale));
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: 1.7;
  white-space: pre-line;
  text-align: right;
}

.agent-log-item-meta {
  margin-top: calc(2px * var(--ui-scale));
  color: var(--text-muted);
  font-size: var(--font-xs);
  direction: ltr;
  text-align: right;
  unicode-bidi: plaintext;
}

/* ========================================
   FLOATING WIDGET (client file pages)
======================================== */

/* Pinned bottom-left — the inline end of an RTL page, matching the widget's
   own comment. */
.agent-fab {
  position: fixed;
  bottom: max(20px, calc(var(--safe-bottom) + 16px));
  left: max(20px, calc(var(--safe-left) + 16px));
  z-index: 9200;
  width: calc(56px * var(--ui-scale));
  height: calc(56px * var(--ui-scale));
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
  color: var(--gold-light);
  box-shadow:
    var(--shadow-lg),
    0 0 0 1px var(--gold-a40);
  cursor: pointer;
  transition:
    transform 0.15s ease,
    box-shadow 0.15s ease;
}

.agent-fab:hover {
  transform: scale(1.06);
  box-shadow:
    var(--shadow-lg),
    0 0 0 1px var(--gold-a40);
}

.agent-fab:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 3px;
}

.agent-widget-overlay {
  position: fixed;
  inset: 0;
  z-index: 9300;
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  padding: calc(max(20px, var(--safe-bottom)) * var(--ui-scale));
  background: var(--scrim);
  backdrop-filter: blur(2px);
  animation: agentOverlayIn 0.18s ease;
}

/* Panel stays mounted after first open (so the conversation survives
   close/reopen — see AgentFloatingWidget.jsx) but must be fully
   invisible and non-interactive while "closed", not just visually
   behind other content. */
.agent-widget-overlay-hidden {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  animation: none;
}

@keyframes agentOverlayIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.agent-widget-panel {
  width: calc(420px * var(--ui-scale));
  max-width: 100%;
  height: min(680px, calc(100vh - 40px));
  height: min(680px, calc(100dvh - 40px));
  animation: agentPanelIn 0.2s ease;
}

.agent-widget-panel .agent-panel {
  height: 100%;
  box-shadow: var(--shadow-lg);
}

@keyframes agentPanelIn {
  from {
    opacity: 0;
    transform: translateY(16px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (max-width: 768px) {
  .agent-page {
    height: calc(100vh - 110px);
    height: calc(100dvh - 110px);
    padding: var(--space-sm);
  }

  /* Full-screen on a phone: the panel's header (close button!) would
       otherwise sit under the clock / dynamic island. The overlay's top
       safe-area strip is filled with the app's navy so the translucent
       status bar reads exactly like it does on every other screen. */
  .agent-widget-overlay {
    padding: var(--safe-top) 0 0;
    align-items: stretch;
    background: var(--primary);
    backdrop-filter: none;
  }

  .agent-widget-panel {
    width: 100%;
    height: 100%;
    max-width: 100%;
    animation: agentPanelInMobile 0.2s ease;
  }

  .agent-widget-panel .agent-panel {
    border-radius: 0;
    border: none;
  }

  @keyframes agentPanelInMobile {
    from {
      opacity: 0;
      transform: translateY(100%);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

/* ---- Reduced motion: nothing animates on its own ---- */

@media (prefers-reduced-motion: reduce) {
  .agent-turn-user,
  .agent-md-block,
  .agent-mark-working::before,
  .agent-spin,
  .agent-widget-overlay,
  .agent-widget-panel {
    animation: none !important;
  }

  .agent-shimmer {
    animation: none;
    background: none;
    color: var(--ag-muted);
  }

  .agent-plan-bar-fill,
  .agent-trail-chevron {
    transition: none;
  }
}

/* app: styles/legalLibrary.css */
/* ========================================
   LEGAL LIBRARY SCREEN (ticket #56, 98-4a)
   The read-only stored-laws screen, moved onto the chosen prototype: a page
   head, section titles with their count, the prototype's rows and its chip
   marks. Every selector is "legal-"-prefixed, so it restyles nothing that
   already exists, and every colour comes from the existing variables.
======================================== */

.legal-library {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.legal-library-hint {
  margin: 0;
  /* --text-muted is 4.44:1 on the light card; the hint takes --text (#213). */
  color: var(--text);
  font-size: var(--font-sm);
}

/* The search: the kit's own field, with the search control beside it. */
.legal-library-search {
  display: flex;
  align-items: flex-end;
  gap: var(--space-sm);
}

.legal-library-search-field {
  flex: 1;
  min-width: 0;
}

.legal-library-search .ui-btn {
  white-space: nowrap;
}

/* The error line the Manager's panels share (LegalLibraryManagePanel,
   LegalOldCopyDeleteSection); this screen shows its failures through the
   kit's state block instead. */
.legal-library-error {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
  font-size: var(--font-sm);
  font-weight: 600;
}

/* ========================================
   THE SECTION TITLE AND ITS LIST
   Opening a law replaces the list of laws with that law's articles — over a
   thousand rows for one law — so the way back sits at the TOP of the view,
   beside the title, and sticks to the top of the list area so it stays
   reachable without scrolling to the last row. The head takes the same
   surface token as the rows it heads (--card), so it introduces no new
   colour, and it is opaque so the rows do not show through it.
======================================== */

.legal-library-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.legal-library-section-head {
  position: sticky;
  top: var(--safe-top);
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  flex-wrap: wrap;
  padding: var(--space-sm) var(--space-md);
  background: var(--card);
}

.legal-library-section-title {
  margin: 0;
  color: var(--heading-text);
  font-size: var(--font-base);
  font-weight: 800;
}

.legal-library-section-tools {
  display: inline-flex;
  align-items: center;
  gap: var(--space-sm);
  flex: 0 0 auto;
}

/* The prototype's .count badge: the rows the view is showing. */
.legal-library-count {
  color: var(--text-muted);
  font-size: var(--font-xs);
  font-weight: 700;
  white-space: nowrap;
}

.legal-library-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  margin: 0 0 var(--space-md);
  padding: 0;
  list-style: none;
}

.legal-library-row {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  width: 100%;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  text-align: start;
  cursor: pointer;
}

.legal-library-row:hover {
  border-color: var(--gold);
}

.legal-library-row-title {
  color: var(--heading-text);
  font-size: var(--font-sm);
  font-weight: 700;
  overflow-wrap: anywhere;
}

.legal-library-row-text {
  color: var(--text-muted);
  font-size: var(--font-xs);
  overflow-wrap: anywhere;
}

/* ========================================
   THE ARTICLE MARKS
   The prototype's chip (section 8-5's «غير موثّقة» mark), on the app's own
   status tokens, so light and dark both follow. «غير مؤكدة» and «محتاج
   مراجعة» read as the problem tone; the copies-differ caution is the softer
   warning tone; the source mark is quiet.
======================================== */

.legal-library-marks {
  display: flex;
  flex-wrap: wrap;
  gap: calc(4px * var(--ui-scale));
  margin-top: calc(4px * var(--ui-scale));
}

.legal-library-mark {
  display: inline-flex;
  align-items: center;
  border-radius: var(--radius-full);
  padding: calc(2px * var(--ui-scale)) calc(10px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 700;
  white-space: nowrap;
}

.legal-library-mark.is-danger {
  background: var(--status-danger-bg);
  color: var(--status-danger-fg);
}

.legal-library-mark.is-warn {
  background: var(--status-warning-bg);
  color: var(--status-warning-fg);
}

.legal-library-mark.is-neutral {
  background: var(--status-neutral-bg);
  color: var(--status-neutral-fg);
}

/* ========================================
   ONE ARTICLE
   The article's text is legal data: its own line breaks are kept
   (white-space: pre-wrap) and nothing is trimmed or reflowed. Its frame is
   the prototype's source block (--surface-subtle with the app's border).
======================================== */

.legal-article {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.legal-article-title {
  margin: 0;
  color: var(--text);
  font-size: var(--font-md);
  font-weight: 700;
}

.legal-article-text {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  background: var(--surface-subtle);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  font-size: var(--font-base);
  line-height: 1.9;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.legal-article-source {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  color: var(--text-muted);
  font-size: var(--font-xs);
  overflow-wrap: anywhere;
}

.legal-article-source-link {
  color: var(--heading-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ========================================
   THE MANAGE / IMPORT / OLD-COPY SECTIONS (ticket 98-4b)
   The three sections inside the Settings «النصوص القانونية» modal, now on the
   kit's blocks. Layout only — every class is "legal-manage"-prefixed, so
   nothing else is restyled, and every colour comes from the existing
   variables, so dark mode follows without a second rule.
======================================== */

.legal-manage {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.legal-manage-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

/* The pasted law's own box: it may be resized, and its text wraps inside it. */
.legal-manage-textarea {
  resize: vertical;
  overflow-wrap: anywhere;
}

/* The size line: the text takes the room, the warning chip keeps its shape. */
.legal-manage-size {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin: 0;
}

.legal-manage-due {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
}

.legal-manage-due-row {
  margin: 0;
  overflow-wrap: anywhere;
}

/* The article's stored wording: a read-only block that wraps its own text. */
.legal-manage-readonly {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
}

.legal-manage-readonly-text {
  margin: 0;
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  overflow-wrap: anywhere;
}

/* The before / after view: one block per wording, each wrapping on its own.
   A span with display:block, so the same view is valid inside the form and
   inside the confirmation block's paragraph. */
.legal-manage-preview {
  display: block;
}

.legal-manage-preview-text {
  display: block;
  overflow-wrap: anywhere;
}

.legal-manage-history {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  /* The correction's source address is long and unbroken: it wraps here. */
  overflow-wrap: anywhere;
}

/* The saved laws and their previous versions. */
.legal-manage-saved {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.legal-manage-saved-law {
  display: flex;
  flex-direction: column;
  gap: calc(4px * var(--ui-scale));
}

.legal-manage-saved-version {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.legal-manage-saved-when {
  flex: 1;
  min-width: 0;
  font-size: var(--font-xs);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* app: styles/table.css */
/* ========================================
   TABLES — الجداول وعناصر البيانات
======================================== */

/* ========================================
   TABLE WRAPPER — removed (ticket 96c)

   Every screen now renders through UiTableShell, so nothing uses the old
   `.table-wrapper` any more and its rules were removed: `.table-wrapper`,
   `.table-wrapper thead` and `.table-wrapper thead th`. The shell's own
   `.ui-table-shell` (styles/ui.css) owns the wrapper box, and its
   `.ui-table thead th` owns the sticky header.
======================================== */

/* ========================================
   TABLE BASE
======================================== */

table {
  width: 100%;
  min-width: calc(650px * var(--ui-scale));
  table-layout: auto;
  border-collapse: collapse;
  border-spacing: 0;
  overflow: hidden;
  border-radius: var(--radius-lg);
  /* var(--white) is #ffffff in light mode (identical to the old literal)
       and #1a1a2e in dark — the literal left every table a light island. */
  background: var(--white);
}

/* ========================================
   TABLE HEAD
======================================== */

thead {
  background: linear-gradient(135deg, var(--primary), var(--primary-dark));
}

thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: calc(8px * var(--ui-scale)) calc(8px * var(--ui-scale));
  color: var(--status-neutral-fg);
  font-size: var(--font-xs);
  font-weight: 700;
  text-align: center;
  letter-spacing: 0.2px;
  border-bottom: 1px solid var(--on-dark-a10);
}

/* ========================================
   TABLE BODY
======================================== */

tbody tr {
  background: var(--white);
}

tbody tr:nth-child(even) {
  background: var(--row-alt);
}

tbody tr:hover {
  background: var(--gold-a08);
}

tbody tr:hover td {
  color: var(--heading-text);
}

tbody tr:last-child td {
  border-bottom: none;
}

tbody td {
  padding: calc(7px * var(--ui-scale)) calc(8px * var(--ui-scale));
  font-size: var(--font-xs);
  font-weight: 500;
  text-align: center;
  line-height: 1.4;
  vertical-align: middle;
  color: var(--text);
  border-bottom: 1px solid var(--border);
}

/* ========================================
   TABLE BUTTONS
======================================== */

table .btn {
  padding: calc(4px * var(--ui-scale)) calc(8px * var(--ui-scale));
  font-size: var(--font-2xs);
  border-radius: var(--radius-sm);
  min-height: calc(28px * var(--ui-scale));
  min-width: calc(50px * var(--ui-scale));
}

/* ========================================
   ADMIN RECORD ACTIONS - تم نقلها إلى admin.css
   لتجنب التعارض
======================================== */

/* ========================================
   ADMIN DEADLINE CELL
======================================== */

.admin-deadline-cell {
  display: flex;
  flex-direction: column;
  gap: calc(2px * var(--ui-scale));
  align-items: center;
}

.admin-deadline-date {
  font-weight: 700;
  color: var(--text);
}

/* ========================================
   SESSION DATE CELL
======================================== */

.session-date-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(4px * var(--ui-scale));
}

.session-date-value {
  font-weight: 600;
}

/* ========================================
   SESSION ACTIONS COLUMN
   Layout: Row 1 = Edit + Delete (icon-only, side-by-side)
           Row 2 = View  (icon-only, full-width)
======================================== */

.session-actions-column {
  display: flex;
  flex-direction: column;
  gap: calc(4px * var(--ui-scale));
  min-width: calc(72px * var(--ui-scale)); /* prevents the column from collapsing too narrow */
}

/* A horizontal sub-row inside the actions column */
.session-actions-column .session-actions-row {
  display: flex;
  gap: calc(4px * var(--ui-scale));
  width: 100%;
}

/* Buttons inside horizontal rows: equal share of available width */
.session-actions-column .session-actions-row .btn {
  flex: 1;
  min-width: calc(28px * var(--ui-scale));
  min-height: calc(30px * var(--ui-scale));
  padding: calc(3px * var(--ui-scale)) calc(5px * var(--ui-scale));
  font-size: 0; /* suppress accidental text nodes */
}

/* View row — single button, full column width */
.session-actions-column .session-view-row {
  width: 100%;
}

.session-actions-column .session-view-row .btn {
  width: 100%;
  min-height: calc(28px * var(--ui-scale));
  padding: calc(3px * var(--ui-scale)) calc(5px * var(--ui-scale));
  font-size: 0;
}

/* ========================================
   HIGHLIGHTED SESSION ROW (urgent)
======================================== */

.highlight-row,
.highlighted-session-row {
  animation: highlightedSessionPulse 1.5s infinite alternate;
}

.highlighted-session-row td,
.highlight-row td {
  background: var(--gold-a40) !important;
  border-top: 1px solid var(--gold-a40);
  border-bottom: 1px solid var(--gold-a40);
}

@keyframes highlightedSessionPulse {
  from {
    transform: scale(1);
  }

  to {
    transform: scale(1.05);
  }
}

/* ========================================
   MUHADREEN TABLE COLUMNS
======================================== */

.muhadreen-tab tbody td {
  font-size: var(--font-2xs);
  padding: calc(5px * var(--ui-scale)) calc(5px * var(--ui-scale));
}

.muhadreen-tab table {
  table-layout: auto;
  min-width: calc(650px * var(--ui-scale));
}

.muhadreen-session-cell {
  display: flex;
  flex-direction: column;
  gap: calc(3px * var(--ui-scale));
  align-items: center;
}

.muhadreen-tab .action-group {
  display: flex;
  flex-direction: column;
  gap: calc(3px * var(--ui-scale));
}

.muhadreen-tab .action-group .btn {
  width: 100%;
  padding: calc(4px * var(--ui-scale)) calc(5px * var(--ui-scale));
  font-size: var(--font-2xs);
  min-width: 0;
}

/* ========================================
   ADMIN TABLE COLUMNS
======================================== */

.admin-tab table {
  table-layout: auto;
  min-width: calc(650px * var(--ui-scale));
}

.admin-tab tbody td {
  font-size: var(--font-2xs);
  line-height: 1.3;
  padding-top: calc(4px * var(--ui-scale));
  padding-bottom: calc(4px * var(--ui-scale));
}

/* ========================================
   ADMIN RECORD ACTIONS - الأزرار داخل admin
   تم نقلها إلى admin.css
======================================== */

.admin-tab .admin-record-actions .btn {
  font-size: var(--font-2xs);
  padding: calc(3px * var(--ui-scale)) calc(5px * var(--ui-scale));
}

/* ========================================
   CLIENT SESSIONS TABLE COLUMNS
======================================== */

.client-sessions-table table {
  table-layout: auto;
  /* The prototype's own table width: every column gets the room it was
       designed with, and the table scrolls sideways inside its own frame
       instead of squeezing the columns (ticket 95c). 660px on a phone — see
       the 768px block in styles/mobile.css. */
  min-width: calc(700px * var(--ui-scale));
}

.client-sessions-table tbody td {
  /* The prototype's body text — 13px (--font-sm) on a desktop and on a
       phone, replacing the 10px the old layout used (ticket 95c). The
       readable-phone rule in ui.css keeps the same size at 768px and below. */
  font-size: var(--font-sm);
  padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale));
  line-height: 1.35;
}

.client-sessions-table .action-group {
  display: flex;
  flex-direction: column;
  gap: calc(3px * var(--ui-scale));
}

.client-sessions-table .action-group .btn {
  width: 100%;
  min-width: 0;
  padding: calc(4px * var(--ui-scale)) calc(6px * var(--ui-scale));
  font-size: var(--font-2xs);
}

/* ========================================
   CLIENT SESSION ACTIONS — one column
   عمود الإجراءات: زر تحت زر

   The prototype's .row-actions: one column of full-width controls, each
   showing its icon and its word at every width — never side by side, never
   shrunk below its own content (ticket 95c). The column's width comes from
   the buttons' content with this minimum, NOT from a percentage of the
   table. The expert table reuses the very same class, so one rule covers
   both; the per-table button rules live in styles/client.css.
======================================== */

.client-sessions-actions {
  display: flex;
  flex-direction: column;
  gap: calc(5px * var(--ui-scale));
  width: 100%;
  min-width: calc(96px * var(--ui-scale));
}

/* زر تسجيل — gold and full width, like its siblings. */
.client-sessions-actions .send-btn {
  width: 100%;
  background-color: var(--gold);
  color: var(--primary-dark);
  border: none;
}

/* ========================================
   ARCHIVE TABLE COLUMNS
======================================== */

.archive-tab .countdown-red {
  width: fit-content;
  margin: auto;
  padding: calc(4px * var(--ui-scale)) calc(8px * var(--ui-scale));
  border-radius: var(--radius-sm);
  font-size: var(--font-2xs);
  font-weight: 700;
}

.archive-tab table td:nth-child(5),
.archive-tab table td:nth-child(6) {
  white-space: nowrap;
}
/* app: styles/mobile.css */
/* ========================================
   RESPONSIVE DESIGN — دعم الموبايل
   Mobile breakpoints: 1024 → 768 → 480 → 360
   Desktop is 100% untouched — all rules here
   are inside media queries only.
======================================== */

/* Phones keep today's sizes: undo the desktop scale and its type floor. */
@media (max-width: 768px) {
  :root {
    --ui-scale: 1;
    --ui-text-min: 0px;
  }
}

/* ======================================
   iOS SAFARI ZOOM PREVENTION
   Safari force-zooms the whole page when
   a focused text input's font-size is
   under 16px. Android Chrome has no such
   behavior, so this was invisible during
   development/testing on Android. Scoped
   !important is deliberate here: this must
   win over every per-component font-size
   override (there are many across
   client.css/table.css) without having to
   chase each one individually.
====================================== */

@media (max-width: 768px) {
  input,
  select,
  textarea,
  .input,
  .custom-select {
    font-size: 16px !important;
  }
}

/* ======================================
   1024px — TABLET / SMALL LAPTOP
====================================== */

@media (max-width: 1024px) {
  .page-container {
    padding: calc(12px * var(--ui-scale)) calc(16px * var(--ui-scale)) calc(40px * var(--ui-scale));
    padding-left: calc(max(16px, var(--safe-left)) * var(--ui-scale));
    padding-right: calc(max(16px, var(--safe-right)) * var(--ui-scale));
    gap: calc(14px * var(--ui-scale));
  }

  .dashboard-grid {
    grid-template-columns: repeat(auto-fit, minmax(calc(140px * var(--ui-scale)), 1fr));
    gap: calc(10px * var(--ui-scale));
  }

  .dashboard-insights-grid {
    grid-template-columns: repeat(auto-fit, minmax(calc(130px * var(--ui-scale)), 1fr));
  }

  .client-page-top-header-layout {
    grid-template-columns: auto 1fr auto;
    gap: calc(8px * var(--ui-scale));
  }

  .modal-content {
    max-width: 90vw;
  }
}

/* ======================================
   768px — TABLET
====================================== */

@media (max-width: 768px) {
  /* ── Clock ── */

  .digital-clock {
    top: calc(6px + var(--safe-top));
    left: calc(6px + var(--safe-left));
    font-size: var(--font-xs);
    min-width: 75px;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
  }

  /* ── Page ── */

  .page-container {
    padding: 10px 12px 36px;
    padding-left: max(12px, var(--safe-left));
    padding-right: max(12px, var(--safe-right));
    gap: 10px;
  }

  .page-header-title h1 {
    font-size: var(--font-md);
  }

  /* ── Cards ── */

  .main-card {
    padding: 10px;
    border-radius: var(--radius-md);
  }

  .dashboard-card {
    padding: 8px;
    border-radius: var(--radius-md);
  }

  .dashboard-icon {
    width: 36px;
    height: 36px;
    min-width: 36px;
  }

  .dashboard-value {
    font-size: var(--font-base);
  }

  /* ── Dashboard grids ── */

  .dashboard-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  .dashboard-insights-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
  }

  /* ── The five summary cards, compact (ticket uifix, item 4) ──
       Two per row (the grid above), the number BESIDE the label instead of
       under it, less padding. The label and the number stay at --font-sm or
       above, the icon stays (only smaller), and every card keeps a 44px
       touch target. Scoped to the operations grid, so the Finance subtab's
       own insight cards are untouched. */
  .dashboard-insights-grid--summary .dashboard-insight-card {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
    min-height: 44px;
    padding: 4px 8px;
    text-align: start;
  }

  .dashboard-insights-grid--summary .dashboard-insight-card svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
  }

  .dashboard-insights-grid--summary .dashboard-insight-number {
    margin-top: 0;
    font-size: var(--font-lg);
  }

  .dashboard-insights-grid--summary .dashboard-insight-label {
    min-width: 0;
    font-size: var(--font-sm);
  }

  /* The sub-tab row and the dialogs' clickable items keep a 44px target
       (ticket 98-2a). */
  .dashboard-subtabs button {
    min-width: 44px;
  }

  .dashboard-dialog-item--open {
    min-height: 44px;
  }

  .dashboard-report-header {
    flex-direction: column;
    align-items: flex-start;
  }

  /* The report's own send control reaches a 44px target on a phone
       (ticket 98-2b). */
  .dashboard-report-header-actions .ui-btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Finance view's period buttons keep a 44px target on a phone, and
       its four money cards take two per row (ticket 98-2c). */
  .finance-period-seg .ui-btn {
    min-width: 44px;
  }

  .finance-kpis {
    grid-template-columns: 1fr 1fr;
  }

  /* ── Operations Center — the card stays one column, every control
       reaches a 44px target and nothing widens the page at 360px. ── */

  .operations-center-op {
    padding: var(--space-sm);
  }

  .operations-center-op-actions .ui-btn,
  .operations-center-missing-save,
  .operations-center-ignore,
  .operations-center-link,
  .operations-center-collapse {
    min-width: 44px;
    min-height: 44px;
  }

  .operations-center-op-actions .ui-btn {
    flex: 1 1 auto;
  }

  .operations-center-group-head {
    flex-wrap: wrap;
  }

  .operations-center-undo button {
    min-width: 44px;
    min-height: 44px;
  }

  /* ── Search — same row ── */

  .search-wrapper {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
  }

  .search-wrapper .ui-field-input {
    flex: 1;
    min-width: 0;
  }

  .search-wrapper .btn {
    flex-shrink: 0;
  }

  /* ── Buttons ── */

  .btn {
    min-height: 36px;
    padding: 6px 12px;
    font-size: var(--font-xs);
    min-width: 60px;
  }

  /* ── Inputs ── */

  .input {
    height: 38px;
    font-size: 16px;
  }

  .custom-select {
    height: 38px;
    font-size: 16px;
  }

  /* ── Tables ── */

  table {
    min-width: 600px;
  }

  thead th {
    padding: 8px 5px;
    font-size: var(--font-xs);
  }

  tbody td {
    padding: 6px 5px;
    font-size: var(--font-xs);
  }

  /* ── AdminTab table: the الإجراء column slightly narrower,
          the الجلسة القادمة column slightly wider ──
       The screen now renders through UiTableShell (ticket 96b), so the old
       `.admin-tab .table-wrapper th:nth-child(5)` selectors die with the
       wrapper. They are re-aimed at the columns' own classes (from
       ADMIN_COLUMNS), header and cell both. The element+class selector
       (0,2,1) ties with admin.css's own `.admin-tab th:nth-child(5)` desktop
       width rule and wins by source order (mobile.css is imported last). */

  .admin-tab th.admin-procedure-column,
  .admin-tab td.admin-procedure-column {
    width: 11%;
  }

  .admin-tab th.admin-session-column,
  .admin-tab td.admin-session-column {
    width: 14%;
    white-space: nowrap;
  }

  /* ── Archive table: client name right-aligned ──
       The shell now puts the column's own class (archive-name-column, from
       ARCHIVE_COLUMNS) on that column's <th> and <td>, so this is the old
       `.archive-tab .table-wrapper th:nth-child(2)` treatment re-aimed
       (ticket 96a round 2). Header and cell both, exactly as before. */

  .archive-tab .archive-name-column {
    text-align: right;
  }

  .archive-tab td.archive-name-column {
    text-align: justify;
    text-align-last: right;
  }

  /* ── ClientSessionTab: col widths adjusted ──
       #2=تاريخ الجلسة  #4=القرار  #5=الجلسة التالية. Request: reduce #4,
       give to #2. Ticket 96c re-aimed these from `th/td:nth-child(n)` to each
       column's own class (from CLIENT_SESSION_COLUMNS), header and cell both.
       Ticket 95c: the actions column no longer carries a percentage — its
       width comes from its content with the 96px floor on
       `.client-sessions-actions` (styles/table.css) — and the table keeps the
       prototype's own width so it scrolls sideways inside its frame. */

  .client-sessions-table th.client-session-date-column,
  .client-sessions-table td.client-session-date-column {
    width: 13%; /* was 10% */
  }

  .client-sessions-table th.client-session-decision-column,
  .client-sessions-table td.client-session-decision-column {
    width: 21%; /* was 25% */
  }

  .client-sessions-table th.client-session-next-column,
  .client-sessions-table td.client-session-next-column {
    width: 13%; /* was 10% */
  }

  /* The prototype's own table width on a phone — every column keeps the
       room it was designed with, and the table scrolls sideways inside its
       own frame, never the page (ticket 95c). */
  .client-sessions-table table {
    min-width: 660px;
  }

  /* The prototype's one line saying the table scrolls sideways; hidden
       above 768px (styles/client.css) and shown on a phone only (ticket
       95c). */
  .client-sessions-scroll-hint {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--font-xs);
    font-weight: 700;
    color: var(--text-muted);
  }

  /* The expert table's actions column keeps the same fixed length on a
       phone as on a desktop (ticket 95c round 2): the 96px floor of
       `.client-sessions-actions` plus the cell's 8px + 8px padding. The
       table's fixed layout does not grow the column, so without this the
       buttons would overflow it at 768px and below. */
  .expert-sessions-table th.ui-table-actions,
  .expert-sessions-table td.ui-table-actions {
    width: 112px;
  }

  /* The Client Profile's «الملاحظات» and «الملفات» item actions (ticket
       98-1a): every action reaches a 44px touch target on a phone. The extra
       class outranks the plain `.btn` steps at 480 and 360 (mobile.css), so
       the 44px floor holds there too. */
  .client-notes-item-actions .btn,
  .client-files-item-actions .btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Client Profile's «السكرتير والخصوم» tab (ticket 98-1b): every
       control in the tab — the add / edit controls in each list's title line,
       the empty state's own add control and each item's delete control —
       reaches a 44px touch target on a phone. The tab's own class outranks
       the plain `.btn` steps at 480 and 360 (mobile.css), so the 44px floor
       holds there too. */
  .client-secretaries-opponents-layout .btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Client Profile's «الأرشيف» tab (ticket 98-1c): the archive number
       field and the group's two actions reach a 44px touch target on a phone.
       The tab's own classes outrank the plain `.input` / `.btn` steps at 480
       and 360 (mobile.css), so the 44px floor holds there too. */
  .client-archive-main-content .input,
  .client-archive-actions .btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Client Profile's «سجل التعديلات» tab (ticket 98-1c): the error
       state's retry control reaches a 44px touch target on a phone. */
  .client-changelog .ui-btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The pending notice's open control reaches a 44px touch target on a
       phone, like every other screen's controls. */
  .pending-notice .ui-btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* The Settings screen's five moved sections (ticket 98-3a): every control
       in a section reaches a 44px touch target on a phone. The section's own
       classes outrank the plain `.btn` steps at 480 and 360 (mobile.css), so
       the 44px floor holds there too. */
  .settings-section .ui-btn,
    .settings-section-actions .ui-btn,
    .settings-broadcast-option,
    /* The unresolved-rows panel and the devices list sit outside a section
       card (ticket 98-3b), so they join this rule; so do the part-c screens'
       controls that sit outside a card — the contacts list rows, the password
       dialog and the pending-completion list (ticket 98-3c). */
    .settings-devices .ui-btn,
    .settings-unresolved .ui-btn,
    .settings-contacts .ui-btn,
    .settings-password .ui-btn,
    .settings-pending .ui-btn,
    /* The Users panel and its delete dialog (ticket 98-3d) join the same
       floor, and so do the Legal Library's manage, import and old-copy
       sections (ticket 98-4b), which all render inside .legal-manage. */
    .users-panel .ui-btn,
    .users-delete .ui-btn,
    .legal-manage .ui-btn,
    /* The Global Search dialog, the Change Log panel and the pending items
       list (ticket 98-7b) join the same floor: each control in them reaches
       the prototype's 44px touch target on a phone — the row actions, the
       list's close control and the error state's retry. */
    .pending-items-list .ui-btn,
    .pending-items-actions .ui-btn,
    .pending-items-state .ui-btn,
    .change-log-panel .ui-btn {
    min-width: 44px;
    min-height: 44px;
  }

  /* A Global Search result row a User can open is its own touch target, and
       a long name wraps inside the row instead of widening the dialog. */
  .global-item {
    min-height: 44px;
    overflow-wrap: anywhere;
  }

  /* The unresolved row's amount field keeps the kit's own 44px phone floor
       (.ui-field-input at 768px in ui.css) — no second rule here. */

  /* The section's switch keeps its 24px track but its hit area reaches the
       44px touch target; the track is re-centred inside it. */
  .settings-section .switch {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }

  .settings-section .slider {
    top: 10px;
    bottom: 10px;
  }

  /* ── Modals ── */

  .modal-overlay {
    /* A top-aligned modal draws from the top of the screen, so its first
           row must clear the status bar / Dynamic Island (ticket uifix,
           item 1). 0px on a device without a safe area. */
    padding-top: max(12px, calc(var(--safe-top) + 12px));
    padding-bottom: 12px;
    align-items: flex-start;
  }

  .modal-content {
    max-width: 95vw;
    max-height: 90vh;
    max-height: 90dvh;
    border-radius: var(--radius-lg);
  }

  .modal-header {
    padding: 10px 14px;
  }

  .modal-title {
    font-size: var(--font-base);
  }

  /* Compact modal body: less padding, tighter label/input gaps */
  .modal-body {
    padding: 6px 10px;
    gap: 0;
  }

  .modal-body .input-label {
    margin-top: 6px;
    margin-bottom: 2px;
  }

  .modal-body .action-group {
    margin-top: 10px;
  }

  /* The frame's actions row and every control in it reach a 44px target on
       a phone; the icon-only calculator control grows on both axes. */
  .modal-foot {
    padding: 10px var(--space-lg);
  }

  .modal-foot .ui-btn,
  .modal-form .ui-btn {
    min-height: 44px;
  }

  .modal-form .ui-btn--icon {
    min-width: 44px;
    min-height: 44px;
  }

  /* ── Client page — top header single row ── */

  .client-page-top-header-layout {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 8px;
  }

  .client-page-top-header-layout > *:first-child {
    justify-self: start;
  }

  .client-page-top-header-layout > *:last-child {
    justify-self: end;
  }

  /* ClientPage tabs — 3 per row ── */

  .client-tabs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
  }

  .client-tabs button {
    justify-content: center;
    text-align: center;
    padding: 6px 4px;
    font-size: var(--font-xs);
    min-height: 44px;
  }

  /* Client page frame + data tab (ticket 95): the back control and the
       edit controls grow to a 44px target, and the dossier stacks to one
       column. */
  .client-page-frame .ui-btn {
    min-height: 44px;
  }

  .client-data-dossier {
    grid-template-columns: 1fr;
  }

  /* Client Profile «البيانات» (ticket 95b): the tiles drop to two across
       (the groups already stack to one column through .client-data-dossier
       above) and every tile / band control reaches a 44px touch target. */
  .client-data-tiles.is-3,
  .client-data-tiles.is-4 {
    grid-template-columns: 1fr 1fr;
  }

  .client-data-tile-input,
  .client-data-case-input,
  .client-data-loc-input,
  .client-data-contact-input,
  .client-header-name-input {
    min-height: 44px;
  }

  .client-header-band .ui-btn,
  .client-data-contact-actions .btn {
    min-height: 44px;
  }

  /* The archived client's own lock toggle (ticket 98-1d) is a plain .btn,
       not the kit's .ui-btn, so it needs its own 44px phone target — the
       compound selector also outranks the ≤360px .btn rule. */
  .client-header-band .archive-client-lock-toggle {
    min-width: 44px;
    min-height: 44px;
  }

  .client-header-row {
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--space-md);
  }

  /* The band's actions take their own full line under the back button and
       the name, so a long action stops squeezing the name (ticket 310). */
  .client-header-band .client-header-actions {
    flex: 1 1 100%;
    order: 3;
  }

  .client-header-name {
    font-size: var(--font-lg);
  }

  .client-header-back-label {
    display: none;
  }

  /* ── Login ── */

  .login-page {
    padding: 10px;
    align-items: center;
    overflow: hidden;
  }

  .login-card {
    padding: 18px 16px;
    max-width: 100%;
  }

  .login-logo {
    width: 48px;
    height: 48px;
    font-size: 24px;
    margin-bottom: 6px;
  }

  .login-title {
    font-size: var(--font-lg);
  }

  .login-subtitle {
    font-size: var(--font-xs);
    margin-bottom: 12px;
  }

  .login-form {
    gap: 10px;
  }

  /* Every control on the auth screens is a 44px touch target: the buttons,
       the fields and the shared-device row (the label wraps the box, so the
       row itself is the target). Scoped to .auth-page, which every screen in
       the shared auth card carries — sign-in, the code screen, the message
       states and the accept-invitation page. */
  .auth-page .ui-btn,
  .auth-page .ui-field-input,
  .auth-page .auth-shared-device {
    min-height: 44px;
  }

  /* ── Dropdowns ── */

  .filter-list {
    max-height: 200px;
  }

  .admin-client-suggestions {
    max-height: 160px;
  }

  /* ── Legal Library ── */

  /* The prototype's phone rule: every control of this screen is a 44px
       touch target, and the search wraps instead of scrolling sideways. */
  .legal-library-row,
  .legal-library-search .ui-btn,
  .legal-library-section-tools .ui-btn,
  .legal-library .ui-state-actions .ui-btn {
    min-height: 44px;
  }

  .legal-library-search {
    flex-wrap: wrap;
  }
}

/* ======================================
   480px — MOBILE
====================================== */

@media (max-width: 480px) {
  /* ── Clock ── */

  .digital-clock {
    top: calc(4px + var(--safe-top));
    left: calc(4px + var(--safe-left));
    min-width: 58px;
    padding: 3px 5px;
    border-radius: var(--radius-sm);
  }

  .digital-clock-time {
    font-size: 9px;
  }

  .digital-clock-date {
    font-size: 7px;
  }

  /* ── Page container ── */

  .page-container {
    padding: 8px 10px 32px;
    padding-left: max(10px, var(--safe-left));
    padding-right: max(10px, var(--safe-right));
    gap: 8px;
  }

  /* ── Cards ── */

  .main-card {
    padding: 8px;
    border-radius: var(--radius-md);
  }

  /* ── Dashboard ── */

  .dashboard-grid {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }

  .dashboard-insights-grid {
    grid-template-columns: 1fr 1fr;
    gap: 6px;
  }

  .dashboard-card {
    padding: 8px 6px;
    gap: 6px;
    border-radius: var(--radius-md);
  }

  .dashboard-icon {
    width: 32px;
    height: 32px;
    min-width: 32px;
    border-radius: var(--radius-sm);
  }

  .dashboard-value {
    font-size: var(--font-base);
  }

  .dashboard-label {
    font-size: var(--font-xs);
  }

  .dashboard-subtabs button {
    padding: 0 9px;
  }

  /* ── Buttons ── */

  .btn {
    min-height: 36px;
    padding: 7px 12px;
    font-size: var(--font-xs);
    border-radius: var(--radius-sm);
    min-width: 56px;
  }

  /* ── Inputs & selects ── */

  .input {
    height: 40px;
    font-size: 16px;
    border-radius: var(--radius-sm);
    padding: 0 12px;
  }

  .custom-select {
    height: 40px;
    font-size: 16px;
    padding: 0 12px;
  }

  .input-label {
    font-size: var(--font-xs);
    margin-bottom: 4px;
  }

  /* ── Tables — horizontal scroll ── */

  table {
    min-width: 480px;
  }

  tbody td {
    font-size: var(--font-xs);
    padding: 5px 4px;
  }

  thead th {
    font-size: var(--font-xs);
    padding: 7px 4px;
  }

  /* Condensed action buttons inside tables */
  .session-actions-column .btn,
  .client-sessions-table .action-group .btn,
  .muhadreen-tab .action-group .btn {
    font-size: var(--font-xs);
    padding: 3px 4px;
  }

  /* ── Modals — sheet style from bottom ── */

  .modal-overlay {
    padding: 0;
    align-items: flex-end;
    overflow: hidden;
  }

  .modal-content {
    width: 100%;
    max-width: 100%;
    max-height: 92vh;
    max-height: 92dvh;
    /* The sheet is anchored to the bottom, so its height is what decides
           where its top edge sits: shortening it by the safe-area inset keeps
           a full-height sheet clear of the status bar / Dynamic Island
           (ticket uifix, item 1). 0px on a device without a safe area. */
    max-height: calc(92dvh - var(--safe-top));
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    padding-bottom: var(--safe-bottom);
    position: relative;
  }

  .modal-header {
    padding: 10px 14px 8px;
    position: sticky;
    top: 0;
    z-index: 2;
    background: linear-gradient(180deg, var(--modal-header-from), var(--modal-header-to));
  }

  .modal-title {
    font-size: var(--font-sm);
  }

  .modal-body {
    padding: 4px 10px 8px;
    -webkit-overflow-scrolling: touch;
  }

  .modal-body .input-label {
    margin-top: 6px;
    margin-bottom: 2px;
  }

  .modal-body .action-group {
    margin-top: 8px;
  }

  /* ── Page header ── */

  .page-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }

  .page-header-actions {
    width: 100%;
    justify-content: flex-end;
  }

  .page-header-title h1 {
    font-size: var(--font-base);
  }

  /* ── Search — same row ── */

  .search-wrapper {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 6px;
    flex-wrap: nowrap;
  }

  .search-wrapper .ui-field-input {
    flex: 1;
    min-width: 0;
    width: auto;
  }

  .search-wrapper .btn {
    flex-shrink: 0;
    width: auto;
    min-height: 40px;
  }

  /* ── Badge ── */

  .badge {
    font-size: var(--font-xs);
    padding: 2px 6px;
  }

  /* ── Client page ── */

  .client-page-top-header-layout {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: 6px;
  }

  .client-page-top-header-layout > *:first-child {
    justify-self: start;
  }

  .client-page-top-header-layout > *:last-child {
    justify-self: end;
  }

  .client-page-info-value {
    min-height: 32px;
    padding: 4px 6px;
    font-size: var(--font-xs);
  }

  /* ClientPage tabs — 3 per row */
  .client-tabs {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
  }

  .client-tabs button {
    justify-content: center;
    text-align: center;
    padding: 6px 4px;
    font-size: var(--font-xs);
    min-height: 44px;
  }

  /* ── Login ── */

  .login-page {
    padding: 8px;
    padding-top: max(8px, var(--safe-top));
    padding-bottom: max(8px, var(--safe-bottom));
    align-items: center;
    overflow: hidden;
    height: 100vh;
    height: 100dvh;
    min-height: unset;
  }

  .login-card {
    padding: 20px 16px;
    border-radius: var(--radius-xl);
    max-height: 95vh;
    overflow-y: auto;
  }

  .login-logo {
    width: 44px;
    height: 44px;
    font-size: 22px;
  }

  .login-title {
    font-size: var(--font-base);
  }

  .login-subtitle {
    font-size: var(--font-xs);
    margin-bottom: 8px;
  }

  /* ── Archived stamp ── */

  /* In the header's empty top-left corner, clear of the actions row that
       now takes its own line (ticket 310). */
  .archived-stamp {
    width: 56px;
    height: 56px;
    font-size: 11px;
    top: calc(var(--safe-top) + 8px);
    left: 8px;
    border-width: 3px;
  }

  /* ── Admin client suggestions ── */

  .admin-client-suggestions {
    max-height: 140px;
  }

  /* ── Confirm modal text ── */

  .confirm-text {
    font-size: var(--font-base);
    line-height: 1.7;
  }
}

/* ======================================
   360px — SMALL MOBILE
====================================== */

@media (max-width: 360px) {
  .dashboard-grid {
    grid-template-columns: 1fr;
    gap: 8px;
  }

  .dashboard-insights-grid {
    grid-template-columns: 1fr;
  }

  /* The five summary cards keep two per row at the narrowest step too, so
       they still take about a third of a phone screen (ticket uifix, item 4).
       Placed after the one-column rule above, which it ties on specificity
       with, so it wins by source order. */
  .dashboard-insights-grid--summary {
    grid-template-columns: 1fr 1fr;
  }

  .btn {
    padding: 6px 8px;
    min-width: 48px;
    font-size: var(--font-xs);
    min-height: 34px;
  }

  .input,
  .custom-select {
    height: 38px;
    font-size: 16px;
  }

  .client-tabs {
    grid-template-columns: repeat(3, 1fr);
  }

  .page-container {
    padding: 6px 8px 28px;
    padding-left: max(8px, var(--safe-left));
    padding-right: max(8px, var(--safe-right));
    gap: 6px;
  }

  .main-card {
    padding: 6px;
  }
}

/* ========================================
   MOBILE TABLE READABILITY & ACTION REACHABILITY
   (report 07 §5.3)

   Ticket 96c: the last table screens moved onto UiTableShell, so no screen
   uses the old `.table-wrapper` table any more. This block — which pinned
   `.table-wrapper`'s last cell and raised its body text on a phone — is now
   dead and removed. The shell's own phone rules in styles/ui.css do the same
   job for every table: `.ui-table-shell .ui-table-actions` pins the actions
   column, and `readableOnPhone` / `compact` set the body text.
======================================== */

/* ========================================
   THE ASSISTANT — 44px TARGETS ON A PHONE (ticket 98-5a)

   Every control the assistant renders is a kit button now, so one scoped rule
   grows them all to the prototype's 44px touch target: the header icons, the
   starters, the copy/send/jump controls and the confirm card's two buttons.
   The composer's field keeps the same 44px floor. Scoped to the panel, so no
   other screen is touched. The floating button stays its own 56px.
======================================== */

@media (max-width: 768px) {
  .agent-panel .ui-btn {
    min-width: 44px;
    min-height: 44px;
  }

  .agent-panel .agent-composer-input {
    min-height: 44px;
  }
}

// created by oran
/* The line above is the project's file marker. CSS has no `//` comments, so
   the empty block below absorbs it: the browser drops that one invalid rule
   and parses everything after it normally. */ {
}

/* ========================================
   SIMULATION-ONLY CSS (unit 1)

   Three things live here and nothing else:
     1. #sim-bar — the grey simulation bar. Deliberately outside the app's
        design language so it can never be mistaken for part of the office
        app (SIM_SPEC 9).
     2. .sim-note — the pre-written assistant answer of the simulation
        (SIM_SPEC 7), visibly different from a real assistant message.
     3. html.sim-record — the clean recording mode (SIM_SPEC 2): no bar, no
        demo line, no scrollbars.

   No app class is restyled here. The app's own stylesheets (inlined by the
   build script, in the order of styles/styles.css) still own every screen.
======================================== */

/* The bar is fixed above the page. The app's own safe-area token is raised by
   the bar's height, which is the token the header band, the clock, the toast
   and the app's sign-out already read — so nothing is covered and no app rule
   is touched. */
html:not(.sim-record) {
  --safe-top: 36px;
}

html.sim-record {
  --safe-top: 0px;
}

/* ========================================
   THE SIMULATION BAR
======================================== */

#sim-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5000;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 36px;
  padding: 0 12px;
  overflow-x: auto;
  overflow-y: hidden;
  background: #e7e8ec;
  border-bottom: 1px solid #c6c9d1;
  color: #3c4250;
  font-family:
    system-ui,
    -apple-system,
    'Segoe UI',
    Tahoma,
    Arial,
    sans-serif;
  font-size: 12px;
  line-height: 1;
  direction: rtl;
  scrollbar-width: none;
}

#sim-bar::-webkit-scrollbar {
  display: none;
}

#sim-bar .sim-select {
  height: 24px;
  max-width: 210px;
  padding: 0 6px;
  border: 1px solid #b6bac4;
  border-radius: 6px;
  background: #ffffff;
  color: #2f3542;
  font: inherit;
  cursor: pointer;
}

#sim-bar .sim-btn {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  height: 24px;
  padding: 0 10px;
  border: 1px solid #b6bac4;
  border-radius: 6px;
  background: #f7f8fa;
  color: #2f3542;
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s ease;
}

#sim-bar .sim-btn:hover {
  background: #ffffff;
}

#sim-bar .sim-btn:active {
  background: #dfe1e7;
}

#sim-bar .sim-journey {
  min-width: 24px;
  justify-content: center;
}

#sim-bar .sim-sep {
  flex: 0 0 auto;
  width: 1px;
  height: 18px;
  background: #c6c9d1;
}

#sim-bar .sim-demo-line {
  margin-inline-start: auto;
  padding-inline-start: 10px;
  color: #6b7280;
  white-space: nowrap;
}

/* ========================================
   THE SIMULATION'S ASSISTANT NOTE (SIM_SPEC 7)
   A pre-written reply, not the assistant's own: dashed edge, hatched wash and
   an information icon, so it never reads as a real answer.
======================================== */

.sim-note {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border: 1px dashed var(--border);
  border-radius: var(--radius-md);
  background-image: repeating-linear-gradient(135deg, var(--gold-a08) 0 6px, transparent 6px 12px);
  color: var(--text-muted);
  font-size: var(--font-sm);
  line-height: 1.7;
  text-align: start;
}

.sim-note svg {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--gold);
}

/* ========================================
   RECORDING MODE (?record=1)
======================================== */

html.sim-record #sim-bar {
  display: none;
}

html.sim-record,
html.sim-record body {
  scrollbar-width: none;
}

html.sim-record ::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

/* ========================================
   NARROW SCREENS
   The bar stays one 36px line: the journey buttons lose their «رحلة» prefix
   and the demo line gives way.
======================================== */

@media (max-width: 560px) {
  #sim-bar {
    gap: 6px;
    padding: 0 8px;
    font-size: 11px;
  }

  #sim-bar .sim-btn {
    padding: 0 7px;
  }

  #sim-bar .sim-select {
    max-width: 138px;
  }

  #sim-bar .sim-j-label {
    display: none;
  }

  #sim-bar .sim-demo-line {
    display: none;
  }
}

/* The simulation's own note in the toast slot: a runtime style element would be blocked by style-src 'self'. */
.sim-toast-note {
  align-items: flex-start;
  background: var(--card);
  background-image: repeating-linear-gradient(135deg, var(--gold-a08) 0 6px, transparent 6px 12px);
  color: var(--text);
  border: 1px dashed var(--gold);
  font-weight: 600;
  line-height: 1.7;
  text-align: start;
}

.sim-toast-note svg {
  flex-shrink: 0;
  margin-top: 2px;
  color: var(--gold);
}
