/* Design language for زوویار — a Persian buy-now-pay-later / micro-credit
   platform, run through neighbourhood shops (نمایندگی) but managed from a
   proper back-office. The look is deliberately "enterprise admin console":
   a fixed petroleum-blue sidebar (--brand, #0F3B4D — deep, confident, the
   color of a ledger binding) carries navigation, a cool light-gray content
   canvas holds the work, and a single warm egg-yolk yellow (--accent,
   #F2A900) is spent ONLY on the things that need attention — the active nav
   item, primary actions, key numbers. White cards with crisp 1px borders
   read as "real back-office software", not a consumer app. Font stays
   Vazirmatn (full Persian coverage) with a wide weight range for hierarchy. */
:root{
  /* This whole UI is a fixed light theme (see the palette below) — it never
     follows the OS/browser dark-mode preference. Without declaring that
     explicitly, some browsers (Firefox especially, on a dark-mode OS) still
     render *native* popups — a <select>'s dropdown list chief among them —
     using dark system widget colors while our own CSS gives the <option>
     text a light-theme color, so the two collide and the text disappears.
     Chrome happens to reconcile that combination fine on its own, which is
     why the earlier fix looked complete after only testing there; Firefox's
     native dropdown popup needs this explicit signal to match. */
  color-scheme: light;
  /* --- v2 palette ---------------------------------------------------
     The blue moved down and in: from a mid petroleum (#0F3B4D) to a near-
     black teal, so the sidebar reads as one confident slab instead of a
     large mid-tone block competing with the content beside it. Dropping
     the sidebar's value also frees the yolk yellow to be used at full
     strength — before, a bright accent on a mid-blue was close enough in
     weight that the accent stopped meaning "look here". Everything else
     (states, canvas) is retuned to sit against that darker anchor. */
  --ink:#0A1C26;
  --ink-2:#4E6675;
  --paper:#EDF1F4;
  --paper-2:#FFFFFF;
  --line:#D7E0E6;
  --line-2:#C3D0D8;       /* the heavier rule — table underlines, dividers that carry weight */
  --brand:#062A3A;        /* primary — near-black teal, the sidebar slab */
  --brand-d:#031A25;
  --brand-2:#0E4459;      /* raised surfaces on the dark sidebar */
  --brand-bg:#E4EBEF;
  --gold:#062A3A;         /* legacy variable name a few inline styles still reference */
  --gold-d:#031A25;
  --accent:#C07F00;       /* deepened yolk — only where yellow has to be readable AS TEXT */
  --accent-bright:#FFB400;/* full-strength yolk — active nav, key figures, the logo */
  --accent-bg:#FFF4DB;
  --teal:#127A4E;
  --teal-bg:#DFF2E8;
  --amber:#A96C00;
  --amber-bg:#FFF4DB;
  --coral:#B33127;
  --coral-bg:#FBE4E2;
  --muted:#7C919E;
  /* Radius scale, applied by role rather than per-rule taste: containers
     get the large one, controls the small one, status pills the full
     round. Previously .5/.55/.625/.75/1rem were mixed with no rule, which
     is why nothing looked deliberately grouped. */
  --r-lg:14px;            /* panels, cards, queue rows, modals */
  --r-md:10px;            /* tab bars, notes, inputs */
  --r-sm:8px;             /* buttons, small controls */
  /* Elevation is now reserved for things that genuinely float above the
     page (modals, the login card, dropdowns). Static cards use a border.
     Shadow under every surface flattens hierarchy instead of building it. */
  --shadow-sm:0 1px 2px rgba(6,42,58,.05);
  --shadow-md:0 4px 14px rgba(6,42,58,.09);
  --shadow-lg:0 22px 50px rgba(6,42,58,.20),0 6px 16px rgba(6,42,58,.09);
}
*{box-sizing:border-box;}
html,body{margin:0;font-family:'Vazirmatn','Tahoma',sans-serif;background:var(--paper);color:var(--ink);-webkit-font-smoothing:antialiased;}
/* --- Login / entrance ------------------------------------------------
   Three doors (customer, همکار, admin) share this one screen. It used to
   be a centred 480px column: header, tabs, then a .panel card that itself
   contained a .center-box card — a frame inside a frame, with the brand
   reduced to a 40px icon in the header.
   Now the page is split. The brand side is the whole reason the gradient
   exists: the mark at 96px, the name, and one line saying what this
   particular door is for — /agency and /yara were previously identical
   above the fold, which is a poor thing for a login screen to be. The
   form side carries a single card and nothing else.
   Below 860px the two stack and the brand block shrinks to a header, so
   the form is still the first thing a thumb reaches. */
body.landing-bg{background:linear-gradient(155deg,#0E4459 0%,#062A3A 52%,#02141C 100%);min-height:100vh;}
body.landing-bg .app{max-width:980px;padding-top:0;display:flex;align-items:center;min-height:100vh;}

.auth-shell{display:grid;grid-template-columns:1fr 420px;gap:56px;align-items:center;width:100%;}
.auth-brand{color:#fff;}
.auth-mark{margin-bottom:22px;}
.auth-brand h1{font-size:44px;font-weight:800;letter-spacing:-.035em;margin:0 0 10px;color:#fff;}
.auth-tagline{font-size:16px;font-weight:600;color:var(--accent-bright);margin:0 0 18px;}
.auth-lead{font-size:14px;line-height:2.1;color:rgba(255,255,255,.72);margin:0;max-width:46ch;}
.auth-main .tabs{margin-bottom:14px;}
.auth-main .center-box{margin:0;max-width:none;width:100%;padding:28px;}
.auth-main .center-box h2{font-size:20px;letter-spacing:-.02em;margin-bottom:20px;}
/* «مرا به خاطر بسپار» on the internal login — the switch sits on the reading
   edge with the consequence spelled out next to it, because the default
   (session ends with the browser) is the one that protects a shared machine and
   the person needs to know what turning it off buys them. */
.remember-row{display:flex;align-items:flex-start;gap:11px;margin:2px 0 16px;cursor:pointer;}
.remember-row .switch{margin-top:2px;}
.remember-label{display:block;font-size:13px;font-weight:600;color:var(--ink);}
.remember-hint{display:block;font-size:11.5px;line-height:1.75;color:var(--muted);margin-top:3px;}
/* The fixed "IR" beside the شبا field — printed rather than typed, so the 24
   digits the person enters are exactly the 24 the format calls for. */
.iban-prefix{
  flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  height:48px;padding:0 14px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--paper);color:var(--ink-2);font-weight:800;font-size:16px;direction:ltr;
}
.btn-block{width:100%;justify-content:center;padding:12px 18px;font-size:14px;}

@media (max-width:860px){
  body.landing-bg .app{padding:28px 18px 40px;align-items:flex-start;min-height:0;}
  .auth-shell{grid-template-columns:1fr;gap:24px;}
  .auth-brand{display:flex;align-items:center;gap:14px;flex-wrap:wrap;}
  .auth-mark{margin-bottom:0;}
  .auth-mark svg{width:52px;height:52px;}
  .auth-brand h1{font-size:26px;margin:0;}
  .auth-tagline{font-size:13px;margin:0;width:100%;}
  .auth-lead{font-size:13px;line-height:1.9;}
  .auth-main .center-box{padding:22px 18px;}
}
body.landing-bg .tabs{background:rgba(255,255,255,.10);border:1px solid rgba(255,255,255,.16);border-radius:var(--r-md);padding:4px;margin:0;width:100%;}
body.landing-bg .tabs .tab{color:rgba(255,255,255,.82);border-radius:var(--r-sm);flex:1;text-align:center;}
body.landing-bg .tabs .tab:not(.active):hover{background:rgba(255,255,255,.10);color:#fff;}
body.landing-bg .tabs .tab.active{background:var(--accent-bright);color:var(--brand-d);font-weight:800;}
/* Tabs nested inside the white login/register card (e.g. "ورود با نام کاربری" /
   "ورود با پیامک یا تماس تلفنی") sit on a light background, not the blue page
   gradient — the white text above was invisible there. This more specific
   selector overrides just that case, back to normal dark tab text; the
   role-selector tabs directly on the blue background (outside .center-box)
   keep their white styling untouched. */
body.landing-bg .center-box .tabs{background:var(--paper);border-color:var(--line);}
body.landing-bg .center-box .tabs .tab{color:var(--ink-2);}
body.landing-bg .center-box .tabs .tab.active{color:#fff;background:var(--brand);}
.app{max-width:1400px;margin:0 auto;padding:28px 20px 60px;transition:max-width .2s ease-in-out;}
.app.app-wide{max-width:1920px;}
.app.app-wide .panel{padding:28px 36px;}
/* Safety net for any table that still doesn't fit even at the wide page width
   above (e.g. تسهیلات اعطا شده when the "مدت اعتبار در دسترس" cell opens its
   inline day/month/year edit form) — the table scrolls horizontally within its
   own box instead of overflowing outside the panel or the page. */
.panel{overflow-x:auto;}
a{color:inherit;}
::selection{background:var(--accent-bright);color:var(--brand-d);}

/* ---------------------------------------------------------------------
   Sidebar shell — admin & agent panels only (customer keeps its mobile-
   first bottom-nav; landing keeps its centered login-card layout). A CSS
   Grid with named areas lets masthead()/dashboardHeader()/adminTabsBar()
   stay simple, independent functions — each just tags its own output with
   a grid-area, so no render call site anywhere had to change to get this
   layout; the grid is what actually does the "sidebar on the right,
   content on the left" rearranging, driven purely by these area names
   (in RTL, the logical first grid column renders on the right automatically).
   The whole shell is pinned to exactly one viewport height with its own
   overflow hidden, and only .panel scrolls internally — otherwise a long
   list (e.g. «تسهیلات اعطا شده») scrolled the *entire* page, sidebar and
   topbar included, making it easy to lose your place. */
#app.sidebar-shell{
  max-width:1600px;
  padding:0;
  display:grid;
  grid-template-columns:258px 1fr;
  grid-template-rows:auto 1fr;
  grid-template-areas:
    "brand  topbar"
    "nav    panel";
  align-items:start;
  height:100vh;
  overflow:hidden;
  transition:grid-template-columns .18s ease-in-out;
}
#app.sidebar-shell.app-wide{max-width:none;}
#app.sidebar-shell.sidebar-collapsed{grid-template-columns:0 1fr;}
#app.sidebar-shell.sidebar-collapsed .masthead,
#app.sidebar-shell.sidebar-collapsed .sidebar-nav{overflow:hidden;padding-left:0;padding-right:0;white-space:nowrap;}
#app.sidebar-shell .masthead{
  grid-area:brand;
  background:var(--brand);
  border-bottom:1px solid rgba(255,255,255,.08);
  padding:22px 22px 18px;
  margin-bottom:0;
  flex-direction:column;
  align-items:flex-start;
  gap:4px;
}
#app.sidebar-shell .masthead .brand{gap:10px;}
#app.sidebar-shell .masthead h1{color:#FFFFFF;font-size:19px;}
#app.sidebar-shell .masthead .sub{display:none;}
#app.sidebar-shell .sidebar-nav{
  grid-area:nav;
  background:linear-gradient(180deg,var(--brand) 0%,var(--brand-d) 100%);
  height:100%;
  padding:14px 12px 24px;
  overflow-y:auto;
}
#app.sidebar-shell .topbar{
  grid-area:topbar;
  background:var(--paper-2);
  border-bottom:1px solid var(--line);
  padding:14px 28px;
}
#app.sidebar-shell .panel{
  grid-area:panel;
  margin-top:0;
  border-radius:0;
  border:none;
  border-top:none;
  box-shadow:none;
  height:100%;
  overflow-y:auto;
  padding:26px 28px;
}
#app.sidebar-shell.app-wide .panel{padding:26px 32px;}
.sidebar-toggle-btn{
  display:flex;align-items:center;justify-content:center;
  width:32px;height:32px;border-radius:.5rem;cursor:pointer;flex:0 0 auto;
  color:var(--ink-2);
}
.sidebar-toggle-btn:hover{background:var(--brand-bg);color:var(--brand);}
.sidebar-toggle-btn svg{width:19px;height:19px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;}
/* --- Narrow screens: the sidebar becomes a drawer ---------------------
   The previous rule stacked the nav as a normal block between the topbar
   and the panel. On a phone that meant every single screen opened with a
   full column of menu items and you scrolled past all of them to reach
   the thing you came for — and the "collapse" button just hid the menu
   entirely with no way back that didn't look like a bug.
   Now the brand block and nav slide in over the content from the reading
   edge, the same toggle opens and closes them, and picking any item
   closes the drawer behind you. The panel keeps the full width at all
   times, so content is never pushed down by navigation. */
@media (max-width:900px){
  #app.sidebar-shell{
    height:100vh;overflow:hidden;
    grid-template-columns:1fr;
    grid-template-rows:auto 1fr;
    grid-template-areas:"topbar" "panel";
  }
  /* The desktop rule `#app.sidebar-shell.sidebar-collapsed{grid-template-columns:0 1fr}`
     carries one more class than the single-column rule above, so specificity
     let it win here even inside this media query — leaving a two-column grid
     under a one-column area map. Every panel ended up about 32px wide.
     Restated at matching specificity so the drawer layout actually holds. */
  #app.sidebar-shell.sidebar-collapsed{grid-template-columns:1fr;}
  #app.sidebar-shell .masthead,
  #app.sidebar-shell .sidebar-nav{
    position:fixed;top:0;right:0;width:270px;max-width:82vw;z-index:60;
    transform:translateX(100%);
    transition:transform .22s cubic-bezier(.4,0,.2,1);
  }
  #app.sidebar-shell .masthead{height:74px;}
  #app.sidebar-shell .sidebar-nav{top:74px;bottom:0;height:auto;overflow-y:auto;}
  /* Open state is the *absence* of .sidebar-collapsed, matching desktop,
     so the one toggle button drives both without a second flag. */
  #app.sidebar-shell:not(.sidebar-collapsed) .masthead,
  #app.sidebar-shell:not(.sidebar-collapsed) .sidebar-nav{transform:translateX(0);}
  #app.sidebar-shell.sidebar-collapsed .masthead,
  #app.sidebar-shell.sidebar-collapsed .sidebar-nav{
    display:block;overflow:hidden;padding-left:12px;padding-right:12px;
  }
  #app.sidebar-shell .topbar{grid-area:topbar;padding:12px 16px;}
  #app.sidebar-shell .panel{grid-area:panel;height:100%;overflow-y:auto;padding:18px 16px 40px;}
  .sidebar-scrim{display:block;}
  /* Tap targets: 44px is the smallest reliably hittable size with a thumb. */
  .sidebar-nav-item{padding:13px 15px;font-size:14px;}
  .btn{padding:10px 18px;}
  .btn.small{padding:8px 14px;font-size:12px;}
  .tab{padding:10px 16px;}
  .pager-btn{min-width:38px;height:38px;}
  .grid,.grid.g2,.grid.g3{grid-template-columns:1fr 1fr;gap:10px;}
  .card .value{font-size:21px;}
  .queue-item{flex-direction:column;align-items:stretch;}
  .queue-actions{justify-content:flex-start;flex-wrap:wrap;}
  .searchbox-row{flex-direction:column;}
  .searchbox-row .btn{width:100%;justify-content:center;}
}
@media (max-width:420px){
  .grid,.grid.g2,.grid.g3{grid-template-columns:1fr;}
}

/* The dimmed backdrop behind an open drawer. Lives on <body> rather than
   inside the grid so it can cover the whole viewport regardless of which
   panel is rendered, and it is created once at startup — nothing in the
   per-render markup has to know it exists. */
.sidebar-scrim{
  display:none;position:fixed;inset:0;z-index:55;
  background:rgba(3,26,37,.45);
  opacity:0;pointer-events:none;transition:opacity .22s ease-in-out;
}
body.drawer-open .sidebar-scrim{opacity:1;pointer-events:auto;}
@media (prefers-reduced-motion: reduce){
  #app.sidebar-shell .masthead,
  #app.sidebar-shell .sidebar-nav,
  .sidebar-scrim{transition:none;}
}

.sidebar-nav{display:flex;flex-direction:column;gap:2px;}
.sidebar-nav-item{
  position:relative;
  display:flex;align-items:center;gap:11px;
  padding:11px 15px;border-radius:var(--r-sm);
  font-family:inherit;font-size:13.5px;font-weight:600;
  background:transparent;border:none;color:rgba(255,255,255,.68);
  cursor:pointer;text-align:right;width:100%;
  transition:background .15s ease-in-out,color .15s ease-in-out;
}
.sidebar-nav-item:hover{background:rgba(255,255,255,.07);color:#FFFFFF;}
/* The active item is the single loudest thing in the chrome: full-strength
   yolk, plus a bar on the reading edge that ties it to the panel it opened.
   Against the darker slab this now carries across the whole screen. */
.sidebar-nav-item.active{background:var(--accent-bright);color:var(--brand-d);font-weight:800;}
.sidebar-nav-item.active::before{
  content:"";position:absolute;right:-12px;top:6px;bottom:6px;width:4px;
  border-radius:0 3px 3px 0;background:var(--accent-bright);
}
.sidebar-nav-item.active .sidebar-nav-icon svg{stroke:var(--brand-d);}
.sidebar-nav-icon{display:flex;flex:0 0 auto;}
.sidebar-nav-icon svg{width:17px;height:17px;stroke:rgba(255,255,255,.75);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:stroke .15s ease-in-out;}
.sidebar-nav-item:hover .sidebar-nav-icon svg{stroke:#FFFFFF;}

.topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;}
.topbar-title{font-size:16px;font-weight:800;margin:0;letter-spacing:-.01em;}

.masthead{display:flex;align-items:center;justify-content:space-between;padding-bottom:16px;margin-bottom:18px;border-bottom:1px solid var(--line);}
.masthead .brand{display:flex;align-items:center;gap:12px;}
.masthead h1{font-size:28px;font-weight:800;margin:0;letter-spacing:-.01em;}
.masthead .sub{font-size:13px;color:var(--muted);}

.tabs{display:flex;gap:3px;margin-top:0;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);padding:4px;width:fit-content;max-width:100%;overflow-x:auto;}
.tab{position:relative;padding:9px 18px;font-size:13px;font-weight:600;background:transparent;border:none;border-radius:var(--r-sm);color:var(--ink-2);cursor:pointer;transition:background .14s ease-in-out,color .14s ease-in-out;white-space:nowrap;}
.tab.active{color:#fff;background:var(--brand);font-weight:700;}
.tab:not(.active):hover{color:var(--ink);background:rgba(6,42,58,.06);}

/* Tabs on the reading edge, the section's own action pushed to the far side —
   on an RTL page that puts «+ تولید کیت» in the left corner, well away from the
   tabs so it never reads as one of them. Wraps rather than squeezing on narrow
   screens, where the button drops under the tab bar at full width. */
.tabs-row{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;}
@media (max-width:640px){
  .tabs-row > .btn-add{width:100%;justify-content:center;}
}

/* Yolk variant of the add mark. The teal default reads as «confirm»; on a
   screen whose whole purpose is creating records, the accent colour is the one
   that says «new». */
.btn.btn-add-accent{background:var(--accent);}
.btn.btn-add-accent:hover{background:var(--accent-bright);color:var(--brand);}
.btn.btn-add-accent .plus{background:#fff;color:var(--accent);}
.btn.btn-add-accent:hover .plus{background:var(--brand);color:var(--accent-bright);}
.btn.btn-add-accent:focus-visible{box-shadow:0 0 0 3px var(--accent-bg);}

.panel{background:var(--paper-2);border-radius:var(--r-lg);padding:28px;min-height:420px;margin-top:14px;box-shadow:none;border:1px solid var(--line);}

.role-line{font-size:12px;color:var(--muted);margin-bottom:20px;padding-bottom:14px;border-bottom:1px dashed var(--line);display:flex;justify-content:space-between;align-items:center;}
.role-line b{color:var(--ink);}

.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:14px;margin-bottom:22px;}
.grid.g3{grid-template-columns:repeat(auto-fit,minmax(170px,1fr));}
.grid.g2{grid-template-columns:repeat(auto-fit,minmax(200px,1fr));}

/* Stat cards carry the numbers this whole product exists to report, so the
   figure — not the frame — is what got the weight. The card itself lost its
   shadow and hover-lift (it isn't clickable; the lift promised an action
   that doesn't exist) and gained a yolk rule on the reading edge. */
.card{background:var(--paper-2);border:1px solid var(--line);border-right:3px solid var(--line-2);border-radius:var(--r-lg);padding:16px 18px;box-shadow:none;transition:border-right-color .15s ease-in-out;}
.card:hover{border-right-color:var(--accent-bright);}
.card .label{font-size:11.5px;color:var(--muted);margin-bottom:7px;font-weight:600;}
.card .value{font-size:26px;line-height:1.25;font-weight:800;color:var(--ink);letter-spacing:-.025em;font-variant-numeric:tabular-nums;}
.card .value.gold{color:var(--accent);}
.card .value.danger{color:var(--coral);}

h2.section{font-size:17px;font-weight:800;letter-spacing:-.02em;margin:30px 0 13px;padding-right:14px;border-right:4px solid var(--accent-bright);}
h2.section:first-of-type{margin-top:0;}
.section-sub{font-size:12px;color:var(--muted);margin-top:-8px;margin-bottom:14px;padding-right:16px;line-height:1.7;}

table{width:100%;border-collapse:collapse;font-size:13px;margin-bottom:8px;}
/* The header is now a rule rather than a grey block: a solid line under
   real-weight text separates head from body more cleanly than a filled
   band, and it survives the sticky positioning added below without the
   fill bleeding over scrolled rows. */
th{text-align:right;font-weight:800;color:var(--ink);font-size:11.5px;padding:11px 12px;border-bottom:2px solid var(--line-2);background:var(--paper-2);}
td{padding:12px;border-bottom:1px solid var(--line);}
tr:last-child td{border-bottom:none;}
tr:hover td{background:rgba(6,42,58,.04);}

/* A status pill now carries a dot in its own state color. Colour alone was
   the only signal before, which fails for anyone who can't separate the
   green and amber tints at this size — the dot gives the state a second,
   non-colour cue, and reads faster down a column either way. */
.badge{display:inline-flex;align-items:center;gap:6px;padding:4px 11px 4px 12px;border-radius:10rem;font-size:11.5px;font-weight:700;}
.badge::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:0 0 auto;}
.badge.ok{background:var(--teal-bg);color:var(--teal);}
.badge.pending{background:var(--amber-bg);color:var(--amber);}
.badge.late{background:var(--coral-bg);color:var(--coral);}

.btn{display:inline-flex;align-items:center;gap:7px;padding:9px 19px;border-radius:var(--r-sm);font-family:inherit;font-size:13px;font-weight:700;border:1px solid transparent;background:var(--brand);color:#fff;cursor:pointer;transition:background .14s ease-in-out,border-color .14s ease-in-out,color .14s ease-in-out;box-shadow:none;}
.btn:hover{background:var(--brand-2);}
.btn:active{transform:scale(.985);}
.btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--brand-bg);}
.btn.ghost{background:var(--paper-2);color:var(--brand);border-color:var(--line-2);}
.btn.ghost:hover{background:var(--brand-bg);border-color:var(--brand);color:var(--brand);}
.btn.small{padding:6px 13px;font-size:11.5px;}
.btn.reject{background:var(--paper-2);color:var(--coral);border-color:var(--coral);}
.btn.reject:hover{background:var(--coral-bg);}
.btn.approve{background:var(--teal);}
.btn.approve:hover{background:#0E6440;}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none;}

.queue-item{display:flex;justify-content:space-between;align-items:center;padding:15px 18px;border-radius:var(--r-lg);margin-bottom:10px;flex-wrap:wrap;gap:10px;background:var(--paper-2);border:1px solid var(--line);box-shadow:none;transition:border-color .14s ease-in-out;}
.queue-item:hover{border-color:var(--line-2);}
.queue-item .meta{font-size:12px;color:var(--muted);margin-top:3px;}
.queue-actions{display:flex;gap:8px;}

.note{margin-top:18px;padding:14px 17px;background:var(--brand-bg);border-right:4px solid var(--brand);border-radius:var(--r-md);font-size:12.5px;color:var(--ink-2);line-height:1.8;}
.note.warn{background:var(--amber-bg);border-right-color:var(--amber);}
.inline-icon{display:inline-flex;flex:0 0 auto;vertical-align:-3px;}
.inline-icon svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
.error{margin-top:10px;padding:12px 15px;background:var(--coral-bg);color:var(--coral);border-right:3px solid var(--coral);border-radius:var(--r-sm);font-size:12.5px;font-weight:600;}
.success{margin-top:10px;padding:12px 15px;background:var(--teal-bg);color:var(--teal);border-right:3px solid var(--teal);border-radius:var(--r-sm);font-size:12.5px;font-weight:600;}

.form-row{margin-bottom:13px;}
.form-row label{display:block;font-size:12px;color:var(--ink-2);margin-bottom:6px;font-weight:600;}
input[type=text],input[type=password],input[type=number],input[type=tel],input[type=date],input[type=file],select,textarea{
  width:100%;padding:10px 12px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  font-family:inherit;font-size:13px;color:var(--ink);background:var(--paper-2);
  transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-bg);}
/* Styled dropdowns (see enhanceSelects() in app.js for why).
   ------------------------------------------------------------------
   The real <select> stays in the DOM as the form's actual field — it is only
   moved out of sight, never removed, so FormData, validation and every change
   handler keep working. If the script fails to run for any reason, removing
   .select-shell's styling leaves a perfectly usable native control behind.
   The colors below are ordinary in-page CSS on ordinary <div>s, so they apply
   in every browser regardless of OS theme — which is the whole point. */
.select-shell{position:relative;width:100%;}
/* Date pickers and other selects that size to their content: inline so the
   day/month/year trio stays on one line. */
.select-shell-auto{display:inline-block;width:auto;min-width:96px;vertical-align:bottom;}
.select-shell-auto .select-display{width:auto;min-width:96px;}
.select-shell-auto .select-menu{min-width:130px;}
.select-shell > select{
  position:absolute;opacity:0;pointer-events:none;
  width:100%;height:100%;top:0;right:0;margin:0;
}
.select-display{
  display:flex;align-items:center;gap:8px;width:100%;
  padding:10px 12px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  font-family:inherit;font-size:13px;font-weight:500;color:var(--ink);
  background:var(--paper-2);cursor:pointer;text-align:right;
  transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;
}
.select-display:hover{border-color:var(--brand);}
.select-display:focus-visible{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-bg);}
.select-display:disabled{background:var(--paper);color:var(--muted);cursor:not-allowed;}
.select-text{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
/* Caret drawn in currentColor rather than as a background image, so it can
   never end up invisible against the control the way the native one could. */
.select-caret{
  flex:0 0 auto;width:0;height:0;
  border-left:4.5px solid transparent;border-right:4.5px solid transparent;
  border-top:5px solid var(--ink-2);
}
.select-shell.open .select-caret{transform:rotate(180deg);}

.select-menu{
  display:none;position:absolute;top:calc(100% + 4px);right:0;left:0;z-index:70;
  max-height:260px;overflow-y:auto;
  background:var(--paper-2);border:1px solid var(--line-2);border-radius:var(--r-md);
  box-shadow:var(--shadow-md);padding:4px;
}
.select-shell.open .select-menu{display:block;}
.select-option{
  padding:9px 11px;border-radius:var(--r-sm);font-size:13px;color:var(--ink);
  cursor:pointer;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.select-option:hover{background:var(--brand-bg);color:var(--brand);}
.select-option.selected{background:var(--brand);color:#fff;font-weight:700;}
.select-option.disabled{color:var(--muted);cursor:not-allowed;background:none;}

/* Fallback for the un-enhanced case (script blocked, or a multi-select, which
   enhanceSelects deliberately skips): keep the native control readable. */
select{background-color:#FFFFFF;color:#0A1C26;}
select option{color:#0A1C26;background-color:#FFFFFF;}
.password-field{position:relative;}
.password-field input[type=password],.password-field input[type=text]{padding-left:38px;}
.password-toggle{position:absolute;left:6px;top:50%;transform:translateY(-50%);background:none;border:none;cursor:pointer;padding:5px;color:var(--muted);display:flex;border-radius:6px;}
.password-toggle:hover{color:var(--ink);background:var(--line);}
.password-toggle svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.form-inline{display:flex;gap:10px;align-items:flex-end;flex-wrap:wrap;}
.form-inline .form-row{flex:1;min-width:140px;margin-bottom:0;}
.toolrow{display:flex;gap:10px;flex-wrap:wrap;margin-top:8px;}

/* home screen tile grid, bottom nav */
.home-wrap{padding-bottom:70px;}
.home-header{display:flex;align-items:center;justify-content:space-between;padding:6px 2px 20px;}
.home-header .app-title{font-size:17px;font-weight:800;letter-spacing:-.01em;}
.home-header .icon-btn{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--paper-2);border:1px solid var(--line);position:relative;cursor:pointer;box-shadow:var(--shadow-sm);color:var(--ink-2);}
.home-header .icon-btn svg{width:18px;height:18px;}
.home-header .icon-btn .dot{position:absolute;top:1px;left:1px;width:8px;height:8px;border-radius:50%;background:var(--coral);border:1.5px solid var(--paper-2);}
.tile-section{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:19px;margin-bottom:14px;box-shadow:none;}
.tile-section h3{font-size:14px;font-weight:800;letter-spacing:-.015em;margin:0 0 15px;}

/* Tiles fill the row rather than being pinned to a fixed column count: a
   section with five tiles used to leave a three-quarter-empty last row on a
   four-column grid. auto-fit with a minimum keeps them a sensible size at any
   count and any width. Screens that pass an explicit column count inline still
   override this, which is why those cases still work. */
.tile-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(148px,1fr));gap:12px;}
@media (max-width:520px){.tile-grid{grid-template-columns:repeat(2,1fr);}}

/* Each tile is now a real card, not a floating icon with a caption under it.
   It has a surface, an edge, and a hit area that matches what it looks like —
   before, the clickable region was just the icon and the words. */
.tile{
  display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:11px;
  min-height:132px;padding:18px 12px 16px;
  background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);
  cursor:pointer;font-family:inherit;position:relative;overflow:hidden;
  transition:border-color .16s ease-in-out,transform .16s ease-in-out,background .16s ease-in-out;
}
/* A yolk bar that grows along the top edge on hover. One accent, one moment —
   enough to confirm the target without the card itself changing colour and
   making a grid of them flicker as the pointer crosses. */
.tile::before{
  content:"";position:absolute;top:0;right:0;left:0;height:3px;
  background:var(--accent-bright);transform:scaleX(0);transform-origin:right;
  transition:transform .18s cubic-bezier(.4,0,.2,1);
}
.tile:hover{border-color:var(--brand);transform:translateY(-2px);background:var(--paper-2);}
.tile:hover::before{transform:scaleX(1);}
.tile:active{transform:translateY(0);}
.tile:focus-visible{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-bg);}

.tile .tile-icon{
  width:52px;height:52px;border-radius:var(--r-lg);background:var(--brand-bg);
  display:flex;align-items:center;justify-content:center;position:relative;flex:0 0 auto;
  transition:background .16s ease-in-out;
}
.tile:hover .tile-icon{background:var(--brand);}
.tile .tile-icon svg{width:24px;height:24px;stroke:var(--brand);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:stroke .16s ease-in-out;}
.tile:hover .tile-icon svg{stroke:#fff;}

/* Raised from 11px: these are the main navigation of several screens, and a
   two-line Persian label at 11px is genuinely hard to read. The fixed line
   height keeps one-line and two-line tiles the same height as each other. */
.tile .tile-label{
  font-size:12.5px;color:var(--ink);text-align:center;line-height:1.65;font-weight:600;
  display:flex;align-items:center;min-height:2.4em;
}
.tile .tile-icon .badge-count{
  position:absolute;top:-5px;left:-5px;background:var(--coral);color:#fff;
  font-size:10.5px;font-weight:800;border-radius:10rem;min-width:19px;height:19px;
  display:flex;align-items:center;justify-content:center;padding:0 5px;
  box-shadow:0 0 0 2px var(--paper-2);font-variant-numeric:tabular-nums;
}
/* A tile inside .tile-section sits on a white card already, so it takes the
   canvas tint instead — otherwise it is a white card on a white card and the
   edge is the only thing separating them. */
.tile-section .tile{background:var(--paper);}
.tile-section .tile:hover{background:var(--paper-2);}
.tile-section .tile::before{background:var(--accent-bright);}

@media (prefers-reduced-motion: reduce){
  .tile,.tile::before,.tile .tile-icon{transition:none;}
  .tile:hover{transform:none;}
}

.bottom-nav{position:fixed;bottom:0;left:0;right:0;background:var(--paper-2);border-top:1px solid var(--line);display:flex;justify-content:space-around;padding:9px 4px 11px;max-width:1400px;margin:0 auto;box-shadow:var(--shadow-lg);}
.bottom-nav .nav-item{display:flex;flex-direction:column;align-items:center;gap:4px;font-size:10px;color:var(--muted);cursor:pointer;flex:1;background:none;border:none;font-family:inherit;transition:color .15s ease-in-out;font-weight:600;}
.bottom-nav .nav-item .nav-icon{display:flex;}
.bottom-nav .nav-item .nav-icon svg{width:21px;height:21px;stroke:var(--muted);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:stroke .15s ease-in-out;}
.bottom-nav .nav-item.active{color:var(--brand);}
.bottom-nav .nav-item.active .nav-icon svg{stroke:var(--brand);}

.center-box{max-width:420px;margin:60px auto;background:var(--paper-2);border:none;border-radius:var(--r-lg);padding:32px;box-shadow:var(--shadow-lg);}
.center-box h2{font-size:18px;margin:0 0 18px;font-weight:800;}

.logout{font-size:12px;color:var(--muted);cursor:pointer;text-decoration:underline;}
#app.sidebar-shell .logout{color:var(--ink-2);}

.invoice-box{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:22px;margin-top:10px;box-shadow:none;}
.invoice-box .invoice-row{display:flex;justify-content:space-between;padding:7px 0;border-bottom:1px dashed var(--line);}
.invoice-box .invoice-row:last-child{border-bottom:none;}
@media print{
  body *{visibility:hidden;}
  .invoice-print,.invoice-print *{visibility:visible;}
  .invoice-print{position:absolute;top:0;right:0;left:0;margin:0;padding:24px;box-shadow:none;}
}

.product-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;}
@media (max-width:720px){.product-grid{grid-template-columns:repeat(2,1fr);}}
.product-card{background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;display:flex;flex-direction:column;box-shadow:none;transition:border-color .15s ease-in-out,transform .15s ease-in-out;}
.product-card:hover{border-color:var(--brand);transform:translateY(-2px);}
.product-card .product-image{width:100%;aspect-ratio:1/1;object-fit:cover;background:var(--paper);display:block;}
.product-card .product-image-placeholder{width:100%;aspect-ratio:1/1;background:var(--paper);display:flex;align-items:center;justify-content:center;color:var(--muted);}
.product-card .product-image-placeholder svg{width:32px;height:32px;stroke:var(--muted);fill:none;stroke-width:1.6;}
.product-card .product-body{padding:11px 13px 13px;display:flex;flex-direction:column;gap:6px;flex:1;}
.product-card .product-name{font-size:13px;font-weight:700;color:var(--ink);}
.product-card .product-price{font-size:15.5px;font-weight:800;color:var(--brand);letter-spacing:-.02em;font-variant-numeric:tabular-nums;}
.product-card .product-desc{font-size:11px;color:var(--muted);line-height:1.6;max-height:32px;overflow:hidden;}

.chip-row{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0;}
.chip{background:var(--paper-2);border:1px solid var(--line-2);border-radius:999px;padding:7px 16px;font-size:12.5px;font-weight:600;color:var(--ink);cursor:pointer;white-space:nowrap;transition:background .12s ease-in-out,border-color .12s ease-in-out,color .12s ease-in-out;}
.chip:hover{background:var(--brand-bg);border-color:var(--brand);color:var(--brand);}

.permission-picker{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;max-height:420px;overflow-y:auto;}
.permission-item{display:flex;align-items:center;gap:10px;padding:9px 14px;cursor:pointer;font-size:12.5px;font-weight:500;color:var(--ink);background:var(--paper-2);border-bottom:1px solid var(--line);user-select:none;transition:background .12s ease-in-out;}
.permission-item:last-child{border-bottom:none;}
.permission-item:hover{background:var(--brand-bg);}
.permission-item input[type=checkbox]{display:inline-block;width:17px;height:17px;flex:0 0 auto;accent-color:var(--brand);cursor:pointer;margin:0;padding:0;}
.permission-item.sub-item{padding-right:36px;background:var(--paper);font-size:12px;font-weight:400;}
.permission-item.sub-item:hover{background:var(--brand-bg);}
/* Grouped/gridded layout — one bordered card per top-level section (فروشگاه،
   تسهیلات، مدیریت مالی، ...), its own checkbox as the card's header row, and
   its sub-permissions (if any) laid out in a responsive grid underneath instead
   of one long scrolling column — used in «تنظیمات → کاربران مدیریتی و سطوح
   دسترسی»'s create/edit pages. */
.permission-groups{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:10px;}
.permission-group{border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;background:var(--paper-2);align-self:start;}
.permission-group .permission-item{border-bottom:1px solid var(--line);font-weight:700;}
.permission-group .permission-subgrid{display:flex;flex-direction:column;}
.permission-group .permission-subgrid .permission-item{border-bottom:1px solid var(--line);}
.permission-group .permission-subgrid .permission-item:last-child{border-bottom:none;}

/* Roomier field layout for the "تسهیلات" admin tab's expanded application /
   final-approval detail views, so applicant + guarantor + document fields
   don't all wrap into a single cramped column. */
.queue-detail-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:6px 22px;margin-top:8px;}
.queue-detail-grid .meta{margin:0;}
.app-wide .queue-item{padding:18px 22px;}

/* ---------------------------------------------------------------------
   Public marketing homepage (www.<domain> / the bare domain — SITE_MODE
   "all"). Deliberately its own look, not the app/login chrome: full-width,
   no card, no sidebar — a normal commercial site layout. */
/* Deep blue and the logo's yolk, per brief. Scoped to .hp so the panels' own
   near-black-teal system is untouched — the public page is a different room. */
.hp{
  --hp-blue:#072E63;        /* the field: deep, saturated, not navy-grey */
  --hp-blue-d:#041D42;      /* footer and pressed states */
  --hp-blue-2:#0C4E96;      /* the lift in the hero gradient */
  --hp-yolk:#FFB400;        /* the logo's own yellow */
  --hp-yolk-d:#C07F00;      /* yolk that has to survive as text on white */
  --hp-paper:#F4F7FB;
  --hp-ink:#0A1C2E;
  --hp-ink-2:#4A6076;
  --hp-line:#DCE5EE;
  background:var(--paper-2);color:var(--hp-ink);
}
body.homepage-mode{background:var(--paper-2);}
body.homepage-mode .app{max-width:none;padding:0;}

/* --- header ------------------------------------------------------- */
.hp-header{
  display:flex;align-items:center;gap:24px;
  max-width:1180px;margin:0 auto;padding:18px 24px;
}
.hp-brand{display:flex;align-items:center;gap:10px;font-size:19px;font-weight:800;color:var(--hp-blue);text-decoration:none;}
.hp-brand.footer{color:#fff;}
.hp-nav{display:flex;gap:22px;margin-inline-start:auto;}
.hp-nav a{font-size:13.5px;font-weight:600;color:var(--hp-ink-2);text-decoration:none;padding:4px 0;border-bottom:2px solid transparent;}
.hp-nav a:hover{color:var(--hp-blue);border-bottom-color:var(--hp-yolk);}
.hp-header-actions{display:flex;gap:10px;}
@media (max-width:860px){
  .hp-nav{display:none;}
  .hp-header{flex-wrap:wrap;gap:12px;}
  .hp-header-actions{margin-inline-start:auto;}
}

.hp-btn{
  display:inline-flex;align-items:center;justify-content:center;
  padding:9px 18px;border-radius:8px;font-size:13px;font-weight:700;
  text-decoration:none;border:1.5px solid transparent;
  transition:background .15s ease-in-out,color .15s ease-in-out,border-color .15s ease-in-out;
}
.hp-btn.lg{padding:13px 26px;font-size:14.5px;}
.hp-btn.solid{background:var(--hp-yolk);color:var(--hp-blue-d);}
.hp-btn.solid:hover{background:#FFC633;}
.hp-btn.ghost{background:transparent;color:var(--hp-blue);border-color:var(--hp-line);}
.hp-btn.ghost:hover{border-color:var(--hp-blue);}
.hp-btn.outline{background:transparent;color:#fff;border-color:rgba(255,255,255,.55);}
.hp-btn.outline:hover{border-color:var(--hp-yolk);color:var(--hp-yolk);}
.hp-btn:focus-visible{outline:3px solid var(--hp-yolk);outline-offset:2px;}

/* --- hero ---------------------------------------------------------
   The one bold element: the logo's zigzag, blown up to fill the field.
   Everything else on the page stays quiet against it. */
.hp-hero{
  position:relative;overflow:hidden;isolation:isolate;
  background:linear-gradient(135deg,var(--hp-blue-d) 0%,var(--hp-blue) 45%,var(--hp-blue-2) 100%);
  padding:96px 24px 84px;text-align:center;
}
.hp-hero::before{
  content:"";position:absolute;inset:0;z-index:-2;
  background-image:var(--hp-hero-img,none);background-size:cover;background-position:center;
  opacity:.22;
}
.hp-hero-mark{
  position:absolute;z-index:-1;
  inset-inline-end:2%;top:50%;transform:translateY(-50%);
  width:min(420px,52vw);height:min(420px,52vw);
  opacity:.16;
}
@media (max-width:720px){.hp-hero-mark{inset-inline-end:-6%;opacity:.11;}}
.hp-hero-inner{position:relative;max-width:760px;margin:0 auto;}
.hp-hero h1{
  color:#fff;font-size:clamp(26px,4.4vw,42px);font-weight:800;
  line-height:1.55;margin:0 0 18px;letter-spacing:-.2px;
}
.hp-hero-sub{color:rgba(255,255,255,.86);font-size:clamp(14px,1.7vw,17px);line-height:2;margin:0 auto 32px;max-width:56ch;}
.hp-hero-actions{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;}
.hp-hero-nav{
  position:absolute;top:50%;transform:translateY(-50%);z-index:2;
  width:42px;height:42px;border-radius:50%;border:1.5px solid rgba(255,255,255,.35);
  background:rgba(255,255,255,.08);color:#fff;font-size:22px;line-height:1;cursor:pointer;
}
.hp-hero-nav:hover{background:rgba(255,255,255,.18);border-color:var(--hp-yolk);}
/* RTL: «previous» sits on the right, where reading starts, and its chevron
   points back that way. */
.hp-hero-nav.prev{inset-inline-end:18px;}
.hp-hero-nav.next{inset-inline-start:18px;}
@media (max-width:720px){.hp-hero{padding:64px 20px 56px;}.hp-hero-nav{display:none;}}

.hp-dots{display:flex;gap:8px;justify-content:center;margin-top:30px;}
.hp-dot{width:26px;height:4px;border-radius:2px;border:0;padding:0;background:rgba(255,255,255,.3);cursor:pointer;transition:background .15s ease-in-out;}
.hp-dot.active{background:var(--hp-yolk);}
.hp-dot:focus-visible{outline:2px solid var(--hp-yolk);outline-offset:3px;}

/* --- sections ------------------------------------------------------ */
.hp-section{max-width:1180px;margin:0 auto;padding:72px 24px;}
.hp-section-tint{max-width:none;background:var(--hp-paper);border-block:1px solid var(--hp-line);}
.hp-section-tint > *{max-width:1180px;margin-inline:auto;}
.hp-section-title{font-size:clamp(20px,2.6vw,27px);font-weight:800;margin:0 0 10px;text-align:center;color:var(--hp-blue);}
.hp-section-title.align-start{text-align:start;}
.hp-section-lead{text-align:center;color:var(--hp-ink-2);font-size:14px;line-height:1.9;margin:0 auto 40px;max-width:60ch;}
.hp-section > .hp-section-title + .hp-steps,
.hp-section > .hp-section-title + .hp-features{margin-top:40px;}

/* --- how it works: a genuine sequence, so it is numbered ----------- */
.hp-steps{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,1fr);gap:28px;}
@media (max-width:800px){.hp-steps{grid-template-columns:1fr;gap:20px;}}
.hp-step{display:flex;gap:16px;align-items:flex-start;}
.hp-step-num{
  flex:0 0 auto;width:38px;height:38px;border-radius:10px;
  display:flex;align-items:center;justify-content:center;
  background:var(--hp-yolk);color:var(--hp-blue-d);font-weight:800;font-size:16px;
}
.hp-step h3{font-size:15px;font-weight:800;margin:6px 0 6px;color:var(--hp-blue);}
.hp-step p{font-size:13px;line-height:1.95;color:var(--hp-ink-2);margin:0;}

/* --- products ------------------------------------------------------ */
.hp-cat{margin-bottom:44px;}
.hp-cat-name{
  font-size:15px;font-weight:800;color:var(--hp-blue);margin:0 0 18px;
  padding-inline-start:12px;border-inline-start:4px solid var(--hp-yolk);
}
.hp-products{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:18px;}
/* Two per row rather than one full-width card per product: a single column of
   4:3 images turns the section into a very long scroll on a phone. */
@media (max-width:560px){.hp-products{grid-template-columns:repeat(2,1fr);gap:12px;}
  .hp-product{padding:10px;}
  .hp-product h4{font-size:12.5px;}
  .hp-product-price{font-size:13.5px;}
  .hp-product-note{display:none;}
}
.hp-product{
  background:var(--paper-2);border:1px solid var(--hp-line);border-radius:12px;
  padding:14px;transition:border-color .15s ease-in-out;
}
.hp-product:hover{border-color:var(--hp-blue-2);}
.hp-product-img{
  aspect-ratio:4/3;border-radius:8px;overflow:hidden;background:var(--hp-paper);
  display:flex;align-items:center;justify-content:center;margin-bottom:12px;
}
.hp-product-img img{width:100%;height:100%;object-fit:cover;}
.hp-product-placeholder{width:52%;height:52%;}
.hp-product h4{font-size:13.5px;font-weight:700;margin:0 0 6px;line-height:1.7;color:var(--hp-ink);}
.hp-product-price{font-size:15px;font-weight:800;color:var(--hp-blue);margin:0 0 4px;}
.hp-product-note{font-size:11px;color:var(--hp-ink-2);line-height:1.7;margin:0;}

.hp-cta-strip{
  display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap;
  background:var(--hp-blue);border-radius:14px;padding:24px 28px;margin-top:8px;
}
.hp-cta-strip p{color:#fff;font-size:14.5px;font-weight:600;margin:0;line-height:1.8;}

/* --- features ------------------------------------------------------ */
.hp-features{display:grid;grid-template-columns:repeat(4,1fr);gap:20px;}
@media (max-width:900px){.hp-features{grid-template-columns:repeat(2,1fr);}}
@media (max-width:520px){.hp-features{grid-template-columns:1fr;}}
.hp-feature{border:1px solid var(--hp-line);border-radius:12px;padding:26px 20px;text-align:center;}
.hp-feature-icon{
  width:52px;height:52px;border-radius:12px;background:var(--hp-blue);
  display:flex;align-items:center;justify-content:center;margin:0 auto 15px;
}
.hp-feature-icon svg{width:24px;height:24px;stroke:var(--hp-yolk);fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;}
.hp-feature h3{font-size:14.5px;font-weight:800;margin:0 0 8px;color:var(--hp-blue);}
.hp-feature p{font-size:12.5px;color:var(--hp-ink-2);line-height:1.85;margin:0;}

/* --- about --------------------------------------------------------- */
.hp-about-grid{display:grid;grid-template-columns:300px 1fr;gap:44px;align-items:center;}
@media (max-width:820px){.hp-about-grid{grid-template-columns:1fr;gap:28px;}}
.hp-about-img{width:100%;border-radius:14px;object-fit:cover;}
.hp-about-mark{
  aspect-ratio:1/1;border-radius:14px;
  background:linear-gradient(135deg,var(--hp-blue-d),var(--hp-blue-2));
  display:flex;align-items:center;justify-content:center;
}
.hp-about-text{font-size:14px;line-height:2.1;color:var(--hp-ink-2);margin:14px 0 0;max-width:66ch;}

/* --- footer -------------------------------------------------------- */
.hp-footer{background:var(--hp-blue-d);color:rgba(255,255,255,.72);padding:44px 24px 26px;}
.hp-footer-grid{
  max-width:1180px;margin:0 auto;display:flex;gap:36px;flex-wrap:wrap;
  align-items:flex-start;justify-content:space-between;
}
.hp-footer-tag{font-size:12.5px;color:var(--hp-yolk);margin:10px 0 0;}
.hp-footer-contact{display:flex;flex-direction:column;gap:12px;}
.hp-contact-item{display:flex;align-items:center;gap:10px;font-size:13px;color:rgba(255,255,255,.86);}
.hp-contact-item svg{width:17px;height:17px;stroke:var(--hp-yolk);fill:none;stroke-width:1.8;stroke-linecap:round;flex:0 0 auto;}
.hp-footer-seal{background:#fff;border-radius:10px;padding:10px;}
.hp-footer-seal img{display:block;max-width:110px;height:auto;}
.hp-footer-legal{
  max-width:1180px;margin:32px auto 0;padding-top:20px;
  border-top:1px solid rgba(255,255,255,.14);
  font-size:12px;text-align:center;
}

@media (prefers-reduced-motion:reduce){
  .hp *{transition:none !important;}
}

/* =====================================================================
   Shared control layer — v2
   ---------------------------------------------------------------------
   These four controls (switch, searchbox, pager, table chrome) appear in
   all three panels, so they live here as one styled vocabulary rather
   than being re-improvised with inline styles at each of the ~40 call
   sites. Changing a control here changes it everywhere at once, and the
   markup helpers in app.js (switchHtml / searchBoxHtml /
   paginationControlsHtml) are the only places that emit them.
   ===================================================================== */

/* --- Switch ---------------------------------------------------------
   Replaces the checkbox wherever the thing being set is a *state* that
   stays on ("this admin holds this permission"), not an action you
   confirm later. Green rather than the brand blue: an on-switch should
   read as "granted" at a glance, and blue is already the color of every
   nav item and button around it. The real <input type=checkbox> is kept
   underneath and stays the form's actual field — only its appearance is
   replaced — so nothing about form submission or the server changed. */
.switch{position:relative;display:inline-flex;flex:0 0 auto;width:38px;height:22px;}
.switch input{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;z-index:2;}
.switch .switch-track{position:absolute;inset:0;background:#C9D4DB;border-radius:999px;transition:background .18s ease-in-out;}
.switch .switch-thumb{
  position:absolute;top:3px;right:3px;width:16px;height:16px;border-radius:50%;
  background:#fff;box-shadow:0 1px 3px rgba(15,40,54,.35);
  transition:transform .18s cubic-bezier(.4,0,.2,1);pointer-events:none;
}
.switch input:checked ~ .switch-track{background:var(--teal);}
.switch input:checked ~ .switch-thumb{transform:translateX(-16px);}
.switch input:disabled{cursor:not-allowed;}
.switch input:disabled ~ .switch-track{opacity:.45;}
.switch input:focus-visible ~ .switch-track{box-shadow:0 0 0 3px var(--brand-bg);}

/* Permission rows: label on the reading edge, switch on the far edge, so
   a column of them scans as one straight line of on/off states.
   The row icons reuse .sidebar-nav-icon for its sizing, but that class was
   written for the dark blue sidebar and paints its stroke near-white — on
   this white card the icons were effectively invisible. Repaint them here. */
.permission-item .sidebar-nav-icon svg{stroke:var(--ink-2);width:16px;height:16px;}
.permission-group > .permission-item .sidebar-nav-icon svg{stroke:var(--brand);}
.permission-item{justify-content:space-between;}
.permission-item .permission-label{display:flex;align-items:center;gap:9px;min-width:0;}
.permission-item .permission-label span:last-child{overflow:hidden;text-overflow:ellipsis;}
.permission-group .permission-item:first-child{background:var(--paper);}
.permission-group .permission-subgrid .permission-item{background:var(--paper-2);}

/* --- Search box -----------------------------------------------------
   Was a bare text input identical to every other field on the page, so
   nothing marked it as search. Magnifier sits on the reading edge; the
   clear button only exists while there's something to clear. */
.searchbox{position:relative;display:block;margin-bottom:13px;}
.searchbox > input[type=text]{padding-right:38px;padding-left:34px;height:40px;}
.searchbox .searchbox-icon{
  position:absolute;top:50%;right:12px;transform:translateY(-50%);
  display:flex;pointer-events:none;color:var(--muted);
}
.searchbox .searchbox-icon svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.searchbox > input[type=text]:focus ~ .searchbox-icon{color:var(--brand);}
.searchbox .searchbox-clear{
  position:absolute;top:50%;left:8px;transform:translateY(-50%);
  width:22px;height:22px;border:none;border-radius:50%;background:var(--paper);
  color:var(--ink-2);cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0;
}
.searchbox .searchbox-clear:hover{background:var(--line);color:var(--ink);}
.searchbox .searchbox-clear svg{width:12px;height:12px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;}
.searchbox-row{display:flex;gap:10px;align-items:flex-start;}
.searchbox-row .searchbox{flex:1;min-width:180px;}
.searchbox-row .btn{height:40px;}

/* --- Pager ----------------------------------------------------------
   The old control was «قبلی / صفحه ۳ از ۹ / بعدی»: to reach page 7 you
   clicked four times. Numbered pages make any page one click away, and
   the record count answers "how much is there?" without counting rows.
   Arrows are drawn as SVG chevrons rather than ◄ ►, whose direction is
   ambiguous in an RTL layout and which render as a different glyph on
   every platform. */
.pager{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap;margin-top:16px;padding-top:14px;border-top:1px solid var(--line);}
.pager-count{font-size:12px;color:var(--muted);}
.pager-count b{color:var(--ink-2);font-weight:700;}
.pager-pages{display:flex;align-items:center;gap:4px;}
.pager-btn{
  min-width:34px;height:34px;padding:0 9px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--paper-2);color:var(--ink-2);font-family:inherit;font-size:12.5px;font-weight:600;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  transition:background .12s ease-in-out,border-color .12s ease-in-out,color .12s ease-in-out;
}
.pager-btn:hover:not(:disabled){background:var(--brand-bg);border-color:var(--brand);color:var(--brand);}
.pager-btn.current{background:var(--brand);border-color:var(--brand);color:#fff;cursor:default;}
.pager-btn:disabled{opacity:.35;cursor:not-allowed;}
.pager-btn svg{width:15px;height:15px;stroke:currentColor;fill:none;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.pager-gap{min-width:18px;text-align:center;color:var(--muted);font-size:12px;user-select:none;}

/* --- Brand mark ------------------------------------------------------
   Both variants are emitted together and CSS picks one, so no render path
   has to know what colour the surface behind it is. The dark-surface form
   wins inside the sidebar and on the login gradient; the tile form
   everywhere else. */
.brand-mark{display:inline-flex;flex:0 0 auto;line-height:0;}
.brand-mark svg:last-child{display:none;}
#app.sidebar-shell .masthead .brand-mark svg:first-child,
body.landing-bg .brand-mark svg:first-child{display:none;}
#app.sidebar-shell .masthead .brand-mark svg:last-child,
body.landing-bg .brand-mark svg:last-child{display:block;}

/* --- Filter bar -----------------------------------------------------
   List screens had grown three stacked rows of controls — a search row,
   a sort/count row, then a separate date-filter <form> — each with its
   own margins, so the actual table started a third of the way down the
   page. This groups them into one bounded strip that reads as "the
   controls for the list below": search takes the free space, the rest
   sit at their natural width, and the result count is pushed to the far
   edge where it acts as the strip's readout rather than another control.
   The date filter stays its own <form> (it submits) but sits inside the
   same strip, separated by a rule instead of by whitespace. */
.filterbar{
  display:flex;align-items:flex-end;gap:10px;flex-wrap:wrap;
  padding:14px 16px;margin-bottom:14px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-md);
}
.filterbar > form{display:contents;}
.filterbar .searchbox{flex:1 1 220px;min-width:180px;margin-bottom:0;}
.filterbar .form-row{margin-bottom:0;flex:0 0 auto;}
.filterbar .form-row label{font-size:11.5px;margin-bottom:5px;}
.filterbar .btn{flex:0 0 auto;}
.filterbar .filterbar-count{margin-right:auto;align-self:center;font-size:12.5px;color:var(--ink-2);white-space:nowrap;}
.filterbar .filterbar-count b{color:var(--ink);font-weight:800;font-variant-numeric:tabular-nums;}
/* A vertical rule between the "find" controls and the "report on a date"
   controls — they answer different questions and shouldn't read as one
   continuous row of buttons. */
.filterbar .filterbar-sep{width:1px;align-self:stretch;background:var(--line-2);margin:0 2px;}
@media (max-width:900px){
  .filterbar{padding:12px;gap:9px;}
  .filterbar .searchbox{flex:1 1 100%;}
  .filterbar .filterbar-count{margin-right:0;width:100%;}
  .filterbar .filterbar-sep{display:none;}
}

/* --- Table chrome ---------------------------------------------------
   Long lists scroll inside .panel, so the header row sticks to the top
   of that scroll box instead of disappearing after eight rows. Zebra
   striping carries the eye across wide rows; tabular figures keep money
   columns aligned digit-over-digit. */
thead th{position:sticky;top:0;z-index:1;}
tbody tr:nth-child(even) td{background:rgba(6,42,58,.02);}
tbody tr:hover td{background:rgba(6,42,58,.05);}
td{font-variant-numeric:tabular-nums;}

/* --- Anchored wide tables -------------------------------------------
   «تسهیلات اعطا شده» is nineteen columns. Scrolling sideways to reach
   «وضعیت» used to push the borrower's name off screen, so by the time you
   arrived at the cell you wanted you no longer knew whose row it was.
   Pinning the row number and the name to the reading edge keeps the row's
   identity visible for the whole scroll. Both pinned cells need an opaque
   background of their own — the rest of the row slides underneath them —
   which is why the zebra and hover rules are restated here rather than
   inherited. */
.table-anchored th:nth-child(-n+2),
.table-anchored td:nth-child(-n+2){position:sticky;background:var(--paper-2);}
.table-anchored th:nth-child(1),.table-anchored td:nth-child(1){right:0;z-index:2;}
.table-anchored th:nth-child(2),.table-anchored td:nth-child(2){right:52px;z-index:2;}
.table-anchored thead th:nth-child(-n+2){z-index:3;}
.table-anchored td:nth-child(1){width:52px;min-width:52px;}
.table-anchored tbody tr:nth-child(even) td:nth-child(-n+2){background:#F7F9FA;}
.table-anchored tbody tr:hover td:nth-child(-n+2){background:#EAF0F3;}
/* The edge where the pinned pair ends and the scrolling area begins. */
.table-anchored th:nth-child(2),
.table-anchored td:nth-child(2){box-shadow:-1px 0 0 var(--line-2);}

/* --- Bar chart ------------------------------------------------------
   Horizontal rather than vertical: Persian product names are long, and a
   column chart would either clip them or rotate them onto their side.
   Laid out as rows, the name keeps its full length on the reading edge
   and the bar grows away from it. */
.bar-chart{display:flex;flex-direction:column;gap:8px;padding:16px;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);}
.bar-row{display:flex;align-items:center;gap:10px;}
.bar-label{flex:0 0 34%;max-width:34%;font-size:12.5px;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bar-track{flex:1;height:20px;background:var(--paper-2);border:1px solid var(--line);border-radius:5px;overflow:hidden;}
.bar-fill{display:block;height:100%;border-radius:4px 0 0 4px;transition:width .25s ease-in-out;}
.bar-value{flex:0 0 auto;min-width:44px;text-align:left;font-size:12.5px;font-weight:800;color:var(--ink);font-variant-numeric:tabular-nums;}

/* The legend spells out every pairing in words as well as colour — the
   palette repeats past twelve products, and colour alone also fails for
   anyone who can't separate two neighbouring hues. */
.chart-legend{display:flex;flex-wrap:wrap;gap:8px 18px;align-items:center;margin-top:12px;padding:12px 14px;background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-md);}
.chart-legend-title{font-size:11.5px;font-weight:800;color:var(--muted);width:100%;}
.chart-legend-item{display:inline-flex;align-items:center;gap:7px;font-size:12.5px;color:var(--ink-2);}
.chart-swatch{display:inline-block;width:12px;height:12px;border-radius:3px;flex:0 0 auto;}

@media (max-width:900px){
  .bar-label{flex-basis:42%;max-width:42%;font-size:12px;}
  .bar-chart{padding:12px;}
}

/* --- Agency tickets -------------------------------------------------
   The list is a work queue and the detail is a conversation, so they get
   different treatments: a scannable table on one side, message cards with
   a clear "mine vs support" split on the other. */
.ticket-topbar{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:18px;}
.ticket-head{display:flex;align-items:center;gap:12px;min-width:0;}
.ticket-back{
  flex:0 0 auto;width:38px;height:38px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  display:flex;align-items:center;justify-content:center;cursor:pointer;background:var(--paper-2);
  transition:background .14s ease-in-out,border-color .14s ease-in-out;
}
.ticket-back:hover{background:var(--brand-bg);border-color:var(--brand);}
.ticket-back svg{width:18px;height:18px;fill:none;stroke:var(--ink-2);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;}
.ticket-back-label{font-size:13px;font-weight:700;color:var(--ink-2);}
.ticket-head-title{font-size:18px;font-weight:800;letter-spacing:-.02em;display:flex;align-items:center;gap:10px;flex-wrap:wrap;}
.ticket-head-id{font-size:12px;color:var(--muted);margin-top:5px;font-variant-numeric:tabular-nums;}

.ticket-table .ticket-row{cursor:pointer;}
.ticket-icon-cell{width:44px;}
.ticket-icon{display:inline-flex;width:32px;height:32px;border-radius:var(--r-sm);align-items:center;justify-content:center;}
.ticket-icon svg{width:17px;height:17px;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
/* Open threads carry the brand tint, closed ones fade back — the row's state
   is legible before you reach the وضعیت column at the far end. */
.ticket-icon.open{background:var(--brand-bg);}
.ticket-icon.open svg{stroke:var(--brand);}
.ticket-icon.closed{background:var(--paper);}
.ticket-icon.closed svg{stroke:var(--muted);}
.ticket-id{font-variant-numeric:tabular-nums;color:var(--ink-2);white-space:nowrap;}
.ticket-subject{font-weight:600;}
.ticket-when{color:var(--ink-2);white-space:nowrap;}

.ticket-thread{display:flex;flex-direction:column;gap:12px;margin-bottom:26px;}
.ticket-day{align-self:center;font-size:11.5px;font-weight:700;color:var(--ink-2);background:var(--paper);border:1px solid var(--line);border-radius:999px;padding:4px 14px;margin:4px 0;}
.ticket-msg{border:1px solid var(--line);border-radius:var(--r-lg);padding:16px 18px;background:var(--paper-2);}
/* A rule on the reading edge separates the two voices without colouring the
   whole card, which would make a long thread tiring to read. */
.ticket-msg.from-me{border-right:3px solid var(--brand);}
.ticket-msg.from-support{border-right:3px solid var(--accent-bright);background:var(--paper);}
.ticket-msg-body{font-size:13.5px;line-height:2.05;color:var(--ink);white-space:pre-wrap;word-break:break-word;}
.ticket-msg-foot{font-size:11.5px;color:var(--muted);margin-top:12px;}
.ticket-attach-img{max-width:180px;border-radius:var(--r-md);border:1px solid var(--line);margin-top:10px;display:block;}

.ticket-sla{margin:0 0 16px;padding-right:20px;color:var(--ink-2);font-size:12.5px;line-height:2.1;}
.ticket-sla li{margin-bottom:2px;}

.ticket-composer-actions{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-top:12px;}
/* The native file input is unstyleable and shows an English "no file chosen";
   it is kept as the real field (so the form still submits normally) and hidden
   behind this label. */
.ticket-file{
  display:inline-flex;align-items:center;gap:9px;cursor:pointer;
  padding:9px 16px;border:1px dashed var(--line-2);border-radius:var(--r-sm);
  font-size:12.5px;font-weight:600;color:var(--ink-2);background:var(--paper-2);
}
.ticket-file:hover{border-color:var(--brand);color:var(--brand);}
.ticket-file svg{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.ticket-file input[type=file]{display:none;}
.ticket-file.has-file{border-style:solid;border-color:var(--teal);color:var(--teal);}

@media (max-width:900px){
  .ticket-head-title{font-size:16px;}
  .ticket-composer-actions{flex-direction:column;align-items:stretch;}
  .ticket-composer-actions .btn,.ticket-file{width:100%;justify-content:center;}
  .ticket-when{display:none;}
  .ticket-table thead th:nth-child(4){display:none;}
}

/* --- Rich-text editor (tickets) --------------------------------------
   A contenteditable surface rather than a textarea, because the design
   asks for bold/italic/code/lists. The markup it produces is untrusted
   like any other input — see lib/sanitize-html.js. */
.rte{border:1px solid var(--line-2);border-radius:var(--r-md);overflow:hidden;background:var(--paper-2);}
.rte:focus-within{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-bg);}
.rte-toolbar{display:flex;gap:2px;padding:6px 8px;border-bottom:1px solid var(--line);background:var(--paper);}
.rte-btn{
  width:32px;height:32px;border:none;border-radius:var(--r-sm);background:transparent;
  cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--ink-2);
  transition:background .12s ease-in-out,color .12s ease-in-out;
}
.rte-btn:hover{background:var(--brand-bg);color:var(--brand);}
.rte-btn svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.rte-surface{min-height:150px;max-height:340px;overflow-y:auto;padding:14px 15px;font-size:13.5px;line-height:2.05;color:var(--ink);outline:none;}
/* A contenteditable has no placeholder attribute of its own. */
.rte-surface:empty::before{content:attr(data-placeholder);color:var(--muted);pointer-events:none;}
.rte-surface ul,.rte-surface ol{padding-right:22px;margin:6px 0;}
.rte-surface code,.ticket-msg-body code{
  background:var(--paper);border:1px solid var(--line);border-radius:5px;
  padding:1px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;direction:ltr;display:inline-block;
}
.ticket-msg-body ul,.ticket-msg-body ol{padding-right:22px;margin:6px 0;}
.ticket-msg-body pre{background:var(--paper);border:1px solid var(--line);border-radius:var(--r-sm);padding:10px 12px;overflow-x:auto;direction:ltr;text-align:left;}

/* --- Account-holder inquiry -----------------------------------------
   Two lookups (card number and IBAN) answering the same question, so they
   sit side by side and centred rather than being buried at the top-right
   of a wide empty panel. The numbers and the resulting name are the whole
   content of the screen, so both are set large — this is a field that
   gets read aloud and checked against a document. */
.inquiry-page{max-width:860px;margin:8px auto 0;}
.inquiry-page > .section-sub{margin-bottom:22px;}
.inquiry-card{
  max-width:520px;margin:0 auto 20px;padding:24px;
  background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);
}
.inquiry-title{font-size:15px;font-weight:800;color:var(--ink);text-align:center;margin-bottom:18px;}
.inquiry-input{
  width:100%;text-align:center;direction:ltr;
  font-size:24px;font-weight:700;letter-spacing:.06em;
  padding:16px 12px;font-variant-numeric:tabular-nums;
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
}
.inquiry-count{text-align:center;font-size:12px;color:var(--muted);margin:8px 0 14px;font-variant-numeric:tabular-nums;}
/* The answer box keeps its full height whether or not it holds a name, so
   the layout doesn't jump when the result arrives. */
.inquiry-result{
  margin-top:18px;padding:16px;border-radius:var(--r-md);text-align:center;
  background:var(--paper);border:1px dashed var(--line-2);
}
.inquiry-result.filled{background:var(--brand-bg);border-style:solid;border-color:var(--brand);}
.inquiry-result-label{font-size:11.5px;font-weight:600;color:var(--muted);margin-bottom:8px;}
.inquiry-result-name{font-size:26px;font-weight:800;letter-spacing:-.02em;color:var(--muted);line-height:1.4;}
.inquiry-result.filled .inquiry-result-name{color:var(--brand);}

@media (max-width:900px){
  .inquiry-card{padding:18px;}
  .inquiry-input{font-size:19px;letter-spacing:.03em;padding:14px 8px;}
  .inquiry-result-name{font-size:22px;}
}

/* --- Warranty claim timeline ----------------------------------------
   The claim's history, shown to both sides. A نمایندگی that can see who
   decided what and when does not phone to ask, which is most of what a
   status field alone fails to prevent. */
.timeline{position:relative;padding-right:18px;}
.timeline::before{content:"";position:absolute;top:6px;bottom:6px;right:4px;width:2px;background:var(--line);}
.timeline-item{position:relative;display:flex;gap:10px;padding:0 0 16px;}
.timeline-item:last-child{padding-bottom:0;}
.timeline-dot{position:absolute;right:-18px;top:4px;width:10px;height:10px;border-radius:50%;background:var(--brand);border:2px solid var(--paper-2);}
.timeline-item:last-child .timeline-dot{background:var(--accent-bright);}
.timeline-title{font-size:13px;font-weight:700;color:var(--ink);}
.timeline-meta{font-size:11.5px;color:var(--muted);margin-top:3px;}
.timeline-note{font-size:12.5px;color:var(--ink-2);margin-top:6px;line-height:1.9;background:var(--paper);border-radius:var(--r-sm);padding:8px 10px;}
.service-detail{margin-top:14px;padding-top:14px;border-top:1px solid var(--line);}

/* --- Warranty activation --------------------------------------------
   The «+» button is the entry point for a form that isn't shown until it
   is wanted, so it carries the green of an additive action rather than
   the brand blue every other button uses. */
/* The «+» buttons that start a new record. Deliberately the loudest control on
   their screen: they are the one action a person came to that page to take,
   and everything else there is a list to read. */
.btn-add{
  background:var(--teal);font-size:14px;font-weight:800;
  padding:11px 22px 11px 18px;gap:10px;
}
.btn-add:hover{background:#0E6440;}
.btn-add:focus-visible{box-shadow:0 0 0 3px var(--teal-bg);}
/* The plus sits in its own lighter disc rather than being a character in the
   sentence — at this size a bare "+" reads as punctuation, and the disc makes
   it a mark. */
.btn-add .plus{
  display:inline-flex;align-items:center;justify-content:center;
  width:24px;height:24px;border-radius:50%;
  background:rgba(255,255,255,.22);
  font-size:20px;font-weight:800;line-height:1;
  /* The glyph's own bearing pushes it low inside a circle this small. */
  padding-bottom:2px;margin:0;
}
/* A tab that opens a «create» form. It carries the same mark as the add
   buttons, so the plus means one thing everywhere — it was a hand-written green
   glyph with inline styles before, outside the system and unable to follow it. */
.tab.tab-add .plus{
  display:inline-flex;align-items:center;justify-content:center;
  width:19px;height:19px;border-radius:50%;margin-left:7px;
  background:var(--teal);color:#fff;font-size:15px;font-weight:800;line-height:1;padding-bottom:1px;
  transition:background .14s ease-in-out;
}
.tab.tab-add.active .plus{background:#fff;color:var(--teal);}

/* The compact variant, used inside filter bars and inline forms where a
   full-size button would tower over the fields next to it. Same mark, scaled —
   so an «add» reads as an «add» wherever it appears. */
.btn.small.btn-add{font-size:12.5px;padding:8px 14px 8px 11px;gap:7px;}
.btn.small.btn-add .plus{width:19px;height:19px;font-size:16px;padding-bottom:1px;}

@media (max-width:900px){
  .btn-add{font-size:13.5px;padding:12px 18px;}
  .btn-add .plus{width:22px;height:22px;font-size:18px;}
  .btn.small.btn-add{font-size:12.5px;padding:9px 14px;}
  .btn.small.btn-add .plus{width:18px;height:18px;font-size:15px;}
}
.warranty-form{margin:16px 0 8px;padding:20px;background:var(--paper);border:1px solid var(--line-2);border-radius:var(--r-lg);}
/* Item type is a three-way choice made once per activation, so it reads as
   segmented buttons rather than a dropdown that hides two of the options. */
.type-choices{display:flex;gap:8px;flex-wrap:wrap;}
.type-choice{
  display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  padding:9px 18px;border:1px solid var(--line-2);border-radius:var(--r-sm);
  background:var(--paper-2);font-size:13px;font-weight:600;color:var(--ink-2);
  transition:background .12s ease-in-out,border-color .12s ease-in-out,color .12s ease-in-out;
}
.type-choice:hover{border-color:var(--brand);color:var(--brand);}
.type-choice.active{background:var(--brand);border-color:var(--brand);color:#fff;}
.type-choice input{position:absolute;opacity:0;width:0;height:0;}

/* --- Progress (bank report) ------------------------------------------
   The lookups run one at a time and a few hundred rows takes minutes, so
   the percentage is the only thing telling the person the screen hasn't
   died. It reports rows completed, not elapsed time — a real count rather
   than an animation that would keep moving if the run had stalled. */
.progress-block{margin-top:18px;padding:16px 18px;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);}
.progress-head{display:flex;justify-content:space-between;align-items:baseline;font-size:13px;font-weight:700;color:var(--ink);margin-bottom:10px;}
.progress-head b{font-size:20px;letter-spacing:-.02em;font-variant-numeric:tabular-nums;color:var(--brand);}
.progress-track{height:10px;border-radius:999px;background:var(--paper-2);border:1px solid var(--line);overflow:hidden;}
.progress-fill{display:block;height:100%;background:var(--brand);border-radius:999px;transition:width .25s ease-in-out;}
.progress-note{font-size:12px;color:var(--ink-2);margin-top:9px;}

/* --- Chat -----------------------------------------------------------
   Shared by both ends of the conversation: the customer panel and پنل
   مدیریت render the same markup, mirrored by a single `.mine` class, so
   the two sides can't drift apart in behaviour or spacing.
   The log is a fixed-height scroller rather than a growing page, because
   a long support history should not push the reply box below the fold. */
.chat-log{
  max-height:52vh;min-height:220px;overflow-y:auto;
  padding:16px;margin-bottom:12px;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);
  display:flex;flex-direction:column;gap:10px;
}
.chat-log.empty{align-items:center;justify-content:center;}
/* A date heading appears only when the day changes, so a long conversation
   stays readable without stamping the date onto every single bubble. */
.chat-day{
  align-self:center;font-size:11px;font-weight:700;color:var(--ink-2);
  background:var(--paper-2);border:1px solid var(--line);border-radius:999px;
  padding:3px 13px;margin:6px 0 2px;
}
.chat-msg{display:flex;max-width:78%;}
.chat-msg.mine{align-self:flex-start;}
.chat-msg.theirs{align-self:flex-end;}
.chat-bubble{padding:10px 14px;border-radius:var(--r-lg);font-size:13px;line-height:1.85;}
.chat-msg.mine .chat-bubble{background:var(--brand);color:#fff;border-bottom-left-radius:5px;}
.chat-msg.theirs .chat-bubble{background:var(--paper-2);border:1px solid var(--line);color:var(--ink);border-bottom-right-radius:5px;}
.chat-who{font-size:11px;font-weight:800;margin-bottom:4px;}
.chat-msg.theirs .chat-who{color:var(--accent);}
/* On the admin's own (blue) bubbles the yolk fails contrast, so the name is
   drawn in the bubble's own light-on-dark scale instead. */
.chat-msg.mine .chat-who{color:var(--accent-bright);}
.chat-text{white-space:pre-wrap;word-break:break-word;}
/* The timestamp is quiet but always present — a support log that can't be
   dated can't be audited later. */
.chat-time{font-size:10.5px;margin-top:5px;opacity:.72;font-variant-numeric:tabular-nums;}
.chat-msg.mine .chat-time{color:rgba(255,255,255,.85);}
.chat-msg.theirs .chat-time{color:var(--muted);}

.chat-composer{display:flex;gap:10px;align-items:flex-end;}
.chat-composer textarea{flex:1;resize:vertical;min-height:44px;margin:0;}
.chat-composer .btn{height:44px;flex:0 0 auto;}

/* Queue rows: an unanswered conversation gets the amber edge, so the list
   reads as a work queue at a glance rather than a list of names. */
.chat-thread{cursor:pointer;border-right:4px solid var(--line-2);}
.chat-thread:hover{border-color:var(--brand);border-right-color:var(--brand);}
.chat-thread.unanswered{border-right-color:var(--amber);background:var(--amber-bg);}
.chat-thread-last{font-size:12px;color:var(--ink-2);margin-top:5px;line-height:1.7;}

@media (max-width:900px){
  .chat-msg{max-width:88%;}
  .chat-log{max-height:46vh;padding:13px;}
  .chat-composer{flex-direction:column;align-items:stretch;}
  .chat-composer .btn{width:100%;justify-content:center;}
}

/* --- Readiness rows --------------------------------------------------
   Each row is one pre-launch check. Colour carries the verdict, but so
   does the icon (tick vs warning triangle) and the wording of the title,
   so the state survives being read on a bad screen or by someone who
   can't separate the two tints. */
.readiness-row{display:flex;gap:12px;align-items:flex-start;padding:15px 17px;border:1px solid var(--line);border-right-width:4px;border-radius:var(--r-md);margin-bottom:10px;background:var(--paper-2);}
.readiness-row.ok{border-right-color:var(--teal);}
.readiness-row.warn{border-right-color:var(--amber);background:var(--amber-bg);}
.readiness-mark{display:flex;flex:0 0 auto;margin-top:1px;}
.readiness-mark svg{width:19px;height:19px;fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.readiness-row.ok .readiness-mark svg{stroke:var(--teal);}
.readiness-row.warn .readiness-mark svg{stroke:var(--amber);}
.readiness-title{font-size:13.5px;font-weight:800;color:var(--ink);margin-bottom:4px;}
.readiness-detail{font-size:12.5px;line-height:1.9;color:var(--ink-2);}
.readiness-detail code{background:var(--paper);border:1px solid var(--line);border-radius:5px;padding:1px 6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;direction:ltr;display:inline-block;}

/* --- Empty state ----------------------------------------------------
   A one-cell "موردی یافت نشد" in an otherwise empty table reads as a
   glitch. This says the same thing as a deliberate piece of the page. */
.empty-state{display:flex;flex-direction:column;align-items:center;gap:10px;padding:38px 20px;color:var(--muted);}
.empty-state svg{width:30px;height:30px;stroke:var(--line);fill:none;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
.empty-state .empty-title{font-size:13px;font-weight:700;color:var(--ink-2);}
.empty-state .empty-hint{font-size:12px;line-height:1.7;text-align:center;max-width:320px;}

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

/* =====================================================================
   Installment payment panel — the three-way method chooser
   ===================================================================== */
.payrow > td{background:var(--paper-2);padding:16px !important;}

/* Three equal cards rather than a dropdown: on a phone these are the whole
   decision, and a closed select hides two of the three options. */
.paymethods{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:14px;}
@media (max-width:520px){.paymethods{grid-template-columns:1fr;}}
.paymethod{
  display:flex;flex-direction:column;gap:3px;align-items:center;
  padding:13px 10px;border-radius:10px;cursor:pointer;
  border:1.5px solid var(--line);background:var(--paper);
  font-family:inherit;transition:border-color .15s ease-in-out,background .15s ease-in-out;
}
.paymethod:hover{border-color:var(--teal);}
.paymethod.active{border-color:var(--teal);background:var(--teal-bg);}
.paymethod-label{font-size:13.5px;font-weight:700;color:var(--ink);}
.paymethod-note{font-size:11px;color:var(--ink-2);}
.paymethod:focus-visible{outline:2px solid var(--teal);outline-offset:2px;}

.paybox{border:1px solid var(--line);border-radius:10px;padding:14px;background:var(--paper);}
.paybox-row{display:flex;justify-content:space-between;gap:12px;padding:7px 0;border-bottom:1px solid var(--line);}
.paybox-row:last-of-type{border-bottom:0;}
.paybox-k{font-size:12.5px;color:var(--ink-2);}
/* Tabular figures so the digits the person is copying line up and can be read
   one group at a time — this number has to be transcribed exactly. */
.paybox-v{font-size:15px;font-variant-numeric:tabular-nums;letter-spacing:.4px;}
.paybox-warn{
  margin-top:12px;padding:11px 13px;border-radius:8px;
  background:var(--amber-bg);color:var(--amber);font-size:12.5px;line-height:1.9;
}
.copybtn{
  margin-inline-start:8px;padding:3px 10px;border-radius:6px;cursor:pointer;
  border:1px solid var(--line);background:var(--paper-2);
  font-family:inherit;font-size:11px;font-weight:700;color:var(--ink-2);
}
.copybtn:hover{border-color:var(--teal);color:var(--teal);}
.copybtn:focus-visible{outline:2px solid var(--teal);outline-offset:2px;}
/* Says the screen is watching, so pressing the button feels optional rather
   than required. Quiet on purpose — it is reassurance, not an instruction. */
.paybox-auto{margin-top:12px;font-size:12px;color:var(--ink-2);line-height:1.9;}

/* =====================================================================
   Installment calculator — sliders for the down payment and the term
   ===================================================================== */
.calc{border:1px solid var(--line);border-radius:14px;padding:18px;margin:16px 0;background:var(--paper-2);}
.calc-title{font-size:14.5px;font-weight:800;color:var(--brand);margin-bottom:14px;}
.calc-label{display:flex;justify-content:space-between;align-items:baseline;gap:12px;font-size:13px;color:var(--ink-2);margin:16px 0 8px;}
/* The figure must not wrap mid-number — it is the thing being read. The label
   beside it gives way instead. */
.calc-label b{font-size:15px;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap;flex:0 0 auto;}
.calc-label{max-width:300px;gap:10px;}
.calc-label > :first-child{min-width:0;}

/* A compact slider. It was full-width with a 26px thumb, which on a phone read
   as the loudest thing on the screen when it is only one input among several.
   Blue track to match the brand's deep blue; the figures beside it stay black so
   the numbers — the thing actually being read — carry the weight. */
.calc-slider{
  -webkit-appearance:none;appearance:none;
  width:100%;max-width:300px;height:5px;border-radius:3px;
  background:linear-gradient(to left, #0C4E96, #072E63);
  outline:none;padding:0;margin:0;display:block;
}
.calc-slider::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;width:18px;height:18px;border-radius:50%;
  background:#fff;border:3px solid #072E63;cursor:grab;box-shadow:0 1px 3px rgba(0,0,0,.25);
}
.calc-slider::-moz-range-thumb{
  width:18px;height:18px;border-radius:50%;
  background:#fff;border:3px solid #072E63;cursor:grab;box-shadow:0 1px 3px rgba(0,0,0,.25);
}
.calc-slider:active::-webkit-slider-thumb{cursor:grabbing;}
.calc-slider:focus-visible{box-shadow:0 0 0 3px rgba(12,78,150,.25);}

.calc-ends{display:flex;justify-content:space-between;max-width:300px;font-size:11px;color:var(--ink);margin-top:6px;font-variant-numeric:tabular-nums;}
.calc-note{font-size:12px;color:var(--ink-2);margin-top:10px;line-height:1.9;}

.calc-out{margin-top:18px;border-top:1px solid var(--line);padding-top:6px;}
.calc-row{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:9px 0;border-bottom:1px solid var(--line);}
.calc-row:last-child{border-bottom:0;}
.calc-k{font-size:12.5px;color:var(--ink-2);}
.calc-v{font-size:13.5px;font-variant-numeric:tabular-nums;}
.calc-v.strong{font-size:16px;font-weight:800;color:var(--brand);}
.calc-small{font-size:11px;color:var(--ink-2);font-weight:400;}

/* The sale contract / invoice, shown as issued. Monospaced-ish line handling so
   the schedule table the template produces keeps its alignment. */
.contract-text{
  white-space:pre-wrap;word-break:break-word;
  background:var(--paper-2);border:1px solid var(--line);border-radius:12px;
  padding:20px;font-family:inherit;font-size:13px;line-height:2.1;color:var(--ink);
  margin:14px 0 0;max-height:60vh;overflow:auto;
}
@media print{
  /* Printing a contract should give the contract, not the app around it. */
  body *{visibility:hidden;}
  .contract-text, .contract-text *{visibility:visible;}
  .contract-text{position:absolute;inset:0;max-height:none;border:0;overflow:visible;}
}

/* A slimmer slider for month selection — a month has a handful of stops, not a
   continuous range, so it needs less presence than the amount slider. */
.calc-slider.small{height:4px;max-width:240px;}
.calc-slider.small::-webkit-slider-thumb{width:16px;height:16px;border-width:2.5px;}
.calc-slider.small::-moz-range-thumb{width:16px;height:16px;border-width:2.5px;}
.calc-slider.small + .calc-ends{max-width:240px;}

/* The stops, written out. A slider whose positions are invisible makes the
   person hunt for the value they want. */
.calc-ticks{display:flex;justify-content:space-between;margin-top:8px;}
.calc-ticks span{
  font-size:11.5px;color:var(--ink-2);font-variant-numeric:tabular-nums;
  min-width:22px;text-align:center;padding:2px 0;border-radius:4px;
}
.calc-ticks span.on{background:var(--brand);color:#fff;font-weight:700;}

/* The company seal, printed at the foot of a signed contract. */
.contract-stamp{margin-top:16px;text-align:left;}
.contract-stamp img{max-width:170px;max-height:130px;object-fit:contain;}
@media print{
  .contract-stamp, .contract-stamp *{visibility:visible;}
  .contract-stamp{position:absolute;bottom:20px;left:20px;}
}

/* The install offer on the entrance screens. Quiet by design: it sits under the
   login form, because someone arriving to sign in came to sign in. */
.install-banner{
  display:flex;align-items:center;gap:14px;justify-content:space-between;flex-wrap:wrap;
  margin-top:18px;padding:14px 16px;border-radius:12px;
  background:var(--brand-bg);border:1px solid var(--line);
}
.install-banner b{display:block;font-size:13.5px;color:var(--brand);margin-bottom:3px;}
.install-banner span{font-size:12px;color:var(--ink-2);line-height:1.85;}

/* Images the contract's own placeholders drop in, at the spot the author chose. */
.contract-img{display:inline-block;vertical-align:middle;max-width:100%;}
.contract-img.stamp{max-width:150px;max-height:120px;object-fit:contain;}
.contract-img.logo{max-width:220px;max-height:90px;object-fit:contain;}
.contract-img-missing{
  display:inline-block;padding:2px 8px;border:1px dashed var(--line);border-radius:6px;
  font-size:11px;color:var(--ink-2);
}

/* ---- Contract signing (قرارداد ضمانت / قرارداد خرید) ---------------------
   Laid out like a payment provider's signing step: where you are in the
   process, the contract in its own scrolling sheet, one clear action, and the
   SMS code in a dialog with a box per digit. */
.sign-page{max-width:640px;margin:0 auto;text-align:center;}
.sign-stepper{list-style:none;display:flex;justify-content:space-between;align-items:flex-start;gap:0;margin:6px auto 26px;padding:0;max-width:520px;position:relative;}
.sign-stepper li{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px;position:relative;font-size:12.5px;color:var(--muted);}
.sign-stepper li + li::before{content:"";position:absolute;top:10px;left:50%;width:100%;height:2px;background:var(--line);z-index:0;}
.sign-stepper li.done + li::before,.sign-stepper li.done + li.active::before{background:var(--brand);}
.sign-stepper .dot{position:relative;z-index:1;width:22px;height:22px;border-radius:50%;border:2px solid var(--line-2);background:var(--paper-2);display:flex;align-items:center;justify-content:center;font-size:12px;color:#fff;}
.sign-stepper li.done .dot{background:var(--teal);border-color:var(--teal);}
.sign-stepper li.active .dot{border-color:var(--brand);box-shadow:inset 0 0 0 4px var(--paper-2);background:var(--brand);}
.sign-stepper li.active .lbl{color:var(--ink);font-weight:700;}
.sign-stepper li.done .lbl{color:var(--ink-2);}
.sign-title{font-size:24px;font-weight:800;color:var(--ink);margin:0 0 10px;}
.sign-intro{font-size:13.5px;color:var(--ink-2);line-height:1.9;margin:0 auto 18px;max-width:520px;}
.sign-contract{text-align:right;background:var(--paper);border:1px solid var(--line);border-radius:var(--r-lg);padding:16px 18px;max-height:340px;overflow-y:auto;margin:0 auto;}
.sign-date{font-size:12.5px;color:var(--ink-2);margin-bottom:8px;}
.sign-contract-text{white-space:pre-wrap;word-break:break-word;font-size:13.5px;line-height:2.1;color:var(--ink);}
.sign-facts{display:flex;flex-direction:column;gap:4px;font-size:12.5px;color:var(--ink-2);margin:12px 0 0;}
.btn.sign-primary{display:block;width:100%;max-width:640px;margin:14px auto 0;padding:13px 16px;font-size:14px;font-weight:700;}
.sign-links{display:flex;justify-content:center;gap:22px;margin:14px 0 4px;font-size:13px;}
.linklike{color:var(--brand);cursor:pointer;font-weight:600;}
.linklike:hover{text-decoration:underline;}

.otp-overlay{position:fixed;inset:0;background:rgba(6,42,58,.45);display:flex;align-items:center;justify-content:center;z-index:1000;padding:16px;}
.otp-dialog{background:var(--paper-2);border-radius:var(--r-lg);width:100%;max-width:440px;overflow:hidden;border:1px solid var(--line);}
.otp-head{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid var(--line);}
.otp-head h3{margin:0;font-size:17px;font-weight:800;color:var(--ink);}
.otp-close{background:none;border:0;font-size:26px;line-height:1;color:var(--ink-2);cursor:pointer;padding:0 4px;}
.otp-body{padding:20px 22px 18px;text-align:center;}
.otp-art{display:flex;justify-content:center;margin-bottom:10px;}
.otp-text{font-size:13.5px;line-height:2;color:var(--ink);margin:0 0 16px;}
.otp-boxes{display:flex;justify-content:center;gap:8px;}
.otp-box{width:46px;height:52px;text-align:center;font-size:22px;font-weight:700;border:1.5px solid var(--line-2);border-radius:var(--r-md);background:var(--paper-2);color:var(--ink);padding:0;font-variant-numeric:tabular-nums;}
.otp-box:focus{outline:none;border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-bg);}
.otp-box:disabled{opacity:.6;}
.otp-error{min-height:20px;margin-top:10px;font-size:12.5px;color:var(--coral);}
.otp-resend{font-size:12.5px;color:var(--ink-2);margin-top:4px;}
@media (max-width:420px){.otp-box{width:40px;height:48px;font-size:20px;}.otp-boxes{gap:6px;}.sign-title{font-size:20px;}}

/* The credit request journey at the top of each step. Seven stops do not fit a
   phone's width, so the bar scrolls sideways instead of squeezing the labels. */
.process-stepper-wrap{overflow-x:auto;margin:6px 0 4px;-webkit-overflow-scrolling:touch;}
.process-stepper-wrap .sign-stepper{min-width:620px;max-width:none;margin:8px 0 18px;}
.process-stepper-wrap .sign-stepper li{font-size:11.5px;}
.agency-pick{display:flex;flex-direction:column;gap:8px;text-align:right;max-width:520px;margin:0 auto;}
.agency-option{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:var(--r-md);padding:12px 14px;cursor:pointer;background:var(--paper-2);}
.agency-option input{width:auto;margin:0;}
.agency-option .meta{display:block;margin-top:2px;}
.agency-option:has(input:checked){border-color:var(--brand);box-shadow:0 0 0 2px var(--brand-bg);}

/* Signing screen — laid out like a payment provider's contract step: a narrow
   centred column, the three-step bar, a bold title, the contract on a light
   sheet that scrolls on its own, one full-width action and a plain «بازگشت». */
.sign-screen{padding:18px 0 8px;}
.sign-screen .sign-page{max-width:540px;}
.sign-screen .sign-stepper{max-width:480px;margin:4px auto 34px;}
.sign-screen .sign-title{font-size:26px;margin:0 0 14px;}
.sign-screen .sign-intro{font-size:14px;max-width:470px;margin:0 auto 26px;}
.sign-screen .sign-contract{background:#F1F3F5;border:0;border-radius:10px;padding:16px 20px 18px;max-height:440px;overflow-y:auto;scrollbar-width:thin;}
.sign-contract-title{font-size:15px;font-weight:800;line-height:1.9;margin:2px 0 6px;color:var(--ink);white-space:pre-wrap;}
.sign-screen .sign-contract-text{font-size:14px;line-height:2.15;}
.sign-screen .btn.sign-primary{border-radius:6px;margin-top:0;padding:14px 16px;font-size:14.5px;}
.sign-back{margin:18px 0 6px;font-size:13.5px;}
.sign-back .linklike{color:var(--ink);font-weight:600;}
@media (max-width:560px){.sign-screen .sign-contract{max-height:60vh;}.sign-screen .sign-title{font-size:22px;}}

/* «درخواست تسهیلات» — a single field with a green «+» that opens the request
   form on its own page. */
.add-field{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;margin:4px 0 18px;padding:14px 18px;background:var(--paper-2);border:1px solid var(--line-2);border-radius:var(--r-md);font:inherit;font-size:15px;font-weight:700;color:var(--ink);cursor:pointer;text-align:right;transition:border-color .14s ease-in-out,box-shadow .14s ease-in-out;}
.add-field:hover{border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-bg);}
.add-field:focus-visible{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px var(--teal-bg);}
.add-field-plus{flex:0 0 auto;width:34px;height:34px;border-radius:50%;background:var(--teal);color:#fff;display:flex;align-items:center;justify-content:center;font-size:24px;font-weight:500;line-height:1;padding-bottom:2px;}
.add-field:hover .add-field-plus{background:#0E6340;}

/* داشبورد نمایندگی — «مشتریان در انتظار تحویل مدارک» as a numbered list whose
   rows open on the customer's name. */
.doc-row{padding:0 !important;overflow:hidden;}
.doc-row-head{display:flex;align-items:center;gap:10px;padding:12px 14px;cursor:pointer;}
.doc-row-head:hover{background:var(--paper);}
.doc-row.open .doc-row-head{background:var(--paper);border-bottom:1px solid var(--line);}
.doc-row-name{flex:1;min-width:0;}
.doc-row-side{display:flex;align-items:center;gap:10px;flex:0 0 auto;}
.doc-row-side .chev{color:var(--muted);font-size:11px;}
.doc-row-body{padding:12px 14px 14px;}
.rownum{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:26px;padding:0 6px;border-radius:8px;background:var(--brand-bg);color:var(--brand);font-size:12.5px;font-weight:700;flex:0 0 auto;}
td.rownum{display:table-cell;text-align:center;background:none;color:var(--muted);font-weight:600;}
@media (max-width:560px){.doc-row-side .meta{display:none;}}

/* «خروج از حساب» — the power symbol beside it, in every panel. */
.logout{display:inline-flex;align-items:center;gap:6px;}
.logout-icon{display:inline-flex;}
.logout-icon svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:2.1;}
.btn.logout .logout-icon svg{width:14px;height:14px;}

/* ---- ارتباط سریع (quick contact) -----------------------------------------
   Desktop: a round floating button in the corner. Phone: a full-width sticky
   bar at the bottom. Both open the same sheet, which rises from the bottom. */
.qc{position:fixed;inset:auto 0 0 auto;z-index:1200;direction:rtl;}
.qc-fab{position:fixed;left:24px;bottom:24px;width:58px;height:58px;border:0;border-radius:50%;background:var(--brand);color:var(--accent);display:flex;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 10px 26px rgba(6,42,58,.28);transition:transform .18s ease,box-shadow .18s ease;}
.qc-fab:hover{transform:translateY(-2px);box-shadow:0 14px 32px rgba(6,42,58,.32);}
.qc-fab svg{width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.qc-fab::after{content:"";position:absolute;inset:-6px;border-radius:50%;border:2px solid var(--accent);opacity:.55;animation:qc-pulse 2.4s ease-out infinite;}
@keyframes qc-pulse{0%{transform:scale(.85);opacity:.5;}70%{transform:scale(1.18);opacity:0;}100%{opacity:0;}}
.qc-bar{display:none;}
.qc-backdrop{position:fixed;inset:0;background:rgba(6,42,58,.45);border:0;}
.qc-sheet{position:fixed;left:24px;bottom:96px;width:340px;max-width:calc(100vw - 32px);background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:0 18px 44px rgba(6,42,58,.26);overflow:hidden;}
.qc-sheet-handle{display:none;}
.qc-sheet-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;padding:16px 18px 10px;}
.qc-sheet-title{font-size:16px;font-weight:800;color:var(--ink);}
.qc-sheet-desc{font-size:12.5px;color:var(--muted);margin-top:3px;}
.qc-close{background:none;border:0;font-size:24px;line-height:1;color:var(--muted);cursor:pointer;padding:0 2px;}
.qc-list{display:flex;flex-direction:column;padding:4px 10px 14px;}
.qc-item{display:flex;align-items:center;gap:12px;padding:11px 8px;border-radius:var(--r-md);color:var(--ink);text-decoration:none;}
.qc-item:hover{background:var(--paper);}
.qc-item-icon{flex:0 0 auto;width:40px;height:40px;border-radius:12px;background:var(--brand-bg);color:var(--brand);display:flex;align-items:center;justify-content:center;}
.qc-item-icon svg{width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;}
.qc-item-icon.qc-whatsapp{background:#DCF5E4;color:#128C4B;}
.qc-item-icon.qc-telegram{background:#DDEEFB;color:#1E88C9;}
.qc-item-icon.qc-bale{background:#E6E9FA;color:#3B49AF;}
.qc-item-icon.qc-location{background:#FDE9D9;color:#C2610F;}
.qc-item-text{flex:1;min-width:0;}
.qc-item-title{display:block;font-size:14px;font-weight:700;}
.qc-item-desc{display:block;font-size:12px;color:var(--muted);margin-top:2px;}
.qc-item-go{color:var(--muted);font-size:18px;}
.qc:not(.open) .qc-sheet,.qc:not(.open) .qc-backdrop{display:none;}
@media (max-width:780px){
  .qc-fab{display:none;}
  .qc-bar{display:flex;align-items:center;justify-content:center;gap:10px;position:fixed;inset:auto 0 0 0;width:100%;border:0;padding:14px 16px calc(14px + env(safe-area-inset-bottom));background:var(--brand);color:#fff;font:inherit;font-size:15px;font-weight:700;cursor:pointer;box-shadow:0 -6px 20px rgba(6,42,58,.22);}
  .qc-bar-icon{display:flex;}
  .qc-bar-icon svg{width:20px;height:20px;fill:none;stroke:var(--accent);stroke-width:1.9;}
  .qc-sheet{left:0;right:0;bottom:0;width:100%;max-width:none;border-radius:18px 18px 0 0;padding-bottom:env(safe-area-inset-bottom);}
  .qc-sheet-handle{display:block;width:44px;height:4px;border-radius:2px;background:var(--line-2);margin:8px auto 0;}
  .hp-footer{padding-bottom:78px;}
}
/* Room under the last panel so the sticky bar never covers it on a phone. */
.qc-spacer{display:none;}
@media (max-width:780px){.qc-spacer{display:block;height:68px;}}
