first
This commit is contained in:
commit
fa9d154db9
260 files changed
+17643
No files matched your search
@@ -0,0 +1 @@
|
||||
:root{font-family:Tahoma,Arial,sans-serif;color:#172033;background:#f4f7fb;line-height:1.7;--brand:#075985;--accent:#0ea5e9}*{box-sizing:border-box}body{margin:0}.top{height:68px;background:#fff;border-bottom:1px solid #e2e8f0;display:flex;align-items:center;justify-content:space-between;padding:0 max(20px,calc((100% - 1200px)/2));position:sticky;top:0;z-index:5}.brand{font-weight:800;color:var(--brand);font-size:1.15rem}.top nav{display:flex;gap:18px}.container{max-width:1200px;margin:30px auto;padding:0 18px}a{color:#0369a1;text-decoration:none}h1,h2,h3{line-height:1.35}.card{background:#fff;border:1px solid #e2e8f0;border-radius:16px;padding:22px;box-shadow:0 4px 18px #0f172a0a}.auth{max-width:470px;margin:8vh auto}.form-card{max-width:760px;margin:auto}.muted{color:#64748b}.page-head{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-bottom:22px}.button,button{display:inline-block;background:var(--brand);color:#fff;border:0;border-radius:10px;padding:10px 18px;font:inherit;cursor:pointer}button:disabled{opacity:.45;cursor:not-allowed}label{font-weight:700;display:block;margin-bottom:5px}input,textarea,select{width:100%;border:1px solid #cbd5e1;border-radius:9px;padding:10px 12px;font:inherit;background:#fff}textarea{min-height:120px}.errorlist{color:#b91c1c}.flash{padding:12px;border-radius:9px;background:#dbeafe;margin-bottom:15px}.flash.error{background:#fee2e2}.ticket-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}.ticket{display:flex;flex-direction:column;gap:7px;color:inherit}.ticket h2{font-size:1.05rem;margin:0}.badge{background:#e0f2fe;color:#075985;border-radius:999px;padding:3px 10px;display:inline-block;font-size:.82rem}.priority-urgent{background:#fee2e2;color:#991b1b}.priority-important{background:#fef3c7;color:#92400e}.empty{text-align:center;padding:70px 20px;background:#fff;border-radius:16px}.staff-list{display:grid;gap:10px}.staff-list .ticket{flex-direction:row;align-items:center;justify-content:space-between}.search{display:flex;gap:8px;max-width:600px}.staff-layout{display:grid;grid-template-columns:230px minmax(0,1fr) 230px;gap:16px;align-items:start}.conversation{display:grid;gap:12px;max-height:62vh;overflow:auto}.message{background:#f1f5f9;border-radius:14px;padding:12px 16px;max-width:82%}.message.mine{background:#e0f2fe;margin-right:auto}.message.note{background:#fff7ed;border:1px dashed #fb923c;max-width:100%}.message header{display:flex;justify-content:space-between;gap:15px;font-size:.82rem}.message p{white-space:normal}.attachment{display:block;padding:6px;background:#ffffffaa;border-radius:6px;margin-top:6px}.composer{margin-top:14px}.mode{display:flex;gap:8px}.mode button{background:#e2e8f0;color:#334155}.mode button.active{background:var(--brand);color:#fff}.mode button.note-button{background:#c2410c}.voice{display:flex;align-items:center;gap:8px;margin:10px 0}dl{display:grid;grid-template-columns:auto 1fr;gap:7px}dd{margin:0;font-weight:bold}details{margin-top:15px}summary{cursor:pointer;font-weight:bold}@media(max-width:850px){.staff-layout{grid-template-columns:1fr}.page-head{align-items:stretch;flex-direction:column}.search{flex-direction:column}.staff-list .ticket{align-items:flex-start;flex-direction:column}.message{max-width:94%}.top{padding:0 15px}}
|
||||
@@ -0,0 +1,2 @@
|
||||
.dispatch-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:.7rem}.dispatch-metrics article{display:grid;gap:.25rem;border:1px solid #dce7ef;border-radius:1rem;background:#fff;padding:.9rem 1rem;box-shadow:0 12px 30px -28px #08376b}.dispatch-metrics small{color:#718698;font-size:.62rem}.dispatch-metrics b{color:#123e62;font-size:1.25rem}.dispatch-filter{display:grid;gap:.65rem;border-bottom:1px solid #e3ebf1;background:#f8fbfd;padding:.8rem}.dispatch-filter>div{display:grid;grid-template-columns:1fr 1fr;gap:.5rem}.dispatch-filter label{display:grid;gap:.25rem;color:#536d81;font-size:.58rem;font-weight:900}.dispatch-filter input,.dispatch-filter select{width:100%;min-height:2.35rem;border:1px solid #cbd9e5;border-radius:.6rem;background:#fff;padding:.45rem .55rem;color:#173f60;font-size:.62rem}.dispatch-filter footer{display:flex;align-items:center;gap:.5rem}.dispatch-filter button{min-height:2.35rem;flex:1;border:0;border-radius:.6rem;background:#0875aa;color:#fff;font-size:.62rem;font-weight:900}.dispatch-filter footer a{color:#647b8d;font-size:.58rem;font-weight:900}.dispatch-results{display:grid;max-height:34rem;overflow:auto}.operations-pagination{display:flex;align-items:center;justify-content:space-between;border-top:1px solid #e5edf3;padding:.7rem .8rem;color:#667e91;font-size:.6rem}.operations-pagination a{border-radius:.55rem;background:#e8f4fb;padding:.4rem .65rem;color:#0873a9;font-weight:900}
|
||||
@media(max-width:700px){.dispatch-metrics{display:flex;overflow-x:auto}.dispatch-metrics article{min-width:8.5rem}}
|
||||
@@ -0,0 +1,11 @@
|
||||
.dashboard{display:grid;grid-template-columns:260px minmax(0,1fr);gap:16px}.filters{position:sticky;top:88px}.tabs{display:grid;gap:6px;margin-bottom:18px}.tabs a{padding:7px;border-radius:8px}.tabs a:hover{background:#e0f2fe}.filter-form{display:grid;gap:10px}.check{display:flex;align-items:center;gap:8px}.check input{width:auto}.metrics{display:flex;flex-wrap:wrap;gap:8px}.metrics span{background:#fff;border:1px solid #e2e8f0;border-radius:9px;padding:5px 10px}.danger,.overdue{color:#b91c1c}.danger-button{background:#b91c1c;padding:6px 10px}.grant,.message-actions,.history-item{display:flex;gap:8px;align-items:center;justify-content:space-between;margin-top:8px}.history-item{align-items:flex-start;flex-direction:column;border-top:1px solid #e2e8f0;padding-top:8px}.message-actions{justify-content:flex-end;font-size:.85rem}.message-actions details{margin:0}button:focus,input:focus,textarea:focus,select:focus,a:focus{outline:3px solid #7dd3fc;outline-offset:2px}@media(max-width:850px){.dashboard{grid-template-columns:1fr}.filters{position:static}}
|
||||
/* Organizational operations pages */
|
||||
.operations-toolbar{display:grid;grid-template-columns:minmax(220px,2fr) repeat(2,minmax(150px,1fr)) auto;gap:.75rem;padding:1rem;border-bottom:1px solid var(--line,#e5e7eb)}
|
||||
.operations-toolbar input,.operations-toolbar select{min-height:44px;border:1px solid #d9e1e8;border-radius:10px;background:#fff;padding:.65rem .8rem}
|
||||
.operations-toolbar button{border:0;border-radius:10px;background:#176b54;color:#fff;padding:.65rem 1.2rem;font-weight:700}
|
||||
.operations-form-card{max-width:850px;margin-inline:auto;padding:1.2rem}
|
||||
.table-subtitle{display:block;margin-top:.3rem;color:#64748b;font-size:.76rem;max-width:320px;white-space:normal}
|
||||
.tag-chip{display:inline-block;margin:.15rem;padding:.18rem .48rem;border-radius:999px;background:#e7f5ef;color:#176b54;font-size:.75rem}
|
||||
.operations-metrics{grid-template-columns:repeat(5,minmax(120px,1fr));margin-bottom:1rem}
|
||||
.form-hint{direction:ltr;text-align:left;overflow-wrap:anywhere;padding:.7rem;border-radius:9px;background:#f3f6f8;color:#52677d;font-size:.75rem}
|
||||
@media (max-width:900px){.operations-toolbar{grid-template-columns:1fr}.operations-metrics{grid-template-columns:repeat(2,1fr)}.staff-mobile-dock{overflow-x:auto;justify-content:flex-start}.staff-mobile-dock>a,.staff-mobile-dock>form{min-width:74px;flex:0 0 auto}}
|
||||
@@ -0,0 +1,45 @@
|
||||
/* Staff organizational operations — intentionally scoped to avoid regressions. */
|
||||
.operations-page{display:grid;gap:1rem;min-width:0}
|
||||
.operations-page .staff-page-head{margin-bottom:0}
|
||||
.operations-page .ticket-stream,.operations-page .filters{border:1px solid #d9e4ee;background:#fff;box-shadow:0 18px 45px -38px rgba(8,55,107,.55)}
|
||||
.operations-page .ticket-stream{border-radius:1rem;overflow:hidden}
|
||||
.operations-page .filters{border-radius:1rem;padding:1rem}
|
||||
.operations-page .stream-head{min-height:4.5rem;padding:1rem 1.15rem;border-bottom:1px solid #e5edf4;background:linear-gradient(135deg,#fff,#f6fbff)}
|
||||
.operations-page .filter-form{display:grid;gap:.9rem}
|
||||
.operations-page .filter-form label{display:grid;gap:.4rem;color:#294762;font-size:.75rem;font-weight:800}
|
||||
.operations-page .filter-form input,.operations-page .filter-form select,.operations-page .filter-form textarea{width:100%;min-height:2.9rem;border:1px solid #cbd9e5;border-radius:.75rem;background:#fff;padding:.68rem .8rem;color:#143552;box-shadow:0 1px 2px rgba(8,55,107,.03)}
|
||||
.operations-page .filter-form textarea{min-height:9rem;resize:vertical;line-height:1.9}
|
||||
.operations-page .filter-form select[multiple]{min-height:8rem}
|
||||
.operations-page .filter-form button,.operations-toolbar button{min-height:2.9rem;border:0;border-radius:.75rem;background:linear-gradient(135deg,#087dc1,#075a94);color:#fff;padding:.7rem 1.1rem;font-weight:900;box-shadow:0 10px 24px -16px #075a94}
|
||||
.operations-toolbar{display:grid;grid-template-columns:minmax(220px,1fr) auto;gap:.75rem;padding:1rem;border-bottom:1px solid #e5edf4;background:#f9fcff}
|
||||
.operations-toolbar input,.operations-toolbar select{min-height:2.8rem;border:1px solid #cbd9e5;border-radius:.75rem;background:#fff;padding:.65rem .8rem}
|
||||
.operations-page .table-scroll{overflow:auto;scrollbar-width:thin}
|
||||
.operations-page table{width:100%;border-collapse:separate;border-spacing:0;min-width:820px}
|
||||
.operations-page th{position:sticky;top:0;z-index:1;background:#eef6fc;color:#35556f;font-size:.69rem;font-weight:900;text-align:right;white-space:nowrap;padding:.8rem .9rem;border-bottom:1px solid #d5e3ee}
|
||||
.operations-page td{padding:.85rem .9rem;border-bottom:1px solid #edf2f6;color:#243f56;font-size:.73rem;vertical-align:top;line-height:1.75}
|
||||
.operations-page tbody tr:hover td{background:#f8fcff}
|
||||
.operations-page td a{color:#0874b5;font-weight:900}
|
||||
.table-subtitle{display:block;margin-top:.2rem;color:#718598;font-size:.65rem;max-width:22rem;white-space:normal;line-height:1.65}
|
||||
.tag-chip,.status-pill{display:inline-flex;align-items:center;margin:.12rem;padding:.18rem .5rem;border-radius:999px;background:#e7f5ef;color:#176b54;font-size:.65rem;font-weight:800}
|
||||
.status-pill.is-danger{background:#fff0f0;color:#b42318}.status-pill.is-muted{background:#eef2f5;color:#627586}.status-pill.is-success{background:#e5f7ef;color:#08734e}
|
||||
.view-counter{display:inline-grid;place-items:center;min-width:2rem;height:2rem;border-radius:.65rem;background:#e5f4ff;color:#086ea9}
|
||||
.operations-metrics{grid-template-columns:repeat(5,minmax(110px,1fr));margin:0}
|
||||
.operations-metrics .stat-card{min-height:7rem}
|
||||
.operations-page .empty-state{text-align:center;padding:2.5rem;color:#73879a}
|
||||
.operations-form-card{max-width:860px;width:100%;margin-inline:auto;padding:1.2rem}
|
||||
.form-hint{direction:ltr;text-align:left;overflow-wrap:anywhere;padding:.7rem;border-radius:.65rem;background:#f3f6f8;color:#52677d;font-size:.65rem}
|
||||
@media(max-width:1000px){.operations-page .dashboard{grid-template-columns:1fr}.operations-page .filters{position:static}.operations-metrics{grid-template-columns:repeat(3,1fr)}}
|
||||
@media(max-width:640px){.operations-page{gap:.75rem}.operations-toolbar{grid-template-columns:1fr;padding:.75rem}.operations-metrics{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;padding-bottom:.35rem}.operations-metrics .stat-card{min-width:9rem;scroll-snap-align:start}.operations-page .ticket-stream,.operations-page .filters{border-radius:.8rem}.operations-page td,.operations-page th{padding:.7rem}.staff-mobile-dock{overflow-x:auto;justify-content:flex-start}.staff-mobile-dock>a,.staff-mobile-dock>form{min-width:74px;flex:0 0 auto}}
|
||||
|
||||
/* Unified visual language for the staff operations suite. */
|
||||
.operations-hero{position:relative;display:flex;align-items:center;justify-content:space-between;gap:2rem;overflow:hidden;border:1px solid rgba(255,255,255,.1);border-radius:1.25rem;background:linear-gradient(125deg,#082f55 0%,#0a5684 62%,#087c94 100%);padding:1.55rem 1.75rem;color:#fff;box-shadow:0 22px 48px -32px rgba(8,47,85,.8)}
|
||||
.operations-hero:after{position:absolute;left:-4rem;top:-6rem;width:17rem;height:17rem;border-radius:50%;background:rgba(77,208,225,.12);content:""}.operations-hero>div{position:relative;z-index:1}.operations-hero .eyebrow{margin:0 0 .35rem;color:#8de3e8;font-size:.7rem;font-weight:900;letter-spacing:.06em}.operations-hero h1{margin:0;font-size:1.7rem;line-height:1.5}.operations-hero p:last-child{max-width:48rem;margin:.35rem 0 0;color:rgba(255,255,255,.68);font-size:.78rem;line-height:1.9}.operations-hero-actions{display:flex;align-items:center;gap:.65rem;flex:none}.operations-hero-actions .button{min-height:2.75rem;border-color:rgba(255,255,255,.28);background:#fff;color:#0a426c;box-shadow:none}.operations-hero-actions .button-secondary{background:rgba(255,255,255,.09);color:#fff}.security-callout,.template-guide{display:flex;align-items:center;gap:.7rem;flex:none;border:1px solid rgba(255,255,255,.18);border-radius:1rem;background:rgba(255,255,255,.09);padding:.7rem .9rem;backdrop-filter:blur(8px)}.security-callout>span,.template-guide>span{display:grid;width:2.2rem;height:2.2rem;place-items:center;border-radius:.7rem;background:#8de3e8;color:#083b5d;font-weight:900}.security-callout b,.security-callout small,.template-guide b,.template-guide small{display:block}.security-callout b,.template-guide b{font-size:.7rem}.security-callout small,.template-guide small{margin-top:.15rem;color:rgba(255,255,255,.62);font-size:.58rem}
|
||||
.operations-kpis{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:.7rem}.operations-kpis.compact{grid-template-columns:repeat(3,minmax(0,1fr));max-width:50rem}.operations-kpis article{display:flex;align-items:center;gap:.7rem;min-width:0;border:1px solid #dce7ef;border-radius:1rem;background:#fff;padding:.85rem 1rem;box-shadow:0 12px 30px -28px #08376b}.operations-kpis b,.operations-kpis small{display:block}.operations-kpis b{color:#123e62;font-size:1.25rem;line-height:1}.operations-kpis small{margin-top:.3rem;color:#6f8496;font-size:.62rem;white-space:nowrap}.kpi-icon{display:grid;width:2.4rem;height:2.4rem;flex:none;place-items:center;border-radius:.75rem;background:#e6f6ef;color:#087454;font-weight:900}.kpi-icon.is-blue{background:#e6f4ff;color:#0875b5}.kpi-icon.is-amber{background:#fff4d8;color:#a76b00}.kpi-icon.is-violet{background:#f1eaff;color:#6941c6}.kpi-icon.is-coral{background:#fff0ec;color:#c84d32}
|
||||
.operations-panel{overflow:hidden;border:1px solid #dce7ef;border-radius:1.1rem;background:#fff;box-shadow:0 18px 45px -38px rgba(8,55,107,.65)}.contact-filter-bar{display:grid;grid-template-columns:minmax(230px,1.7fr) repeat(3,minmax(135px,.8fr)) auto auto;align-items:end;gap:.65rem;padding:1rem;background:linear-gradient(135deg,#f6fbff,#fff);border-bottom:1px solid #e3ecf3}.contact-filter-bar label{display:grid;gap:.35rem;color:#526b80;font-size:.63rem;font-weight:800}.contact-filter-bar input,.contact-filter-bar select{width:100%;min-height:2.65rem;border:1px solid #cbd9e5;border-radius:.7rem;background:#fff;padding:.6rem .7rem;color:#163d5d}.contact-search{position:relative}.contact-search>span{position:absolute;right:.75rem;bottom:.65rem;color:#2588bd;font-size:1rem}.contact-search input{padding-right:2.2rem}.contact-filter-bar button{min-height:2.65rem;border:0;border-radius:.7rem;background:#0a6ea7;padding:.6rem 1rem;color:#fff;font-size:.7rem;font-weight:900}.filter-reset{display:grid;min-height:2.65rem;place-items:center;color:#64798c;font-size:.65rem;font-weight:800}.contact-result-meta{display:flex;align-items:center;justify-content:space-between;padding:.85rem 1.1rem;border-bottom:1px solid #e8eff4}.contact-result-meta b,.contact-result-meta small{display:block}.contact-result-meta b{color:#173f61;font-size:.75rem}.contact-result-meta small{margin-top:.15rem;color:#7a8e9e;font-size:.6rem}.contact-result-meta>a{color:#0875b5;font-size:.65rem;font-weight:900}
|
||||
.contact-card-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.8rem;padding:1rem;background:#f7fafc}.contact-card{display:grid;gap:.75rem;min-width:0;border:1px solid #dce7ef;border-radius:1rem;background:#fff;padding:1rem;transition:.18s ease;box-shadow:0 10px 28px -26px #08376b}.contact-card:hover{transform:translateY(-2px);border-color:#9dcbe2;box-shadow:0 18px 36px -29px #08376b}.contact-card header{display:flex;align-items:center;gap:.7rem}.contact-avatar{display:grid;width:2.65rem;height:2.65rem;flex:none;place-items:center;border-radius:.8rem;background:linear-gradient(145deg,#dff4ff,#dff7ef);color:#084d73;font-size:1rem;font-weight:900}.contact-identity{min-width:0;flex:1}.contact-identity h2{overflow:hidden;margin:0;color:#153f60;font-size:.88rem;text-overflow:ellipsis;white-space:nowrap}.contact-identity p{overflow:hidden;margin:.15rem 0 0;color:#718698;font-size:.63rem;text-overflow:ellipsis;white-space:nowrap}.contact-type{flex:none;border-radius:999px;background:#e7f4fb;padding:.2rem .48rem;color:#146b98;font-size:.57rem;font-weight:900}.contact-type.type-supplier{background:#fff3d8;color:#966000}.contact-type.type-carrier{background:#f0eaff;color:#6841b8}.contact-meta{display:flex;flex-wrap:wrap;gap:.4rem .9rem;color:#5f7689;font-size:.64rem}.contact-groups{display:flex;min-height:1.6rem;flex-wrap:wrap;gap:.3rem}.contact-groups span{border-radius:999px;background:#edf5f8;padding:.18rem .48rem;color:#49677c;font-size:.58rem;font-weight:800}.contact-groups small{color:#93a2ae;font-size:.6rem}.contact-ticket-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:.35rem}.contact-ticket-stats span{display:grid;gap:.1rem;border-radius:.6rem;background:#f3f6f8;padding:.45rem;text-align:center;color:#718394;font-size:.55rem}.contact-ticket-stats b{color:#173f60;font-size:.82rem}.contact-ticket-stats .needs-action{background:#fff5df;color:#916000}.contact-ticket-stats .needs-action b{color:#c37700}.contact-card footer{display:flex;align-items:center;justify-content:space-between;border-top:1px solid #edf2f5;padding-top:.7rem}.contact-card footer a{color:#557187;font-size:.64rem;font-weight:900}.contact-card footer .primary-action{border-radius:.6rem;background:#e8f6ff;padding:.4rem .65rem;color:#0875b5}.contact-empty{grid-column:1/-1}.contact-empty>span{display:grid;width:3rem;height:3rem;margin:0 auto .5rem;place-items:center;border-radius:1rem;background:#eaf5fb;color:#1679aa;font-size:1.3rem}
|
||||
.operations-split,.template-layout,.dispatch-layout{display:grid;grid-template-columns:minmax(0,1fr) 20rem;align-items:start;gap:1rem}.panel-heading{display:flex;align-items:center;justify-content:space-between;padding:1rem 1.1rem;border-bottom:1px solid #e5edf3;background:#f8fbfd}.panel-heading small{color:#74889a;font-size:.6rem}.panel-heading h2{margin:.15rem 0 0;color:#173f60;font-size:.95rem}.panel-heading>span{border-radius:999px;background:#e7f4fb;padding:.3rem .6rem;color:#126c9d;font-size:.6rem;font-weight:900}.group-card-list,.template-card-list{display:grid;gap:.55rem;padding:.8rem}.group-card,.template-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto auto;align-items:center;gap:.75rem;border:1px solid #e0e9ef;border-radius:.8rem;padding:.75rem;transition:.15s}.group-card:hover,.template-card:hover{border-color:#acd2e5;background:#fafdff}.group-symbol,.template-icon{display:grid;width:2.35rem;height:2.35rem;place-items:center;border-radius:.7rem;background:#e8f5fb;color:#0870a6;font-weight:900}.group-card h3,.template-card h3{margin:0;color:#173f60;font-size:.78rem}.group-card p,.template-card p{margin:.12rem 0;color:#667d90;font-size:.62rem}.group-card small,.template-card small{color:#8a9aa7;font-size:.56rem}.group-card>a,.template-card>a{color:#0875b5;font-size:.62rem;font-weight:900}.operations-form-side{overflow:hidden;border:1px solid #d8e4ec;border-radius:1rem;background:#fff;box-shadow:0 18px 40px -36px #08376b;position:sticky;top:5.6rem}.operations-form-side>header{display:flex;align-items:center;gap:.65rem;padding:1rem;background:linear-gradient(135deg,#0a4d78,#087b91);color:#fff}.operations-form-side>header>span{display:grid;width:2rem;height:2rem;place-items:center;border-radius:.6rem;background:rgba(255,255,255,.16);font-weight:900}.operations-form-side header small{font-size:.56rem;color:rgba(255,255,255,.65)}.operations-form-side header h2{margin:.12rem 0 0;font-size:.85rem}.operations-form{display:grid;gap:.75rem;padding:1rem}.operations-form label{display:grid;gap:.35rem}.operations-form label>span{color:#405e75;font-size:.65rem;font-weight:900}.operations-form input,.operations-form select,.operations-form textarea{width:100%;min-height:2.65rem;border:1px solid #c8d8e4;border-radius:.7rem;background:#fbfdff;padding:.6rem .7rem;color:#143e60}.operations-form textarea{min-height:6rem;resize:vertical}.operations-form button{min-height:2.75rem;border:0;border-radius:.7rem;background:linear-gradient(135deg,#0879b7,#075b8d);color:#fff;font-size:.7rem;font-weight:900}.operations-form>a{text-align:center;color:#6e8293;font-size:.62rem;font-weight:800}.operations-form .errorlist,.editor-section .errorlist,.dispatch-composer .errorlist{margin:0;padding:0;color:#b42318;font-size:.6rem;list-style:none}
|
||||
.contact-editor,.dispatch-composer{display:grid;gap:.85rem}.contact-editor{max-width:58rem;width:100%;margin-inline:auto}.editor-section,.dispatch-composer>section{overflow:hidden;border:1px solid #dbe6ee;border-radius:1rem;background:#fff;box-shadow:0 15px 38px -35px #08376b}.editor-section>header,.dispatch-composer>section>header{display:flex;align-items:center;gap:.7rem;border-bottom:1px solid #e8eef3;padding:.85rem 1rem;background:#f9fcfe}.editor-section>header>span,.dispatch-composer>section>header>span{display:grid;width:2rem;height:2rem;flex:none;place-items:center;border-radius:.65rem;background:linear-gradient(135deg,#0a699f,#098d9c);color:#fff;font-size:.7rem;font-weight:900}.editor-section h2,.dispatch-composer h2{margin:0;color:#173f60;font-size:.82rem}.editor-section header p,.dispatch-composer header p{margin:.15rem 0 0;color:#73889a;font-size:.6rem}.editor-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.8rem;padding:1rem}.editor-grid label,.group-selector,.message-editor{display:grid;align-content:start;gap:.35rem;color:#3f5f77;font-size:.65rem;font-weight:900}.editor-grid input,.editor-grid select,.group-selector select,.message-editor textarea{width:100%;min-height:2.75rem;border:1px solid #c8d8e4;border-radius:.72rem;background:#fbfdff;padding:.62rem .72rem;color:#123f61}.editor-grid input:focus,.editor-grid select:focus,.group-selector select:focus,.message-editor textarea:focus{border-color:#1689bd;outline:3px solid rgba(22,137,189,.11);background:#fff}.editor-grid small,.group-selector small{color:#7a8e9e;font-size:.56rem;font-weight:500}.editor-grid em,.group-selector em{color:#d05c3b;font-style:normal}.editor-wide{grid-column:1/-1}.group-selector,.message-editor{margin:1rem}.group-selector select{min-height:9rem}.location-status{margin:-.35rem 1rem .85rem;border-radius:.6rem;background:#edf7fc;padding:.55rem .7rem;color:#39708e;font-size:.58rem}.location-status.is-error{background:#fff0ed;color:#b04432}.editor-actions{display:flex;align-items:center;gap:.7rem;border:1px solid #d9e5ed;border-radius:1rem;background:#fff;padding:.8rem}.editor-actions button{min-height:2.75rem;border:0;border-radius:.7rem;background:linear-gradient(135deg,#0879b7,#075b8d);padding:.65rem 1.4rem;color:#fff;font-weight:900}.editor-actions a{color:#657d90;font-size:.65rem;font-weight:900}.editor-actions span{margin-right:auto;color:#8798a5;font-size:.58rem}
|
||||
.dispatch-composer>footer{display:flex;align-items:center;justify-content:space-between;gap:1rem;border:1px solid #d7e4ec;border-radius:1rem;background:#fff;padding:.9rem 1rem}.dispatch-composer footer b,.dispatch-composer footer small{display:block}.dispatch-composer footer b{color:#173f60;font-size:.68rem}.dispatch-composer footer small{margin-top:.18rem;color:#73889a;font-size:.56rem}.dispatch-composer footer button{min-height:2.8rem;border:0;border-radius:.72rem;background:linear-gradient(135deg,#0879b7,#087c86);padding:.65rem 1rem;color:#fff;font-size:.68rem;font-weight:900}.message-editor textarea{min-height:11rem;resize:vertical;line-height:1.9}.dispatch-history{overflow:hidden;border:1px solid #d8e4ec;border-radius:1rem;background:#fff;position:sticky;top:5.6rem}.dispatch-history>header{display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid #e5edf3;padding:1rem}.dispatch-history header small{color:#7b8d9d;font-size:.56rem}.dispatch-history header h2{margin:.12rem 0 0;color:#173f60;font-size:.88rem}.dispatch-history header>span{display:grid;width:2rem;height:2rem;place-items:center;border-radius:.65rem;background:#e8f4fb;color:#0873a9;font-size:.65rem;font-weight:900}.dispatch-history>div{display:grid;max-height:39rem;overflow:auto}.dispatch-history-card{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:.55rem;border-bottom:1px solid #edf2f5;padding:.75rem;color:inherit}.dispatch-history-card:hover{background:#f7fbfd}.dispatch-state{width:.5rem;height:.5rem;border-radius:50%;background:#8da0ae}.dispatch-state.state-sent{background:#12a36d}.dispatch-state.state-queued{background:#e19b18}.dispatch-state.state-partial{background:#dc5c42}.dispatch-history-card b{display:block;overflow:hidden;color:#24485f;font-size:.68rem;text-overflow:ellipsis;white-space:nowrap}.dispatch-history-card small{display:block;margin-top:.15rem;color:#718698;font-size:.56rem}.dispatch-history-card p{display:flex;gap:.6rem;margin:.35rem 0 0;color:#8798a5;font-size:.52rem}.dispatch-history-card em{color:#8aa0b0;font-style:normal}
|
||||
.template-card-list{max-height:44rem;overflow:auto}.variable-box{border:1px dashed #b9cedb;border-radius:.7rem;background:#f7fbfd;padding:.7rem}.variable-box>b{display:block;margin-bottom:.45rem;color:#3e6077;font-size:.62rem}.variable-box>div{display:flex;flex-wrap:wrap;gap:.3rem}.variable-box code{border-radius:.35rem;background:#e7f3f9;padding:.18rem .35rem;color:#075e8d;font-size:.53rem}
|
||||
@media(max-width:1100px){.operations-kpis{grid-template-columns:repeat(3,1fr)}.contact-filter-bar{grid-template-columns:repeat(2,minmax(0,1fr))}.contact-search{grid-column:1/-1}.operations-split,.template-layout,.dispatch-layout{grid-template-columns:1fr}.operations-form-side,.dispatch-history{position:static}.dispatch-history>div,.template-card-list{max-height:none}}
|
||||
@media(max-width:700px){.operations-hero{align-items:stretch;flex-direction:column;padding:1.1rem}.operations-hero h1{font-size:1.3rem}.operations-hero-actions{align-items:stretch;flex-direction:column}.security-callout,.template-guide{align-self:stretch}.operations-kpis,.operations-kpis.compact{display:flex;max-width:none;overflow-x:auto;padding-bottom:.25rem}.operations-kpis article{min-width:9rem}.contact-filter-bar{grid-template-columns:1fr}.contact-search{grid-column:auto}.contact-card-grid{grid-template-columns:1fr;padding:.65rem}.contact-result-meta{align-items:flex-start;flex-direction:column;gap:.4rem}.editor-grid{grid-template-columns:1fr;padding:.8rem}.editor-wide{grid-column:auto}.editor-actions,.dispatch-composer>footer{align-items:stretch;flex-direction:column}.editor-actions span{margin:0}.group-card,.template-card{grid-template-columns:auto minmax(0,1fr) auto}.group-card .status-pill,.template-card .status-pill{grid-column:2}.group-card>a,.template-card>a{grid-column:3;grid-row:1/3}.contact-ticket-stats{grid-template-columns:repeat(2,1fr)}}
|
||||
@@ -0,0 +1,2 @@
|
||||
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
||||
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-tracking:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:Vazirmatn,ui-sans-serif,system-ui;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-800:oklch(47.3% .137 46.201);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-800:oklch(43.2% .095 166.913);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-400:oklch(70.4% .04 256.788);--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--container-xl:36rem;--container-2xl:42rem;--container-5xl:64rem;--container-6xl:72rem;--container-7xl:80rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--text-5xl:3rem;--text-5xl--line-height:1;--font-weight-normal:400;--font-weight-medium:500;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--animate-ping:ping 1s cubic-bezier(0, 0, .2, 1) infinite;--blur-sm:8px;--blur-xl:24px;--blur-2xl:40px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-ink:#08376b;--color-ink-soft:#0b4c8c;--color-cream:#eee;--color-soft:#eaeaea;--color-paper:#fff;--color-sea:#0693e3;--color-sea-dark:#1977ce;--color-blue:#1977ce;--color-mint:#e5f4ff;--color-coral:#fa9f00;--color-sun:#ffc451}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--defLine truncated
|
||||
@@ -0,0 +1,7 @@
|
||||
.intent-finder{display:flex;gap:14px;padding:20px;margin-bottom:20px;border:1px solid #bae6fd;border-radius:20px;background:linear-gradient(135deg,#f0f9ff,#ecfdf5)}
|
||||
.intent-icon{width:46px;height:46px;flex:0 0 46px;display:grid;place-items:center;border-radius:14px;background:#075985;color:#fff;font-size:1.6rem}
|
||||
.intent-copy{min-width:0;flex:1}.intent-copy h2{margin:0 0 4px;font-size:1.15rem}.intent-copy p{margin:0 0 12px;color:#52677d}
|
||||
.intent-search{display:flex;align-items:center;background:#fff;border:2px solid #cbd5e1;border-radius:14px;padding:3px 12px}.intent-search:focus-within{border-color:#0284c7;box-shadow:0 0 0 3px #bae6fd}.intent-search input{border:0!important;box-shadow:none!important;margin:0;min-height:46px;flex:1}.intent-search kbd{color:#64748b;font:inherit;font-size:.75rem}
|
||||
.intent-results{display:grid;gap:8px;margin-top:10px}.intent-result{display:grid;grid-template-columns:1fr auto;gap:3px 10px;text-align:right;padding:11px 13px;border:1px solid #dbeafe;border-radius:12px;background:#fff;color:#0f172a}.intent-result:hover{border-color:#0284c7;background:#f8fdff}.intent-result span{color:#0369a1;font-size:.8rem}.intent-result small{grid-column:1/-1;color:#64748b}.intent-message{margin:8px 2px!important;font-size:.85rem}
|
||||
.manual-routing{border:1px solid #e2e8f0;border-radius:16px;margin-bottom:22px;overflow:hidden}.manual-routing summary{cursor:pointer;padding:14px 16px;background:#f8fafc;display:flex;justify-content:space-between;gap:8px}.manual-routing summary small{color:#64748b}.manual-routing-body{padding:18px}.routing-selectors{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.routing-selectors .field{min-width:0;margin-bottom:8px}.routing-subject{margin-bottom:0}.routing-subject small{display:block;margin-top:6px;color:#64748b;font-weight:500}.location-fields select{width:100%;min-height:48px;background:#fff}.submit-ticket{position:sticky;bottom:calc(8px + env(safe-area-inset-bottom));z-index:5}.request-form{min-width:0}
|
||||
@media(max-width:640px){.request-layout{display:block}.request-aside{display:none}.request-form.card{padding:14px;border-radius:18px}.intent-finder{padding:14px;gap:10px}.intent-icon{width:40px;height:40px;flex-basis:40px}.intent-search kbd{display:none}.manual-routing summary{display:block}.manual-routing summary small{display:block;margin-top:4px}.manual-routing-body{padding:14px}.routing-selectors{gap:8px}.routing-selectors select{padding-inline:10px}.expert-picker{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.expert-card{padding:11px}.expert-card img,.expert-avatar{width:56px;height:56px}.step-title{margin-top:24px}.upload-zone{padding:12px}}
|
||||
@@ -0,0 +1 @@
|
||||
.field{margin-bottom:18px}.expert-picker{border:0;padding:0;margin:22px 0;display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:12px}.expert-picker legend{font-weight:700;margin-bottom:10px}.expert-card{position:relative;border:2px solid #e2e8f0;border-radius:14px;padding:15px;display:flex;flex-direction:column;align-items:center;text-align:center;cursor:pointer;transition:.2s}.expert-card:has(input:checked){border-color:#0284c7;background:#f0f9ff;box-shadow:0 0 0 3px #bae6fd}.expert-card input{position:absolute;opacity:0}.expert-card img,.expert-avatar{width:72px;height:72px;border-radius:50%;object-fit:cover;margin-bottom:8px;background:#e0f2fe;display:grid;place-items:center;font-size:2rem;color:#075985}.expert-card small{color:#64748b}.expert-empty{grid-column:1/-1}.upload-zone{border:2px dashed #94a3b8;border-radius:14px;padding:18px;margin:18px 0;background:#f8fafc}.upload-zone>label{cursor:pointer;color:#0369a1}.file-preview{display:grid;grid-template-columns:repeat(auto-fill,minmax(135px,1fr));gap:10px;margin-top:12px}.file-chip{position:relative;background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:8px;overflow:hidden}.file-chip img{width:100%;height:90px;object-fit:cover;border-radius:7px}.file-chip button{position:absolute;top:3px;left:3px;padding:2px 7px;background:#b91c1c}.file-chip small{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.voice-recorder{border-radius:14px;padding:16px;background:#eff6ff;border:1px solid #bfdbfe;margin:18px 0}.voice-head,.voice-actions{display:flex;align-items:center;justify-content:space-between;gap:8px}.voice-actions{justify-content:flex-start;margin:12px 0;flex-wrap:wrap}.ghost{background:#fff;color:#b91c1c;border:1px solid #fecaca}.submit-ticket{width:100%;font-weight:700;font-size:1.05rem}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Iran location data
|
||||
|
||||
The province and city names in `iran-locations.json` were derived from
|
||||
[`sajaddp/list-of-cities-in-Iran`](https://github.com/sajaddp/list-of-cities-in-Iran),
|
||||
which is distributed under the GNU General Public License v3.0.
|
||||
|
||||
The upstream dataset states that it is based on Iran's official administrative
|
||||
divisions through 1402 (2023). The local file contains only province names and
|
||||
the upstream `cities-filtered.json` city names, grouped by province.
|
||||
@@ -0,0 +1 @@
|
||||
[{"province":"آذربایجان شرقی","cities":["آذرشهر","آقکند","اچاچی","اربطان","اسفهلان","اسکو","اهر","ایلخچی","باسمنج","بخشایش","بناب","تبریز","تبریز1","تبریز2","تبریز3","تبریز4","تبریز5","تبریز6","تبریز7","تبریز8","ترک","ترکمانچای","تسوج","تیمورلو","جلفا","خاروانا","خامنه","خداجوخراجو","خسروشاه","خمارلو","خواجه","داریان","دوزدوزان","زرنق","زنوز","سراب","سردرود","سهند","سیس","شبستر","شربیان","شرفخانه","شندآباد","صوفیان","عاشقلو","علیشاه","کردکندی","کشکسرای","کلوانق","کلیبر","گوگان","لاریجان","لاهیجان","لیلان","مراغه","مرند","ملکان","ممقان","مهربان","میانه","نظرکهریزی","هادیشهر","هریس","هشترود","هوراند","وایقان","ورزقان","یامچی"]},{"province":"آذربایجان غربی","cities":["آواجیق","ارومیه","اشنویه","ایواوغلی","باروق","بازرگان","بکتاش","بوکان","پلدشت","پیرانشهر","تکاب","چهاربرج","حاجیلار","خلیفان","خوی","ربط","زرآباد","سردشت","سرو","سلماس","سیلوانه","سیمینه","شوط","فیرورق","قطور","قوشچی","کشاورز","لاجان","ماکو","محمدیار","محمودآباد","مرگنلر","مهاباد","میاندوآب","میرآباد","نالوس","نقده","نلاس","نوشین","یولاگلدی"]},{"province":"اردبیل","cities":["آراللو","اردبیل","اردیموسی","اصلاندوز","النی","اولتان","ثمرین","جعفرآباد","خلخال","رضی","زهرا","زیوه","سرعین","عنبران","فخراباد","فیروزآباد","قصابه","کلور","کوراییم","گرمی","گیوی","لاهرود","مرادلو","نمین","نیر","هشتجین","هیر"]},{"province":"اصفهان","cities":["ابریشم","ابوزیدآباد","اردستان","اژیه","اشترجان","اصغرآباد","اصفهان","افوس","انارک","بادرود","باغشاد","بافران","برزک","بهارستان","بیده","پیربکران","تودشک","تیران","جندق","جوزدان","چادگان","چرمهین","چمگردان","حنا","خالدآباد","خوانسار","خور","خورزوق","داران","دامنه","درچه","دستگرد","دهاقان","دهق","دیزیچه","رزوه","رضوانشهر","زازران","زواره","زیار","زیباشهر","سجزی","سمیرم","سین","شاپورآباد","شهرضا","طاد","طالخونچه","عسگران","علویجه","فرخی","فریدونشهر","فلاورجان","فولادشهر","قمصر","قهجاورستان","قهدریجان","کاشان","کرکوند","کمشچه","کمه","کهریزسنگ","کوشک","کوهپایه","گرگاب","گزبرخوار","گلپایگان","گلدشت","گلشن","گلشهر","گوگد","مبارکه","مجلسی","محمدآباد","مشکات","منظریه","مهاباد","میمه","مینادشت","نایین","نصرآباد","نطنز","نیاسر","هرند","ورزنه","ورنامخواست","وزوان","ونک","ویست"]},{"province":"البرز","cities":["آسارا","اشتهارد","تنکمان","چهارباغ","طالقان","فردیس","کرج","کوهسار","گرمدره","گلسار","ماهدشت","مهستان","نظرآباد","هشتگرد"]},{"province":"ایلام","cities":["آبدانان","ارکواز","ایلام","ایوان","بدره","بلاوه","پهله","توحید","جعفراباد","چوار","دلگشا","دهلران","زرنه","سرابله","شباب","لومار","ماژین","مهر","مهران","مورموری","موسیان","میمه"]},{"province":"بوشهر","cities":["آباد","آبدان","انارستان","اهرم","بادوله","برازجان","بردخون","بردستان","بندردیر","بندردیلم","بندرریگ","بندرکنگان","بندرگناوه","بنک","بهارستان","بوشکان","بوشهر","بوشهر1","بوشهر2","بیدخون","جم","چغادک","خارک","خورموج","دالکی","دلوار","دوراهک","ریز","سیراف","شبانکاره","شنبه","شیرینو","عسلویه","کاکی","کلمه","وحدتیه"]},{"province":"تهران","cities":["آبسرد","آبعلی","ارجمند","اسلامشهر","اندیشه","باغستان","باقرشهر","بومهن","پاکدشت","پردیس","پرند","پیشوا","تجریش","تهران","جوادآباد","چهاردانگه","خسرواباد","دماوند","رباطکریم","رودهن","ری","سعیداباد","شاهدشهر","شمشک","شهریار","شهریار1","شهریار2","شهریار3","صالحیه","صباشهLine truncated
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
@@ -0,0 +1,18 @@
|
||||
document.querySelectorAll('[data-ticket-composer]').forEach(form=>{
|
||||
const canonical=form.querySelector('input[name="files"]'),preview=form.querySelector('[data-file-preview]');
|
||||
if(!canonical||!preview)return;
|
||||
canonical.classList.add('canonical-file-input');
|
||||
let files=[];
|
||||
const status=form.querySelector('[data-compression-status]');
|
||||
const compress=file=>new Promise(resolve=>{
|
||||
if(!file.type.startsWith('image/')||file.type==='image/gif'||typeof Compressor==='undefined')return resolve(file);
|
||||
new Compressor(file,{quality:.76,maxWidth:1920,maxHeight:1920,convertSize:1500000,success(blob){const ext=blob.type==='image/jpeg'?'.jpg':file.name.match(/\.[^.]+$/)?.[0]||'.jpg';resolve(new File([blob],file.name.replace(/\.[^.]+$/,ext),{type:blob.type,lastModified:Date.now()}))},error(){resolve(file)}});
|
||||
});
|
||||
const sync=()=>{const dt=new DataTransfer();files.forEach(file=>dt.items.add(file));canonical.files=dt.files;preview.replaceChildren();files.forEach((file,index)=>{const item=document.createElement('div');item.className='file-chip';if(file.type.startsWith('image/')){const img=document.createElement('img');const url=URL.createObjectURL(file);img.src=url;img.onload=()=>URL.revokeObjectURL(url);item.appendChild(img)}const name=document.createElement('small');name.textContent=`${file.name} · ${(file.size/1024/1024).toFixed(1)} MB`;item.appendChild(name);const remove=document.createElement('button');remove.type='button';remove.textContent='×';remove.setAttribute('aria-label','حذف فایل');remove.onclick=()=>{files.splice(index,1);sync()};item.appendChild(remove);preview.appendChild(item)})};
|
||||
const add=async selected=>{if(status)status.textContent='در حال بهینهسازی تصاویر…';const prepared=await Promise.all(Array.from(selected).map(compress));files=[...files,...prepared];sync();if(status)status.textContent='تصاویر آماده ارسال هستند؛ نسخه اصلی روی گوشی شما تغییری نکرده است.'};
|
||||
form.querySelectorAll('[data-gallery-input],[data-document-input]').forEach(input=>input.addEventListener('change',async()=>{await add(input.files);input.value=''}));
|
||||
canonical.addEventListener('change',async()=>{if(canonical.dataset.syncing)return;const selected=Array.from(canonical.files);canonical.value='';await add(selected)});
|
||||
form.addEventListener('voice-added',event=>{files=[...files,event.detail];sync()});
|
||||
form.addEventListener('voice-removed',event=>{files=files.filter(file=>file!==event.detail);sync()});
|
||||
form.addEventListener('submit',()=>form.querySelectorAll('button[type=submit],button:not([type])').forEach(button=>button.disabled=true));
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
document.querySelectorAll('form[data-chat-coach]').forEach(form=>{
|
||||
const input=form.querySelector('textarea[name="body"]');
|
||||
if(!input)return;
|
||||
const rapidWindowMs=2*60*1000;
|
||||
const autoDismissMs=3000;
|
||||
let dismissed=false;
|
||||
let dismissTimer=null;
|
||||
|
||||
const readLastTwoMessageTimes=()=>Array.from(document.querySelectorAll('[data-chat-coach-own][data-chat-coach-at]'))
|
||||
.map(node=>Number(node.dataset.chatCoachAt)*1000)
|
||||
.filter(Number.isFinite)
|
||||
.sort((a,b)=>a-b)
|
||||
.slice(-2);
|
||||
|
||||
const hint=document.createElement('aside');
|
||||
hint.className='chat-coach chat-coach-floating';hint.hidden=true;hint.setAttribute('role','status');hint.setAttribute('aria-live','polite');
|
||||
hint.innerHTML='<span class="chat-coach-icon" aria-hidden="true">✦</span><div><b>برای دریافت پاسخ دقیقتر</b><p>لطفاً همه توضیحات و سؤالهای خود را در یک پیام کامل بنویسید و سپس ارسال کنید.</p></div><button type="button" data-chat-coach-dismiss aria-label="بستن راهنما" title="بستن">×</button>';
|
||||
document.body.append(hint);
|
||||
|
||||
const dismiss=({focusInput=false}={})=>{
|
||||
dismissed=true;
|
||||
hint.hidden=true;
|
||||
if(dismissTimer)clearTimeout(dismissTimer);
|
||||
dismissTimer=null;
|
||||
if(focusInput)input.focus();
|
||||
};
|
||||
const showTemporarily=()=>{
|
||||
if(!hint.hidden)return;
|
||||
hint.hidden=false;
|
||||
dismissTimer=setTimeout(()=>dismiss(),autoDismissMs);
|
||||
};
|
||||
const detect=()=>{
|
||||
const [previous,last]=readLastTwoMessageTimes();
|
||||
const rapidPair=Number.isFinite(previous)&&Number.isFinite(last)&&last>=previous&&last-previous<=rapidWindowMs;
|
||||
if(!dismissed&&rapidPair)showTemporarily();
|
||||
else if(!rapidPair)hint.hidden=true;
|
||||
};
|
||||
hint.querySelector('[data-chat-coach-dismiss]').addEventListener('click',()=>dismiss({focusInput:true}));
|
||||
const conversation=document.querySelector('[data-conversation]');
|
||||
if(conversation)new MutationObserver(detect).observe(conversation,{childList:true,subtree:true});
|
||||
detect();
|
||||
});
|
||||
@@ -0,0 +1,132 @@
|
||||
document.querySelectorAll('[data-conversation-workspace]').forEach(workspace=>{
|
||||
const scroller=workspace.querySelector('[data-conversation]');
|
||||
const conversationEnd=workspace.querySelector('[data-conversation-end]');
|
||||
const jump=workspace.querySelector('[data-jump-latest]');
|
||||
const form=workspace.querySelector('[data-ticket-composer]');
|
||||
const input=form?.querySelector('textarea');
|
||||
const composer=workspace.querySelector('[data-composer-shell]');
|
||||
const composerToggle=workspace.querySelector('[data-composer-toggle]');
|
||||
const baseKey=workspace.dataset.draftKey||location.pathname;
|
||||
let mode='reply';
|
||||
|
||||
const atBottom=()=>scroller.scrollHeight-scroller.scrollTop-scroller.clientHeight<80;
|
||||
const scrollLatest=(smooth=false)=>{const top=scroller.scrollHeight;if(smooth&&typeof scroller.scrollTo==='function')scroller.scrollTo({top,behavior:'smooth'});else scroller.scrollTop=top};
|
||||
let initialPin=true;
|
||||
const scheduleLatest=()=>{[0,40,120,300,700,1200].forEach(delay=>setTimeout(()=>{if(initialPin)scrollLatest(false)},delay))};
|
||||
scheduleLatest();
|
||||
window.addEventListener('load',scheduleLatest,{once:true});
|
||||
window.addEventListener('pageshow',scheduleLatest);
|
||||
document.fonts?.ready?.then(scheduleLatest);
|
||||
scroller.querySelectorAll('img,audio').forEach(media=>{const event=media.tagName==='IMG'?'load':'loadedmetadata';media.addEventListener(event,()=>{if(initialPin)scrollLatest(false)},{once:true})});
|
||||
const sizeObserver='ResizeObserver' in window?new ResizeObserver(()=>{if(initialPin)scrollLatest(false)}):null;
|
||||
sizeObserver?.observe(scroller);if(conversationEnd?.parentElement)sizeObserver?.observe(conversationEnd.parentElement);
|
||||
setTimeout(()=>{initialPin=false;sizeObserver?.disconnect()},1800);
|
||||
['wheel','touchstart','pointerdown','keydown'].forEach(eventName=>scroller.addEventListener(eventName,()=>{initialPin=false;sizeObserver?.disconnect()},{once:true,passive:true}));
|
||||
scroller.addEventListener('scroll',()=>{jump.hidden=atBottom()});
|
||||
jump?.addEventListener('click',()=>{scrollLatest(true);jump.hidden=true});
|
||||
|
||||
const groupDates=()=>{scroller.querySelectorAll('.date-divider').forEach(item=>item.remove());let previousDate='';scroller.querySelectorAll('[data-message]').forEach(message=>{if(message.dataset.date!==previousDate){const divider=document.createElement('div');divider.className='date-divider';divider.innerHTML=`<span>${message.dataset.dayLabel}</span>`;message.before(divider);previousDate=message.dataset.date}})};
|
||||
groupDates();
|
||||
document.body.addEventListener('htmx:beforeSwap',event=>{if(event.detail.target?.matches('[data-load-older]')){scroller.dataset.previousHeight=scroller.scrollHeight}});
|
||||
document.body.addEventListener('htmx:afterSwap',event=>{if(event.detail.target?.matches('[data-load-older]')){const previous=Number(scroller.dataset.previousHeight||0);groupDates();scroller.scrollTop+=scroller.scrollHeight-previous}});
|
||||
|
||||
const resize=()=>{if(!input)return;input.style.height='auto';input.style.height=`${Math.min(Math.max(input.scrollHeight,112),240)}px`};
|
||||
const draftKey=()=>`${baseKey}-${mode}`;
|
||||
const status=workspace.querySelector('[data-draft-status]');
|
||||
const replyResult=workspace.dataset.replyResult||new URLSearchParams(location.search).get('reply_result')||'';
|
||||
const submissionSucceeded=replyResult==='reply'||replyResult==='note';
|
||||
if(submissionSucceeded){sessionStorage.removeItem(`${baseKey}-reply`);sessionStorage.removeItem(`${baseKey}-note`)}
|
||||
const setComposerOpen=(open,focus=true)=>{composer?.classList.toggle('is-collapsed',!open);composerToggle?.setAttribute('aria-expanded',String(open));if(open&&focus)setTimeout(()=>input?.focus(),80)};
|
||||
const saveDraft=()=>{if(!input)return;sessionStorage.setItem(draftKey(),input.value);if(status){status.textContent=input.value?'پیشنویس ذخیره شد':'';clearTimeout(saveDraft.timer);saveDraft.timer=setTimeout(()=>status.textContent='',1800)}};
|
||||
const loadDraft=()=>{if(!input)return;input.value=sessionStorage.getItem(draftKey())||'';resize();input.dispatchEvent(new Event('input',{bubbles:true}))};
|
||||
if(input){input.setAttribute('rows','5');input.setAttribute('placeholder','شرح کامل پاسخ، اطلاعات تکمیلی و نتیجه مورد انتظار خود را بنویسید…');input.addEventListener('input',()=>{resize();saveDraft()});loadDraft()}
|
||||
const hasDraft=Boolean(sessionStorage.getItem(`${baseKey}-reply`)||sessionStorage.getItem(`${baseKey}-note`));
|
||||
if(submissionSucceeded){form?.reset();if(input){input.value='';resize()}setComposerOpen(false,false)}else setComposerOpen(hasDraft||replyResult==='error',false);
|
||||
composerToggle?.addEventListener('click',()=>setComposerOpen(true));
|
||||
workspace.querySelectorAll('[data-composer-close]').forEach(button=>button.addEventListener('click',()=>setComposerOpen(false,false)));
|
||||
composer?.addEventListener('keydown',event=>{if(event.key==='Escape'){setComposerOpen(false,false);composerToggle?.focus()}});
|
||||
const primarySubmit=form?.querySelector('[data-primary-submit]');
|
||||
const guideToPrimarySubmit=event=>{event.preventDefault();event.stopPropagation();if(!primarySubmit)return;primarySubmit.scrollIntoView({behavior:'smooth',block:'center'});primarySubmit.classList.remove('submit-attention');void primarySubmit.offsetWidth;primarySubmit.classList.add('submit-attention');setTimeout(()=>primarySubmit.focus({preventScroll:true}),450)};
|
||||
workspace.querySelectorAll('[data-scroll-to-submit]').forEach(control=>{control.addEventListener('click',guideToPrimarySubmit);control.addEventListener('keydown',event=>{if(event.key==='Enter'||event.key===' '){guideToPrimarySubmit(event)}})});
|
||||
|
||||
workspace.querySelectorAll('[data-composer-mode]').forEach(button=>button.addEventListener('click',()=>{saveDraft();mode=button.dataset.composerMode;loadDraft();setTimeout(()=>input?.focus(),0)}));
|
||||
workspace.querySelector('[data-toggle-recorder]')?.addEventListener('click',()=>{const recorder=workspace.querySelector('[data-voice-recorder]');recorder.hidden=!recorder.hidden;if(!recorder.hidden)recorder.querySelector('[data-record]')?.focus()});
|
||||
workspace.querySelector('[data-toggle-extra]')?.addEventListener('click',()=>{const extra=workspace.querySelector('[data-composer-extra]');extra.hidden=!extra.hidden});
|
||||
form?.addEventListener('submit',()=>{form.dataset.submitting='true'});
|
||||
window.addEventListener('pageshow',()=>{if(submissionSucceeded){form?.reset();if(input){input.value='';resize()}setComposerOpen(false,false)}});
|
||||
|
||||
const pollUrl=workspace.dataset.pollUrl;
|
||||
const readUrl=workspace.dataset.readUrl;
|
||||
const pollInterval=3000;
|
||||
let pollController=null,pollRunning=false,pollGeneration=0,pollErrors=0,nextPollAt=0;
|
||||
let readRunning=false;
|
||||
const cookie=name=>document.cookie.split('; ').find(row=>row.startsWith(`${name}=`))?.split('=').slice(1).join('=')||'';
|
||||
const acknowledgeVisibleMessages=async()=>{
|
||||
if(!readUrl||readRunning||document.visibilityState!=='visible')return;
|
||||
const messageIds=[...scroller.querySelectorAll('[data-message-id]')].map(item=>item.dataset.messageId).filter(Boolean);
|
||||
if(!messageIds.length)return;
|
||||
readRunning=true;
|
||||
try{await fetch(readUrl,{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json','X-CSRFToken':decodeURIComponent(cookie('csrftoken'))},body:JSON.stringify({message_ids:messageIds})})}catch(error){console.error('Message read acknowledgement failed',error)}finally{readRunning=false}
|
||||
};
|
||||
acknowledgeVisibleMessages();
|
||||
// Keep the staff/customer conversation synchronized even while another tab is
|
||||
// active. Browsers may throttle background timers, so visibility is used only
|
||||
// to trigger an immediate catch-up, never as a hard polling gate.
|
||||
// navigator.onLine only reports the browser's network-interface heuristic.
|
||||
// It can be false while this Django origin is still reachable (notably on
|
||||
// local networks, installed PWAs and some mobile browsers). Let fetch be the
|
||||
// source of truth and use the existing error backoff when the origin really
|
||||
// is unavailable.
|
||||
const canPoll=()=>Boolean(pollUrl);
|
||||
const schedulePoll=()=>{const delay=pollErrors?Math.min(30000,pollInterval*(2**Math.min(pollErrors,3))):pollInterval;nextPollAt=Date.now()+delay};
|
||||
const applyPollUpdate=data=>{
|
||||
if(!data.changed)return;
|
||||
const wasAtBottom=atBottom();
|
||||
const fragment=document.createRange().createContextualFragment(data.html||'');
|
||||
if(data.replace)scroller.querySelectorAll('[data-message],.date-divider,.conversation-empty').forEach(item=>item.remove());
|
||||
else scroller.querySelectorAll('.conversation-empty').forEach(item=>item.remove());
|
||||
scroller.insertBefore(fragment,conversationEnd);
|
||||
workspace.dataset.pollVersion=data.version||'';workspace.dataset.pollCursor=data.cursor||'';
|
||||
const count=workspace.querySelector('[data-conversation-count]');if(count)count.textContent=String(data.count??'');
|
||||
workspace.querySelectorAll('[data-ticket-status]').forEach(item=>item.textContent=data.status||item.textContent);
|
||||
groupDates();
|
||||
acknowledgeVisibleMessages();
|
||||
scroller.querySelectorAll('img:not([data-poll-bound]),audio:not([data-poll-bound])').forEach(media=>{media.dataset.pollBound='true';const event=media.tagName==='IMG'?'load':'loadedmetadata';media.addEventListener(event,()=>{if(wasAtBottom)scrollLatest(false)},{once:true})});
|
||||
if(wasAtBottom){scrollLatest(true);jump.hidden=true}else jump.hidden=false;
|
||||
};
|
||||
const poll=async()=>{
|
||||
if(!canPoll()||pollRunning)return;
|
||||
const generation=++pollGeneration;pollRunning=true;const controller=new AbortController();pollController=controller;
|
||||
try{
|
||||
const url=new URL(pollUrl,location.origin);url.searchParams.set('version',workspace.dataset.pollVersion||'');url.searchParams.set('cursor',workspace.dataset.pollCursor||'');
|
||||
const response=await fetch(url,{method:'GET',signal:controller.signal,cache:'no-store',headers:{Accept:'application/json'}});
|
||||
if(response.redirected){location.assign(response.url);return}
|
||||
if(!response.ok)throw new Error(`HTTP ${response.status}`);
|
||||
applyPollUpdate(await response.json());pollErrors=0;
|
||||
}catch(error){if(error.name!=='AbortError'){pollErrors+=1;console.error('Ticket polling failed',error)}}finally{if(generation===pollGeneration){pollRunning=false;pollController=null;schedulePoll()}}
|
||||
};
|
||||
const startPolling=()=>{if(!canPoll()||pollRunning||Date.now()<nextPollAt)return;poll()};
|
||||
const stopPolling=()=>{pollGeneration+=1;if(pollController){pollController.abort();pollController=null}pollRunning=false;nextPollAt=0};
|
||||
const restartPolling=()=>{stopPolling();startPolling()};
|
||||
document.addEventListener('visibilitychange',()=>{if(document.visibilityState==='visible'){restartPolling();acknowledgeVisibleMessages()}});
|
||||
window.addEventListener('focus',startPolling);
|
||||
window.addEventListener('pageshow',restartPolling);
|
||||
window.addEventListener('online',restartPolling);
|
||||
// One independent heartbeat cannot be lost in the load/pageshow race that can
|
||||
// cancel a recursively scheduled timeout. pollRunning prevents overlap and
|
||||
// nextPollAt preserves the normal interval and network-error backoff.
|
||||
const pollHeartbeat=setInterval(startPolling,1000);
|
||||
window.addEventListener('beforeunload',()=>{clearInterval(pollHeartbeat);stopPolling()},{once:true});
|
||||
startPolling();
|
||||
|
||||
const resetMessageMenu=menu=>{if(!menu)return;const editor=menu.querySelector('[data-message-editor]');const choices=menu.querySelector('[data-message-menu-choices]');const input=menu.querySelector('[data-message-edit-input]');if(editor)editor.hidden=true;if(choices)choices.hidden=false;if(input){input.value=input.dataset.originalValue||'';input.dispatchEvent(new Event('input',{bubbles:true}))}};
|
||||
const closeMessageMenu=menu=>{if(!menu)return;menu.open=false;resetMessageMenu(menu)};
|
||||
workspace.addEventListener('toggle',event=>{const menu=event.target.closest?.('[data-message-menu]');if(menu?.open)workspace.querySelectorAll('[data-message-menu][open]').forEach(other=>{if(other!==menu)closeMessageMenu(other)})},true);
|
||||
workspace.addEventListener('click',event=>{const close=event.target.closest('[data-message-menu-close]');if(close){event.preventDefault();closeMessageMenu(close.closest('[data-message-menu]'));return}const edit=event.target.closest('[data-message-edit-open]');if(edit){const menu=edit.closest('[data-message-menu]');menu.querySelector('[data-message-menu-choices]').hidden=true;menu.querySelector('[data-message-editor]').hidden=false;const input=menu.querySelector('[data-message-edit-input]');input.focus();input.setSelectionRange(input.value.length,input.value.length);return}const back=event.target.closest('[data-message-edit-back]');if(back){event.preventDefault();resetMessageMenu(back.closest('[data-message-menu]'))}});
|
||||
workspace.addEventListener('input',event=>{if(!event.target.matches('[data-message-edit-input]'))return;const count=event.target.closest('[data-message-editor]').querySelector('[data-message-edit-count]');if(count)count.textContent=`${event.target.value.length.toLocaleString('fa-IR')} / ۴۰۰۰`});
|
||||
document.addEventListener('click',event=>{workspace.querySelectorAll('[data-message-menu][open]').forEach(menu=>{if(!menu.contains(event.target))closeMessageMenu(menu)})});
|
||||
workspace.addEventListener('keydown',event=>{if(event.key==='Escape'){const menu=event.target.closest('[data-message-menu]')||workspace.querySelector('[data-message-menu][open]');if(menu){event.preventDefault();closeMessageMenu(menu);menu.querySelector(':scope > summary')?.focus()}}});
|
||||
|
||||
workspace.querySelectorAll('[data-toggle-panel]').forEach(button=>button.addEventListener('click',()=>{const panel=workspace.querySelector(`#${button.dataset.togglePanel}`);workspace.querySelectorAll('[data-workspace-panel]').forEach(item=>item.classList.toggle('panel-open',item===panel&&!item.classList.contains('panel-open')))}));
|
||||
workspace.querySelectorAll('[data-close-panel]').forEach(button=>button.addEventListener('click',()=>button.closest('[data-workspace-panel]').classList.remove('panel-open')));
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
(()=>{const dialog=document.querySelector('[data-image-viewer]');if(!dialog)return;const image=dialog.querySelector('[data-image-preview]'),title=dialog.querySelector('[data-image-title]'),download=dialog.querySelector('[data-image-download]');document.addEventListener('click',event=>{const trigger=event.target.closest('[data-image-open]');if(!trigger)return;image.src=trigger.dataset.imageSrc;image.alt=trigger.dataset.imageName||'تصویر پیوست';title.textContent=trigger.dataset.imageName||'تصویر پیوست';download.href=trigger.dataset.imageSrc.replace('/view/','/download/');dialog.showModal()});dialog.querySelector('[data-image-close]').addEventListener('click',()=>dialog.close());dialog.addEventListener('click',event=>{if(event.target===dialog)dialog.close()});dialog.addEventListener('close',()=>image.removeAttribute('src'))})();
|
||||
@@ -0,0 +1,38 @@
|
||||
document.querySelectorAll('[data-location-picker]').forEach(async picker=>{
|
||||
const province=picker.querySelector('[data-province-input]');
|
||||
const city=picker.querySelector('[data-city-input]');
|
||||
const provinceList=picker.querySelector('[data-province-options]')||(province?.matches('select')?province:null);
|
||||
const cityList=picker.querySelector('[data-city-options]')||(city?.matches('select')?city:null);
|
||||
const hint=picker.querySelector('[data-location-hint]');
|
||||
if(!province||!city||!provinceList||!cityList)return;
|
||||
|
||||
const normalize=value=>(value||'').trim().replace(/ي/g,'ی').replace(/ك/g,'ک');
|
||||
const setHint=(text,error=false)=>{if(!hint)return;hint.textContent=text;hint.classList.toggle('is-error',error)};
|
||||
const fill=(list,values,placeholder='')=>{
|
||||
const selected=normalize(list.value);
|
||||
const options=values.map(value=>{const option=document.createElement('option');option.value=value;option.textContent=value;return option});
|
||||
if(list.matches('select')){const empty=document.createElement('option');empty.value='';empty.textContent=placeholder;options.unshift(empty)}
|
||||
list.replaceChildren(...options);
|
||||
if(values.includes(selected))list.value=selected;
|
||||
};
|
||||
try{
|
||||
const response=await fetch(picker.dataset.locationsUrl,{cache:'force-cache'});
|
||||
if(!response.ok)throw new Error('location data unavailable');
|
||||
const rows=await response.json();
|
||||
const locations=new Map(rows.map(row=>[normalize(row.province),row.cities]));
|
||||
fill(provinceList,rows.map(row=>row.province),'انتخاب استان');
|
||||
const syncCities=(clearInvalid=false)=>{
|
||||
const cities=locations.get(normalize(province.value))||[];
|
||||
fill(cityList,cities,'انتخاب شهر');
|
||||
city.disabled=!cities.length;
|
||||
if(clearInvalid&&city.value&&!cities.includes(normalize(city.value)))city.value='';
|
||||
setHint(cities.length?`${cities.length.toLocaleString('fa-IR')} شهر برای این استان در دسترس است.`:'برای نمایش شهرها، یک استان معتبر انتخاب کنید.',Boolean(province.value&&!cities.length));
|
||||
};
|
||||
province.addEventListener('input',()=>syncCities(true));
|
||||
province.addEventListener('change',()=>syncCities(true));
|
||||
city.addEventListener('change',()=>{const cities=locations.get(normalize(province.value))||[];setHint(!city.value||cities.includes(normalize(city.value))?'موقعیت انتخابی برای همین تیکت استفاده میشود.':'شهر را از فهرست همین استان انتخاب کنید.',Boolean(city.value&&!cities.includes(normalize(city.value))))});
|
||||
syncCities(false);
|
||||
}catch(error){
|
||||
province.disabled=true;city.disabled=true;setHint('فهرست شهرها بارگذاری نشد؛ صفحه را دوباره باز کنید.',true);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
let deferredInstallPrompt=null;
|
||||
const banner=document.querySelector('[data-pwa-install]'),accept=banner?.querySelector('[data-pwa-accept]'),help=banner?.querySelector('[data-pwa-help]');
|
||||
const standalone=matchMedia('(display-mode: standalone)').matches||navigator.standalone===true;
|
||||
const mobileDevice=navigator.userAgentData?.mobile===true||/android|iphone|ipad|ipod|mobile/i.test(navigator.userAgent)||(matchMedia('(max-width: 820px)').matches&&matchMedia('(pointer: coarse)').matches);
|
||||
const isiOS=/iphone|ipad|ipod/i.test(navigator.userAgent);
|
||||
const dismissed=()=>Date.now()-Number(localStorage.getItem('pwa-install-dismissed')||0)<24*60*60*1000;
|
||||
const show=()=>{if(banner&&mobileDevice&&!standalone&&!dismissed())banner.hidden=false};
|
||||
const setGuide=(text,label='راهنمای نصب')=>{if(help)help.textContent=text;if(accept)accept.textContent=label;banner?.classList.add('pwa-install-guidance')};
|
||||
if('serviceWorker' in navigator&&window.isSecureContext){let workerRegistration=null,workerReloading=false;const assetVersion=document.documentElement.dataset.staticVersion||new URL(document.currentScript?.src||location.href).searchParams.get('v')||'';const serviceWorkerUrl=`/service-worker.js?v=${encodeURIComponent(assetVersion)}`;const updateWorker=()=>{if(workerRegistration&&document.visibilityState==='visible')workerRegistration.update().catch(()=>{})};navigator.serviceWorker.addEventListener('controllerchange',()=>{if(workerReloading)return;workerReloading=true;location.reload()});window.addEventListener('load',async()=>{try{workerRegistration=await navigator.serviceWorker.register(serviceWorkerUrl,{updateViaCache:'none'});await workerRegistration.update()}catch(error){setGuide('فعالسازی نصب برنامه با خطا روبهرو شد. صفحه را تازهسازی کنید.');show()}});document.addEventListener('visibilitychange',updateWorker);setInterval(updateWorker,60000)}
|
||||
window.addEventListener('beforeinstallprompt',event=>{event.preventDefault();deferredInstallPrompt=event;if(accept){accept.textContent='نصب برنامه';accept.disabled=false}banner?.classList.remove('pwa-install-guidance');if(help)help.textContent='برنامه آماده نصب است؛ برای ادامه روی «نصب برنامه» بزنید.';show()});
|
||||
if(mobileDevice&&isiOS&&!standalone){setGuide('در Safari روی دکمه اشتراکگذاری (□↑) بزنید و «Add to Home Screen» را انتخاب کنید.','نمایش راهنما');setTimeout(show,700)}
|
||||
if(mobileDevice&&!isiOS&&!standalone)setTimeout(()=>{if(!deferredInstallPrompt){setGuide(window.isSecureContext?'از منوی مرورگر گزینه «Install app» یا «افزودن به صفحه اصلی» را انتخاب کنید.':'نصب مستقیم روی آدرس HTTP شبکه ممکن نیست. سامانه را با HTTPS باز کنید؛ سپس دکمه نصب فعال میشود.','راهنمای نصب');show()}},1800);
|
||||
banner?.querySelector('[data-pwa-dismiss]')?.addEventListener('click',()=>{banner.hidden=true;localStorage.setItem('pwa-install-dismissed',Date.now())});
|
||||
accept?.addEventListener('click',async()=>{if(deferredInstallPrompt){accept.disabled=true;deferredInstallPrompt.prompt();const {outcome}=await deferredInstallPrompt.userChoice;deferredInstallPrompt=null;if(outcome==='accepted')banner.hidden=true;else{accept.disabled=false;setGuide('نصب لغو شد. برای تلاش دوباره از منوی مرورگر «Install app» را انتخاب کنید.')}}else if(isiOS){setGuide('۱) Safari را باز کنید. ۲) دکمه اشتراکگذاری □↑ را بزنید. ۳) Add to Home Screen و سپس Add را انتخاب کنید.','متوجه شدم')}else if(!window.isSecureContext){setGuide('مرورگر برای نصب و Service Worker به HTTPS نیاز دارد. از نسخه HTTPS سامانه استفاده کنید.','نیازمند HTTPS')}else{setGuide('منوی سهنقطه مرورگر را باز کنید و «Install app» یا «افزودن به صفحه اصلی» را بزنید.','نصب از منوی مرورگر')}});
|
||||
window.addEventListener('appinstalled',()=>{deferredInstallPrompt=null;localStorage.removeItem('pwa-install-dismissed');if(banner)banner.hidden=true});
|
||||
@@ -0,0 +1,21 @@
|
||||
document.addEventListener('DOMContentLoaded',()=>{
|
||||
const root=document.querySelector('[data-customer-picker]');if(!root)return;
|
||||
const search=root.querySelector('[data-customer-search]'),results=root.querySelector('[data-customer-results]'),status=root.querySelector('[data-customer-status]');
|
||||
const idInput=root.querySelector('[data-customer-id]'),mobile=root.querySelector('#id_customer_mobile'),first=root.querySelector('#id_first_name'),last=root.querySelector('#id_last_name'),province=root.querySelector('#id_province'),city=root.querySelector('#id_city');
|
||||
const selected=root.querySelector('[data-selected-customer]');let timer,requestToken=0;
|
||||
const identityRows=[first?.closest('[data-new-customer-field]'),last?.closest('[data-new-customer-field]')].filter(Boolean);
|
||||
const summaryCustomer=root.querySelector('[data-summary-customer]'),summarySubject=root.querySelector('[data-summary-subject]'),summaryCategory=root.querySelector('[data-summary-category]'),subject=root.querySelector('#id_subject'),category=root.querySelector('#id_category');
|
||||
const escapeHtml=value=>String(value??'').replace(/[&<>'"]/g,char=>({'&':'&','<':'<','>':'>',"'":''','"':'"'}[char]));
|
||||
function setNewCustomer(isNew){identityRows.forEach(row=>row.hidden=!isNew);status.className=`customer-lookup-status ${isNew?'is-new':'is-found'}`;status.textContent=isNew?'این شماره در سامانه ثبت نشده است؛ نام و نام خانوادگی مشتری جدید را تکمیل کنید.':'مشتری موجود انتخاب شد؛ مشخصات ثبتشده در بالا نمایش داده شده است.'}
|
||||
function selectCustomer(customer){idInput.value=customer.id;mobile.value=customer.mobile;first.value=customer.first_name;last.value=customer.last_name;province.value=customer.province;city.value=customer.city;selected.hidden=false;selected.querySelector('[data-selected-name]').textContent=customer.name;selected.querySelector('[data-selected-mobile]').textContent=customer.mobile;selected.querySelector('[data-selected-location]').textContent=[customer.city,customer.province].filter(Boolean).join('، ')||'موقعیت ثبت نشده';selected.querySelector('[data-selected-stats]').textContent=`${customer.ticket_count} تیکت، ${customer.active_count} فعال`;summaryCustomer.textContent=customer.name;results.hidden=true;search.value='';setNewCustomer(false);province.dispatchEvent(new Event('input',{bubbles:true}))}
|
||||
function clearCustomer(clearMobile=true){idInput.value='';selected.hidden=true;identityRows.forEach(row=>row.hidden=false);if(clearMobile)mobile.value='';first.value='';last.value='';province.value='';city.value='';summaryCustomer.textContent='هنوز انتخاب نشده';status.className='customer-lookup-status';status.textContent='شماره موبایل را وارد کنید تا عضویت مشتری بررسی شود.'}
|
||||
async function lookup(params,showList=false){const token=++requestToken;try{const response=await fetch(`${root.dataset.searchUrl}?${params}`,{headers:{'Accept':'application/json'}});if(!response.ok)throw new Error();const data=await response.json();if(token!==requestToken)return;if(showList){results.innerHTML=data.results.length?data.results.map(item=>`<button type="button" data-customer-result='${escapeHtml(JSON.stringify(item))}'><b>${escapeHtml(item.name)}</b><span dir="ltr">${escapeHtml(item.mobile)}</span><small>${escapeHtml([item.city,item.province].filter(Boolean).join('، ')||'موقعیت ثبت نشده')} · ${item.ticket_count} تیکت</small></button>`).join(''):'<p>مشتریای با این عبارت پیدا نشد.</p>';results.hidden=false}else if(data.results.length&&data.results[0].mobile.replace(/\D/g,'')===mobile.value.replace(/\D/g,'').replace(/^98(?=9)/,'0'))selectCustomer(data.results[0]);else{if(idInput.value)clearCustomer(false);setNewCustomer(true)}}catch{status.className='customer-lookup-status is-error';status.textContent='بررسی مشتری ممکن نشد؛ اتصال را بررسی و دوباره تلاش کنید.'}}
|
||||
search.addEventListener('input',()=>{clearTimeout(timer);const value=search.value.trim();if(value.length<2){results.hidden=true;return}timer=setTimeout(()=>lookup(`q=${encodeURIComponent(value)}`,true),300)});
|
||||
results.addEventListener('click',event=>{const button=event.target.closest('[data-customer-result]');if(button)selectCustomer(JSON.parse(button.dataset.customerResult))});
|
||||
root.querySelector('[data-clear-customer]').addEventListener('click',()=>{clearCustomer();search.focus()});
|
||||
mobile.addEventListener('input',()=>{if(idInput.value&&mobile.value!==selected.querySelector('[data-selected-mobile]').textContent)clearCustomer(false);clearTimeout(timer);const digits=mobile.value.replace(/\D/g,'');if(digits.length<10){status.className='customer-lookup-status';status.textContent='شماره موبایل را کامل وارد کنید.';return}status.textContent='در حال بررسی شماره…';timer=setTimeout(()=>lookup(`q=${encodeURIComponent(mobile.value)}`),350)});
|
||||
if(idInput.value)lookup(`id=${encodeURIComponent(idInput.value)}`);else if(mobile.value)mobile.dispatchEvent(new Event('input'));
|
||||
subject?.addEventListener('input',()=>summarySubject.textContent=subject.value.trim()||'هنوز وارد نشده');
|
||||
category?.addEventListener('change',()=>summaryCategory.textContent=category.selectedOptions[0]?.text||'انتخاب نشده');
|
||||
if(subject?.value)summarySubject.textContent=subject.value;if(category?.value)summaryCategory.textContent=category.selectedOptions[0]?.text;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
(() => {
|
||||
const form=document.querySelector('[data-ticket-search-url]'); if(!form)return;
|
||||
const input=form.querySelector('[data-ticket-search]'); const results=form.querySelector('[data-ticket-search-results]');
|
||||
const unit=form.querySelector('[data-ticket-unit]'); const category=form.querySelector('[data-ticket-category]'); let timer;
|
||||
const message=text=>{results.replaceChildren(); const p=document.createElement('p'); p.className='intent-message'; p.textContent=text; results.append(p)};
|
||||
const select=async item=>{
|
||||
unit.value=String(item.unit_id);
|
||||
const loaded=new Promise(resolve=>category.addEventListener('ticket-options-loaded',resolve,{once:true}));
|
||||
unit.dispatchEvent(new Event('change',{bubbles:true})); await loaded;
|
||||
category.value=String(item.category_id); category.dispatchEvent(new Event('change',{bubbles:true}));
|
||||
document.querySelector('.manual-routing')?.setAttribute('open',''); message(`مسیر انتخاب شد: ${item.unit} ← ${item.category}`); category.focus();
|
||||
};
|
||||
const render=items=>{
|
||||
results.replaceChildren(); if(!items.length){message('نتیجه دقیقی پیدا نشد؛ از انتخاب دستی استفاده کنید.');return}
|
||||
items.forEach(item=>{const button=document.createElement('button');button.type='button';button.className='intent-result';
|
||||
const title=document.createElement('strong');title.textContent=item.category;const meta=document.createElement('span');meta.textContent=item.unit;
|
||||
const detail=document.createElement('small');detail.textContent=item.description||'انتخاب این مسیر برای درخواست';button.append(title,meta,detail);button.addEventListener('click',()=>select(item));results.append(button)});
|
||||
};
|
||||
input.addEventListener('input',()=>{clearTimeout(timer);const q=input.value.trim();if(q.length<2){results.replaceChildren();return}message('در حال یافتن بهترین مسیر…');timer=setTimeout(async()=>{try{const response=await fetch(`${form.dataset.ticketSearchUrl}?q=${encodeURIComponent(q)}`,{headers:{Accept:'application/json'}});render((await response.json()).results)}catch{message('جستوجو در دسترس نیست؛ از انتخاب دستی استفاده کنید.')}},260)});
|
||||
})();
|
||||
@@ -0,0 +1,62 @@
|
||||
(() => {
|
||||
const form = document.querySelector("[data-unit-options-url]");
|
||||
if (!form) return;
|
||||
const unit = form.querySelector("[data-ticket-unit]");
|
||||
const category = form.querySelector("[data-ticket-category]");
|
||||
const picker = form.querySelector("[data-expert-picker]");
|
||||
if (!unit || !category || !picker) return;
|
||||
let requestController;
|
||||
|
||||
const addGeneralQueue = (queue) => {
|
||||
const label = document.createElement("label"); label.className = "expert-card";
|
||||
label.dataset.generalQueue = ""; label.dataset.unitId = String(queue.unit_id);
|
||||
const radio = document.createElement("input"); radio.type = "radio"; radio.name = "selected_expert"; radio.value = ""; radio.checked = true;
|
||||
const avatar = document.createElement("span"); avatar.className = "expert-avatar"; avatar.textContent = "⌁";
|
||||
const title = document.createElement("strong"); title.textContent = queue.label;
|
||||
const detail = document.createElement("small"); detail.textContent = "اولین کارشناس آزاد همین واحد";
|
||||
label.append(radio, avatar, title, detail); picker.append(label);
|
||||
};
|
||||
const render = (payload) => {
|
||||
category.replaceChildren(new Option("انتخاب دستهبندی", ""));
|
||||
payload.categories.forEach((item) => category.add(new Option(item.label, item.id)));
|
||||
const selectedUnitLabel=unit.options[unit.selectedIndex]?.textContent?.trim() || "واحد";
|
||||
const queue=payload.queue || {unit_id:unit.value,label:`صف عمومی ${selectedUnitLabel}`};
|
||||
picker.replaceChildren(); addGeneralQueue(queue);
|
||||
payload.experts.forEach((item) => {
|
||||
const label=document.createElement("label"); label.className="expert-card";
|
||||
const radio=document.createElement("input"); radio.type="radio"; radio.name="selected_expert"; radio.value=item.id;
|
||||
const image=document.createElement("img"); image.src=item.avatar_url; image.alt=`تصویر ${item.name}`; image.width=56; image.height=56; image.loading="lazy";
|
||||
const title=document.createElement("strong"); title.textContent=item.name;
|
||||
const detail=document.createElement("small"); detail.textContent=item.job_title;
|
||||
label.append(radio,image,title,detail); picker.append(label);
|
||||
});
|
||||
if (!payload.experts.length) {
|
||||
const empty=document.createElement("p"); empty.className="muted expert-empty";
|
||||
empty.textContent="برای این واحد کارشناس قابل انتخابی ثبت نشده است؛ درخواست به صف عمومی میرود.";
|
||||
picker.append(empty);
|
||||
}
|
||||
};
|
||||
unit.addEventListener("change", async () => {
|
||||
requestController?.abort(); requestController=new AbortController();
|
||||
const requestedUnit=unit.value;
|
||||
category.disabled=true;
|
||||
try {
|
||||
const optionsUrl=new URL(form.dataset.unitOptionsUrl,window.location.origin);
|
||||
optionsUrl.searchParams.set("unit",requestedUnit);
|
||||
optionsUrl.searchParams.set("v",document.documentElement.dataset.staticVersion || "1");
|
||||
const response=await fetch(optionsUrl, {headers:{Accept:"application/json"},credentials:"same-origin",cache:"no-store",signal:requestController.signal});
|
||||
if (!response.ok) throw new Error("options request failed");
|
||||
const payload=await response.json();
|
||||
if (unit.value!==requestedUnit) return;
|
||||
render(payload);
|
||||
category.dispatchEvent(new CustomEvent("ticket-options-loaded",{detail:{ok:true,unitId:requestedUnit}}));
|
||||
} catch (error) {
|
||||
if (error.name==="AbortError") return;
|
||||
console.error("Failed to update ticket unit options", error);
|
||||
picker.replaceChildren();
|
||||
const message=document.createElement("p"); message.className="muted expert-empty"; message.setAttribute("role","alert");
|
||||
message.textContent="دریافت کارشناسان این واحد ناموفق بود؛ لطفاً دوباره تلاش کنید."; picker.append(message);
|
||||
category.dispatchEvent(new CustomEvent("ticket-options-loaded",{detail:{ok:false,unitId:requestedUnit}}));
|
||||
} finally { if (unit.value===requestedUnit) category.disabled=false; }
|
||||
});
|
||||
})();
|
||||
@@ -0,0 +1,8 @@
|
||||
document.addEventListener('submit',event=>{
|
||||
const form=event.target;if(!form.matches('form'))return;
|
||||
requestAnimationFrame(()=>{if(!form.checkValidity())return;form.querySelectorAll('button[type="submit"],button:not([type])').forEach(button=>{button.disabled=true;button.setAttribute('aria-busy','true');if(!button.dataset.label)button.dataset.label=button.textContent;button.textContent='در حال ثبت…'})});
|
||||
});
|
||||
document.querySelectorAll('.flash').forEach(flash=>{
|
||||
const close=document.createElement('button');close.type='button';close.className='flash-close';close.setAttribute('aria-label','بستن پیام');close.textContent='×';close.addEventListener('click',()=>flash.remove());flash.appendChild(close);
|
||||
if(flash.classList.contains('success'))setTimeout(()=>{flash.classList.add('flash-leaving');setTimeout(()=>flash.remove(),250)},7000);
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
document.querySelectorAll('[data-voice-recorder]').forEach(root=>{
|
||||
let recorder,stream,chunks=[],started,timer,pausedAt=0,pausedMs=0,voiceFile;
|
||||
const form=root.closest('form'),record=root.querySelector('[data-record]'),pause=root.querySelector('[data-pause]'),stop=root.querySelector('[data-stop]'),remove=root.querySelector('[data-delete]'),audio=root.querySelector('audio'),clock=root.querySelector('[data-timer]');
|
||||
const supported=window.isSecureContext&&navigator.mediaDevices?.getUserMedia&&window.MediaRecorder;
|
||||
if(!supported){record.disabled=true;record.title='ضبط صدا فقط در HTTPS یا localhost و مرورگر سازگار فعال است';root.insertAdjacentHTML('beforeend','<small class="recorder-error">مرورگر یا اتصال فعلی امکان ضبط امن صدا را ندارد.</small>');return}
|
||||
const stopTracks=()=>{stream?.getTracks().forEach(track=>track.stop());stream=null};
|
||||
const reset=()=>{if(voiceFile)form.dispatchEvent(new CustomEvent('voice-removed',{detail:voiceFile}));voiceFile=null;stopTracks();if(audio.src)URL.revokeObjectURL(audio.src);audio.removeAttribute('src');audio.hidden=true;remove.hidden=true;clock.textContent='00:00';record.disabled=false;pause.disabled=true;pause.textContent='مکث';stop.disabled=true};
|
||||
record.addEventListener('click',async()=>{try{stream=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:true,noiseSuppression:true,autoGainControl:true}});const mime=['audio/webm;codecs=opus','audio/mp4','audio/ogg;codecs=opus','audio/webm'].find(type=>MediaRecorder.isTypeSupported(type));recorder=new MediaRecorder(stream,mime?{mimeType:mime}:undefined);chunks=[];pausedMs=0;recorder.ondataavailable=event=>{if(event.data.size)chunks.push(event.data)};recorder.onerror=()=>{stopTracks();alert('ضبط صدا متوقف شد. دوباره تلاش کنید.')};recorder.onstop=()=>{clearInterval(timer);stopTracks();const type=recorder.mimeType.split(';')[0]||'audio/webm',blob=new Blob(chunks,{type});if(!blob.size)return reset();audio.src=URL.createObjectURL(blob);audio.hidden=false;remove.hidden=false;const ext=type.includes('ogg')?'ogg':type.includes('mp4')?'m4a':'webm';voiceFile=new File([blob],`voice-${Date.now()}.${ext}`,{type});form.dispatchEvent(new CustomEvent('voice-added',{detail:voiceFile}))};recorder.start(1000);started=Date.now();record.disabled=true;pause.disabled=false;stop.disabled=false;timer=setInterval(()=>{const elapsed=Date.now()-started-pausedMs-(recorder.state==='paused'?Date.now()-pausedAt:0),seconds=Math.max(0,Math.floor(elapsed/1000));clock.textContent=`${String(Math.floor(seconds/60)).padStart(2,'0')}:${String(seconds%60).padStart(2,'0')}`},500)}catch(error){stopTracks();const denied=error.name==='NotAllowedError';alert(denied?'دسترسی میکروفن رد شده است. از تنظیمات مرورگر، دسترسی Microphone را برای این سایت فعال کنید.':'میکروفن در دسترس نیست یا توسط برنامه دیگری استفاده میشود.')}});
|
||||
pause.addEventListener('click',()=>{if(recorder?.state==='recording'){recorder.pause();pausedAt=Date.now();pause.textContent='ادامه ضبط'}else if(recorder?.state==='paused'){pausedMs+=Date.now()-pausedAt;recorder.resume();pause.textContent='مکث'}});
|
||||
stop.addEventListener('click',()=>{if(recorder&&recorder.state!=='inactive')recorder.stop();pause.disabled=true;stop.disabled=true});
|
||||
remove.addEventListener('click',reset);window.addEventListener('pagehide',stopTracks);
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
if (!('OTPCredential' in window) || !window.isSecureContext) return;
|
||||
const form = document.querySelector('[data-webotp-form]');
|
||||
const input = form?.querySelector('[data-webotp]');
|
||||
if (!form || !input) return;
|
||||
const controller = new AbortController();
|
||||
form.addEventListener('submit', () => controller.abort(), { once: true });
|
||||
try {
|
||||
const credential = await navigator.credentials.get({ otp: { transport: ['sms'] }, signal: controller.signal });
|
||||
if (!credential?.code) return;
|
||||
input.value = credential.code;
|
||||
form.requestSubmit();
|
||||
} catch (error) {
|
||||
if (error.name !== 'AbortError') console.debug('WebOTP unavailable', error);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
{"id":"/","name":"گفتوگو با واحد فروش","short_name":"واحد فروش","description":"ثبت و پیگیری درخواستهای فروش لوله گستر گلپایگان","start_url":"/tickets/","scope":"/","display":"standalone","background_color":"#eeeeee","theme_color":"#08376b","lang":"fa","dir":"rtl","icons":[{"src":"/static/images/pwa-icon.png","sizes":"1024x1024","type":"image/png","purpose":"any maskable"}]}
|
||||
@@ -0,0 +1,134 @@
|
||||
@import "tailwindcss";
|
||||
@source "../../templates/**/*.html";
|
||||
@source "../js/**/*.js";
|
||||
@font-face{font-family:Vazirmatn;src:url("../fonts/vazirmatn-arabic-wght-normal.woff2") format("woff2-variations");font-weight:100 900;font-display:swap}@font-face{font-family:Vazirmatn;src:url("../fonts/vazirmatn-latin-wght-normal.woff2") format("woff2-variations");font-weight:100 900;font-display:swap}
|
||||
@theme{--font-sans:Vazirmatn,ui-sans-serif,system-ui;--color-ink:#08376b;--color-ink-soft:#0b4c8c;--color-cream:#eeeeee;--color-soft:#eaeaea;--color-paper:#ffffff;--color-sea:#0693e3;--color-sea-dark:#1977ce;--color-blue:#1977ce;--color-mint:#e5f4ff;--color-coral:#fa9f00;--color-sun:#ffc451;--shadow-panel:0 18px 55px -35px rgba(8,55,107,.35);--shadow-lift:0 22px 55px -28px rgba(6,147,227,.42)}
|
||||
:root{--color-ink:#08376b;--color-ink-soft:#0b4c8c;--color-cream:#eeeeee;--color-soft:#eaeaea;--color-paper:#ffffff;--color-sea:#0693e3;--color-sea-dark:#1977ce;--color-blue:#1977ce;--color-mint:#e5f4ff;--color-coral:#fa9f00;--color-sun:#ffc451;--theme-thread:#eaeaea;--theme-own-message:#dcefff;--theme-note:#fff1d5;--shadow-panel:0 18px 55px -35px rgba(8,55,107,.35);--shadow-lift:0 22px 55px -28px rgba(6,147,227,.42)}
|
||||
@layer base{*{@apply box-border}html{@apply scroll-smooth}body{@apply m-0 min-h-screen bg-cream font-sans text-ink antialiased}button,a,input,textarea,select{@apply focus-visible:outline-none focus-visible:ring-4 focus-visible:ring-sea/20}a{@apply transition}h1{@apply text-[1.7rem] font-black leading-tight tracking-tight sm:text-4xl}h2{@apply text-xl font-extrabold leading-tight}h3{@apply text-base font-extrabold}p{@apply leading-7}label{@apply mb-2 block text-sm font-bold}input:not([type=checkbox]):not([type=radio]),textarea,select{@apply w-full rounded-2xl border border-ink/10 bg-white px-4 py-3 text-base shadow-sm transition placeholder:text-slate-400 hover:border-sea/30 focus:border-sea focus:ring-4 focus:ring-sea/10 sm:text-sm}textarea{@apply min-h-36 resize-y}button,.button{@apply inline-flex min-h-12 items-center justify-center gap-2 rounded-2xl bg-ink px-5 py-3 text-sm font-extrabold text-white shadow-sm transition hover:-translate-y-0.5 hover:bg-sea-dark hover:shadow-lift disabled:pointer-events-none disabled:opacity-50}form p{@apply mb-5}.errorlist{@apply mb-2 list-none rounded-xl bg-red-50 px-3 py-2 text-xs font-bold text-red-700}}
|
||||
@layer components{
|
||||
.site-header{@apply sticky top-0 z-40 border-b border-ink/5 bg-cream/90 backdrop-blur-xl}.header-inner{@apply mx-auto flex h-17 max-w-7xl items-center justify-between px-4 sm:px-7}.logo{@apply flex items-center gap-3 text-ink}.logo-mark{@apply grid size-10 place-items-center rounded-[14px] bg-ink text-lg font-black text-white}.logo-copy{@apply font-black}.logo-copy small{@apply block text-[9px] font-medium tracking-wide text-ink/50}.desktop-nav{@apply hidden items-center gap-1 sm:flex}.desktop-nav a{@apply rounded-xl px-3 py-2 text-sm font-bold text-ink/65 hover:bg-white hover:text-sea}.desktop-nav .logout{@apply text-coral}.customer-main{@apply mx-auto w-full max-w-6xl px-4 pb-28 pt-6 sm:px-7 sm:pb-12 sm:pt-10}.mobile-dock{@apply fixed inset-x-3 bottom-3 z-50 grid grid-cols-3 rounded-[22px] border border-white/80 bg-ink/95 p-1.5 shadow-2xl backdrop-blur-xl sm:hidden}.mobile-dock a{@apply flex min-h-12 flex-col items-center justify-center gap-0.5 rounded-2xl text-[10px] font-bold text-white/60}.mobile-dock a.primary{@apply bg-sea text-white}.dock-icon{@apply text-base}
|
||||
.staff-shell{@apply min-h-screen lg:grid lg:grid-cols-[250px_1fr]}.staff-sidebar{@apply hidden bg-ink p-5 text-white lg:flex lg:min-h-screen lg:flex-col lg:justify-between}.staff-brand{@apply mb-10 flex items-center gap-3}.staff-brand .logo-mark{@apply bg-sea}.staff-brand small{@apply block text-xs text-white/45}.staff-menu{@apply grid gap-1.5}.staff-menu a{@apply flex items-center gap-3 rounded-2xl px-4 py-3 text-sm font-bold text-white/60 hover:bg-white/8 hover:text-white}.staff-menu a.active{@apply bg-sea text-white}.staff-profile{@apply rounded-2xl bg-white/7 p-4}.staff-profile strong{@apply block text-sm}.staff-profile span{@apply text-xs text-white/45}.staff-main{@apply min-w-0}.staff-topbar{@apply sticky top-0 z-30 flex h-17 items-center justify-between border-b border-ink/5 bg-cream/90 px-4 backdrop-blur-xl sm:px-7}.staff-topbar h2{@apply text-base}.staff-topbar-actions{@apply flex items-center gap-2}.staff-topbar a{@apply rounded-xl px-3 py-2 text-xs font-bold text-ink/60 hover:bg-white}.staff-content{@apply mx-auto max-w-[1500px] px-4 pb-24 pt-6 sm:px-7 lg:pb-10}.staff-mobile-dock{@apply fixed inset-x-3 bottom-3 z-50 grid grid-cols-3 rounded-[22px] bg-ink p-1.5 text-white shadow-2xl lg:hidden}.staff-mobile-dock a{@apply flex min-h-12 flex-col items-center justify-center text-[10px] font-bold text-white/60}.staff-mobile-dock a.active{@apply rounded-2xl bg-sea text-white}
|
||||
.page-kicker{@apply mb-2 text-xs font-black tracking-wider text-sea}.page-head{@apply mb-6 flex flex-col gap-4 sm:flex-row sm:items-end sm:justify-between}.page-head p{@apply mt-2 max-w-xl text-sm text-ink/55}.back-link{@apply inline-flex items-center gap-2 text-xs font-extrabold text-sea}.card{@apply rounded-[26px] border border-ink/7 bg-paper p-5 shadow-panel sm:p-6}.button.secondary,button.secondary{@apply border border-ink/10 bg-paper text-ink shadow-none hover:border-sea/30 hover:bg-mint}.button.coral,button.coral{@apply bg-coral}.muted{@apply text-sm text-ink/50}.flash{@apply mb-5 rounded-2xl border border-sea/15 bg-mint px-4 py-3 text-sm font-bold text-sea-dark}.flash.error{@apply border-red-200 bg-red-50 text-red-700}.flash.success{@apply border-emerald-200 bg-emerald-50 text-emerald-800}
|
||||
.hero-panel{@apply relative mb-7 overflow-hidden rounded-[30px] bg-ink px-5 py-7 text-white sm:px-8 sm:py-9}.hero-panel:after{@apply absolute -left-14 -top-20 size-52 rounded-full bg-sea/45 content-['']}.hero-panel>*{@apply relative z-10}.hero-panel .page-kicker{@apply text-mint}.hero-panel h1{@apply max-w-xl}.hero-panel p{@apply mt-3 max-w-lg text-sm text-white/55}.hero-actions{@apply mt-6 flex flex-col gap-2 sm:flex-row sm:flex-wrap}.hero-panel .hero-actions .button{@apply mt-0 shadow-none hover:shadow-none}.hero-panel .hero-history-button{@apply border border-white/25 bg-white/10 text-white backdrop-blur-sm hover:border-white/45 hover:bg-white/20}.hero-panel .hero-history-button span{@apply text-lg leading-none}.page-head#recent-requests{@apply scroll-mt-24}
|
||||
.ticket-grid{@apply grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3}.ticket-card{@apply relative flex min-h-48 flex-col justify-between overflow-hidden rounded-[24px] border border-ink/7 bg-paper p-5 text-ink shadow-panel transition hover:-translate-y-1 hover:border-sea/25 hover:shadow-lift}.ticket-card:before{@apply absolute inset-y-0 right-0 w-1 bg-sea/0 transition content-['']}.ticket-card:hover:before{@apply bg-sea}.ticket-card-top{@apply flex items-start justify-between gap-3}.ticket-number{@apply font-mono text-[11px] font-bold tracking-wide text-ink/40}.ticket-card h2{@apply mt-4 line-clamp-2 text-lg}.ticket-meta{@apply mt-5 flex items-end justify-between gap-3 border-t border-ink/6 pt-4}.ticket-meta small{@apply block text-[11px] text-ink/45}.expert-line{@apply mt-1 text-xs font-bold text-ink/70}.badge{@apply inline-flex w-fit items-center gap-1.5 rounded-full bg-mint px-3 py-1 text-[11px] font-extrabold text-sea-dark}.badge:before{@apply size-1.5 rounded-full bg-sea content-['']}.priority-urgent{@apply bg-red-50 text-red-700}.priority-urgent:before{@apply bg-red-500}.priority-important{@apply bg-amber-50 text-amber-800}.priority-important:before{@apply bg-amber-500}.empty{@apply col-span-full rounded-[28px] border border-dashed border-ink/15 bg-paper/60 px-5 py-16 text-center}.empty-icon{@apply mx-auto mb-4 grid size-14 place-items-center rounded-full bg-mint text-2xl}.empty h2{@apply mb-2}.empty .button{@apply mt-5}
|
||||
.request-layout{@apply grid gap-5 lg:grid-cols-[minmax(0,1fr)_300px]}.request-form{@apply order-2 lg:order-1}.request-aside{@apply order-1 lg:order-2}.step-title{@apply mb-5 flex items-center gap-3 border-b border-ink/6 pb-4}.step-number{@apply grid size-8 shrink-0 place-items-center rounded-full bg-ink text-xs font-black text-white}.field{@apply mb-5}.expert-picker{@apply mb-7 grid grid-cols-2 gap-2 border-0 p-0 sm:grid-cols-3}.expert-picker legend{@apply col-span-full mb-3 text-sm font-extrabold}.expert-card{@apply relative flex min-h-36 cursor-pointer flex-col items-center justify-center rounded-[20px] border-2 border-ink/8 bg-white p-3 text-center transition hover:border-sea/30}.expert-card:has(input:checked){@apply border-sea bg-mint shadow-sm}.expert-card input{@apply absolute opacity-0}.expert-card img,.expert-avatar{@apply mb-2 grid size-14 place-items-center rounded-full bg-cream object-cover text-xl font-black text-sea}.expert-card strong{@apply text-xs}.expert-card small{@apply mt-1 text-[10px] text-ink/45}.expert-empty{@apply col-span-full}.upload-zone{@apply my-5 rounded-[22px] border-2 border-dashed border-ink/15 bg-cream/60 p-5 text-center transition hover:border-sea/40}.upload-zone>label{@apply cursor-pointer text-sm text-sea}.file-preview{@apply mt-3 grid grid-cols-2 gap-2 sm:grid-cols-3}.file-chip{@apply relative overflow-hidden rounded-xl border border-ink/8 bg-white p-2}.file-chip img{@apply h-24 w-full rounded-lg object-cover}.file-chip button{@apply absolute left-1 top-1 min-h-0 rounded-lg bg-coral px-2 py-0.5}.voice-recorder,.voice{@apply my-4 rounded-[22px] border border-sea/15 bg-mint/65 p-4}.voice-head,.voice-actions,.voice{@apply flex flex-wrap items-center gap-2}.voice-head{@apply justify-between}.voice-actions{@apply mt-3}.voice-actions button,.voice button{@apply min-h-10 rounded-xl px-3 py-2 text-xs}.ghost{@apply border border-coral/20 bg-white text-coral}.submit-ticket{@apply w-full bg-sea text-base}.help-card{@apply rounded-[26px] bg-ink p-6 text-white}.help-card h3{@apply text-white}.help-list{@apply mt-5 grid gap-4}.help-item{@apply flex gap-3 text-sm text-white/60}.help-item b{@apply grid size-7 shrink-0 place-items-center rounded-full bg-white/10 text-xs text-white}
|
||||
.conversation-shell{@apply grid gap-4 lg:grid-cols-[minmax(0,1fr)_280px]}.conversation-column{@apply min-w-0}.conversation{@apply flex max-h-[62vh] min-h-72 flex-col gap-3 overflow-y-auto rounded-[26px] bg-[#e9e5dc] p-3 sm:p-5}.message{@apply w-fit max-w-[92%] rounded-[20px] rounded-tr-md bg-paper px-4 py-3 shadow-sm sm:max-w-[78%]}.message.mine{@apply mr-auto rounded-tr-[20px] rounded-tl-md bg-[#cfeee7]}.message.note{@apply max-w-full rounded-[20px] border border-dashed border-amber-400 bg-[#fff3ce]}.message header{@apply mb-1 flex justify-between gap-6 text-[10px]}.message header b{@apply text-ink/65}.message time{@apply text-ink/35}.message p{@apply break-words text-sm leading-7}.attachment{@apply mt-2 flex rounded-xl bg-white/70 px-3 py-2 text-xs font-bold text-sea}.message-actions{@apply mt-2 flex justify-end gap-2 text-[10px]}.message-actions details{@apply m-0}.composer{@apply mt-3 rounded-[26px] border border-ink/7 bg-paper p-4 shadow-panel sm:p-5}.composer textarea{@apply min-h-24 border-0 bg-cream/70 shadow-none}.mode{@apply mb-4 grid grid-cols-2 gap-1 rounded-2xl bg-cream p-1}.mode button{@apply min-h-10 bg-transparent text-ink/50 shadow-none hover:translate-y-0}.mode button.active{@apply bg-ink text-white}.mode button.note-button.active{@apply bg-amber-500 text-ink}.ticket-side{@apply grid gap-3 self-start lg:sticky lg:top-23}.info-card{@apply rounded-[22px] border border-ink/7 bg-paper p-5}.info-list{@apply mt-4 grid gap-3}.info-row{@apply flex items-start justify-between gap-3 border-b border-ink/5 pb-3 text-xs last:border-0 last:pb-0}.info-row span{@apply text-ink/45}.info-row b{@apply text-left}.history-item{@apply mt-2 flex flex-col gap-1 border-t border-ink/6 pt-3 text-xs}.grant{@apply mt-2 flex items-center justify-between gap-2 rounded-xl bg-cream p-2 text-xs}.danger-button{@apply min-h-9 bg-coral px-3 py-1.5}
|
||||
.stats-grid{@apply mb-5 grid grid-cols-2 gap-2 lg:grid-cols-4}.stat-card{@apply rounded-[20px] border border-ink/6 bg-paper p-4}.stat-label{@apply text-[11px] font-bold text-ink/40}.stat-value{@apply mt-2 text-2xl font-black}.stat-card.alert .stat-value{@apply text-coral}.dashboard{@apply grid grid-cols-1 gap-4 xl:grid-cols-[270px_minmax(0,1fr)]}.filters{@apply self-start rounded-[24px] border border-ink/7 bg-paper p-4 xl:sticky xl:top-23}.filter-heading{@apply mb-4 flex items-center justify-between}.tabs{@apply mb-5 grid grid-cols-2 gap-1 border-b border-ink/6 pb-4}.tabs a{@apply rounded-xl px-3 py-2 text-[11px] font-bold text-ink/50 hover:bg-mint hover:text-sea-dark}.filter-form{@apply grid gap-3 sm:grid-cols-2 xl:grid-cols-1}.check{@apply flex min-h-11 items-center gap-2 rounded-xl bg-cream px-3}.check input{@apply size-4 accent-sea}.staff-list{@apply grid gap-2}.staff-ticket{@apply grid grid-cols-[1fr_auto] gap-4 rounded-[22px] border border-ink/7 bg-paper p-4 text-ink shadow-panel transition hover:border-sea/25 hover:shadow-lift sm:p-5}.staff-ticket-main{@apply min-w-0}.staff-ticket-head{@apply flex flex-wrap items-center gap-2}.staff-ticket h2{@apply mt-2 truncate text-base}.staff-ticket p{@apply mt-2 text-xs text-ink/50}.staff-ticket-side{@apply flex flex-col items-end justify-between gap-3}.staff-ticket-badges{@apply flex flex-wrap justify-end gap-1}.staff-layout{@apply grid gap-4 xl:grid-cols-[240px_minmax(0,1fr)_240px] xl:items-start}.staff-layout>aside{@apply grid gap-3 self-start xl:sticky xl:top-23}.staff-layout>div{@apply min-w-0}.staff-layout dl{@apply grid grid-cols-[auto_1fr] gap-2 text-xs}.staff-layout dt{@apply text-ink/45}.staff-layout dd{@apply m-0 text-left font-bold}.staff-layout aside form{@apply mt-3 border-t border-ink/6 pt-3}.staff-layout aside form button{@apply w-full}.staff-layout aside details{@apply rounded-xl border border-ink/8 p-3}.staff-layout aside summary{@apply cursor-pointer text-sm font-bold}
|
||||
.auth-shell{@apply mx-auto grid min-h-[calc(100vh-9rem)] max-w-5xl items-center gap-8 lg:grid-cols-2}.auth-intro{@apply hidden lg:block}.auth-intro-icon{@apply mb-6 grid size-14 place-items-center rounded-[18px] bg-sea text-2xl text-white}.auth-intro h2{@apply text-5xl}.auth-intro p{@apply mt-4 max-w-md text-ink/55}.auth{@apply mx-auto w-full max-w-md p-6 sm:p-8}.auth form{@apply mt-6}.auth button{@apply w-full}.auth-links{@apply mt-6 flex justify-between gap-3 border-t border-ink/6 pt-5 text-xs font-bold}.eyebrow{@apply mb-2 text-[11px] font-black tracking-wider text-sea}
|
||||
}
|
||||
.conversation{background-color:var(--theme-thread)}.message.mine{background-color:var(--theme-own-message)}.message.note{background-color:var(--theme-note);border-color:var(--color-coral)}.hero-panel{border-bottom:4px solid var(--color-coral);background-image:linear-gradient(135deg,var(--color-ink),var(--color-ink-soft))}.submit-ticket{box-shadow:0 10px 30px -14px var(--color-sea)}.stats-grid .stat-card:nth-child(1) .stat-value{color:var(--color-sea)}.stats-grid .stat-card:nth-child(2){border-top:3px solid var(--color-sea-dark)}.stats-grid .stat-card:nth-child(3){background:var(--color-mint)}.stats-grid .stat-card:nth-child(4){border-top:3px solid var(--color-coral)}.ticket-card:nth-child(3n+2):before{background-color:var(--color-sea-dark)}.ticket-card:nth-child(3n):before{background-color:var(--color-coral)}.step-title:nth-of-type(2) .step-number{background:var(--color-sea-dark)}.help-card{border-top:4px solid var(--color-coral)}
|
||||
|
||||
/* Nexus-inspired operational rhythm, adapted for the Persian RTL product. */
|
||||
.dashboard-hero{@apply relative mb-4 grid overflow-hidden rounded-[18px] bg-ink p-5 text-white shadow-panel sm:grid-cols-[1fr_auto] sm:items-end sm:p-7}.dashboard-hero:before{@apply pointer-events-none absolute -left-16 -top-24 size-64 rounded-full bg-sea/25 blur-2xl content-['']}.dashboard-hero:after{@apply pointer-events-none absolute bottom-0 right-0 h-1 w-1/3 bg-coral content-['']}.dashboard-hero-copy,.dashboard-signal{@apply relative z-10}.dashboard-overline{@apply mb-5 flex items-center gap-2 text-[10px] font-extrabold tracking-wider text-mint}.live-dot{@apply relative size-2 rounded-full bg-coral}.live-dot:after{@apply absolute inset-0 animate-ping rounded-full bg-coral content-['']}.dashboard-hero h1{@apply text-3xl sm:text-4xl}.dashboard-hero p{@apply mt-2 max-w-2xl text-sm text-white/55}.dashboard-signal{@apply mt-6 flex min-w-48 flex-col border-r border-white/15 pr-4 sm:mt-0}.dashboard-signal span,.dashboard-signal small{@apply text-[10px] text-white/45}.dashboard-signal strong{@apply my-1 text-sm text-white}
|
||||
.stats-grid{@apply gap-2}.stat-card{@apply relative min-h-32 overflow-hidden rounded-[14px] p-4 shadow-none transition hover:-translate-y-0.5 hover:border-sea/25 hover:shadow-panel}.stat-card:after{@apply absolute -bottom-8 -left-8 size-20 rounded-full bg-sea/5 content-['']}.stat-head{@apply flex items-start justify-between}.metric-mark,.panel-index{@apply font-mono text-[9px] font-bold tracking-widest text-ink/25}.stat-value{@apply text-3xl leading-none}.stat-card small{@apply mt-3 block text-[10px] text-ink/40}.stats-grid .stat-card:nth-child(3){background:linear-gradient(145deg,var(--color-mint),var(--color-paper))}.stats-grid .stat-card:nth-child(4){background:linear-gradient(145deg,var(--theme-note),var(--color-paper))}
|
||||
.dashboard{@apply gap-3 xl:grid-cols-[250px_minmax(0,1fr)]}.filters,.ticket-stream{@apply rounded-[16px] border border-ink/7 bg-paper shadow-panel}.filters{@apply p-4}.filter-heading{@apply items-start border-b border-ink/6 pb-4}.filter-heading h3,.stream-head h2{@apply mt-1 text-sm}.filter-heading a{@apply text-[10px] font-bold text-sea}.tabs{@apply grid-cols-1 gap-0.5}.tabs a{@apply flex min-h-9 items-center justify-between rounded-lg px-3 py-2}.tabs a:after{@apply text-ink/20 content-['←']}.filter-form label{@apply text-xs}.filter-form input,.filter-form select{@apply rounded-xl py-2.5}.ticket-stream{@apply min-w-0 overflow-hidden}.stream-head{@apply flex items-center justify-between border-b border-ink/7 px-4 py-4 sm:px-5}.stream-status{@apply flex items-center gap-2 rounded-full bg-mint px-3 py-1 text-[10px] font-extrabold text-sea-dark}.stream-status i{@apply size-1.5 rounded-full bg-sea}.ticket-stream .staff-list{@apply gap-0}.ticket-stream .staff-ticket{@apply rounded-none border-x-0 border-t-0 p-4 shadow-none last:border-b-0 hover:translate-y-0 hover:border-sea/20 hover:bg-mint/30 hover:shadow-none}.ticket-stream .staff-ticket h2{@apply text-sm}.ticket-stream .staff-ticket p{@apply mt-1}.ticket-stream .staff-ticket:before{@apply absolute right-0 top-0 h-full w-0 bg-sea transition-all content-['']}.ticket-stream .staff-ticket:hover:before{@apply w-1}
|
||||
@media (prefers-reduced-motion:reduce){.live-dot:after{animation:none}.stat-card,.staff-ticket{transition:none}}
|
||||
|
||||
/* Focused ticket conversation workspace */
|
||||
body:has(.ticket-workspace){overflow:hidden}.customer-main:has(.ticket-workspace),.staff-content:has(.ticket-workspace){max-width:none;padding:0}.ticket-workspace{height:calc(100dvh - 4.25rem);min-height:32rem;background:var(--color-soft);overflow:hidden}.ticket-workspace-head{@apply flex min-h-18 items-center justify-between gap-3 border-b border-ink/8 bg-paper px-3 py-2 sm:px-5}.ticket-title{@apply flex min-w-0 items-center gap-3}.ticket-title>div{@apply min-w-0}.ticket-title h1{@apply truncate text-base sm:text-xl}.workspace-back,.icon-button{@apply grid size-10 shrink-0 place-items-center rounded-xl border border-ink/8 bg-cream text-ink shadow-none transition hover:border-sea/30 hover:bg-mint}.ticket-head-actions{@apply flex shrink-0 items-center gap-2}.ticket-head-actions form{@apply m-0}.ticket-head-actions form button{@apply min-h-10 rounded-xl px-3 py-2}.workspace-grid{display:grid;height:calc(100% - 4.5rem);min-height:0}.customer-grid{grid-template-columns:minmax(0,1fr) 280px}.staff-conversation-grid{grid-template-columns:240px minmax(0,1fr) 240px}.conversation-pane{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr) auto;min-width:0;min-height:0;background:var(--color-paper);border-inline:1px solid rgba(8,55,107,.07)}.conversation-toolbar{@apply flex min-h-12 items-center justify-between border-b border-ink/6 bg-paper px-4}.conversation-toolbar>div{@apply flex items-center gap-2 text-xs}.conversation-toolbar small{@apply text-[10px] text-ink/40}
|
||||
.ticket-workspace .conversation{display:block;max-height:none;min-height:0;overflow-y:auto;overscroll-behavior:contain;scroll-behavior:smooth;border-radius:0;padding:1rem;background:linear-gradient(180deg,var(--color-soft),var(--color-cream));scrollbar-gutter:stable}.ticket-workspace .conversation:focus-visible{outline:3px solid color-mix(in srgb,var(--color-sea) 25%,transparent);outline-offset:-3px}.ticket-workspace .message{position:relative;display:flex;width:100%;max-width:none;gap:.625rem;border-radius:0;background:transparent;padding:0;box-shadow:none;margin:.65rem 0}.ticket-workspace .message.mine{flex-direction:row-reverse;background:transparent}.message-avatar{@apply grid size-8 shrink-0 place-items-center rounded-xl bg-ink text-[11px] font-black text-white}.message.mine .message-avatar{@apply bg-sea}.message.note .message-avatar{@apply bg-coral text-ink}.message-bubble{position:relative;max-width:min(78%,46rem);border:1px solid rgba(8,55,107,.07);border-radius:18px 5px 18px 18px;background:var(--color-paper);padding:.7rem .85rem;box-shadow:0 8px 24px -22px rgba(8,55,107,.65)}.message.mine .message-bubble{border-radius:5px 18px 18px 18px;background:var(--theme-own-message)}.message.note{justify-content:center}.message.note .message-bubble{width:min(92%,52rem);max-width:none;border:1px dashed color-mix(in srgb,var(--color-coral) 60%,transparent);border-radius:14px;background:var(--theme-note)}.message-bubble header{@apply mb-1.5 flex flex-wrap items-center gap-2}.message-bubble header time{@apply mr-auto}.internal-label{@apply rounded-full bg-coral/15 px-2 py-0.5 text-[9px] font-black text-ink}.message-bubble>p{@apply text-sm leading-7}.edited-label,.revision-link{@apply ml-2 text-[9px] text-ink/35}.revision-link{@apply font-bold text-sea}.deleted-message{@apply italic text-ink/40}.date-divider{@apply sticky top-1 z-10 my-4 flex items-center justify-center}.date-divider span{@apply rounded-full border border-ink/8 bg-paper/90 px-3 py-1 text-[9px] font-bold text-ink/45 shadow-sm backdrop-blur}
|
||||
.attachment-list{@apply mt-3 grid gap-2}.attachment{margin-top:0}.attachment-image{@apply block max-w-72 overflow-hidden p-1}.attachment-image img{@apply max-h-52 w-full rounded-lg object-cover}.attachment-image span{@apply block truncate px-2 py-1 text-[10px]}.attachment-file{@apply flex max-w-sm items-center gap-3 bg-white/75}.file-icon{@apply grid size-9 shrink-0 place-items-center rounded-lg bg-mint text-lg}.attachment-file b,.attachment-file small{@apply block}.attachment-file small{@apply mt-0.5 text-[9px] font-normal text-ink/40}.attachment-audio{@apply block max-w-md}.attachment-audio audio{@apply my-2 h-10 w-full}.attachment-audio>a{@apply text-[10px]}.message-menu{position:absolute;top:.35rem;left:.35rem}.message.mine .message-menu{left:auto;right:.35rem}.message-menu>summary{@apply grid size-8 cursor-pointer list-none place-items-center rounded-full text-xs tracking-widest text-ink/40 transition hover:bg-white hover:text-sea;box-shadow:none}.message-menu>summary::-webkit-details-marker{display:none}.message-menu[open]>summary{@apply bg-white text-sea;box-shadow:0 5px 15px -10px #08376b}.message-menu-panel{@apply absolute left-0 z-20 mt-1 w-72 overflow-hidden rounded-2xl border border-ink/10 bg-paper shadow-xl}.message.mine .message-menu-panel{right:0;left:auto}.message-menu-head{@apply flex items-center justify-between border-b border-ink/8 bg-ink/[.025] px-4 py-3}.message-menu-head b,.message-menu-head small{@apply block}.message-menu-head b{@apply text-xs text-ink}.message-menu-head small{@apply mt-0.5 text-[9px] font-normal text-ink/45}.message-menu-close{@apply grid size-8 min-h-0 place-items-center rounded-full bg-transparent p-0 text-lg font-normal text-ink/45 shadow-none hover:bg-ink/5 hover:text-ink}.message-edit-form{@apply p-4}.message-edit-form label{@apply mb-1.5 text-[10px] text-ink/65}.message-menu-panel textarea{@apply min-h-24 rounded-xl bg-ink/[.025] p-3 text-xs leading-6 shadow-none}.message-menu-actions{@apply mt-3 grid grid-cols-2 gap-2}.message-menu-actions button{@apply m-0 min-h-10 w-full rounded-xl px-3 py-2 text-xs}.message-edit-save{@apply bg-sea}.message-edit-cancel{@apply border border-ink/10 bg-white text-ink/60 shadow-none hover:bg-ink/5 hover:text-ink}.message-delete-zone{@apply flex items-center justify-between gap-3 border-t border-red-200 bg-red-50/50 px-4 py-3}.message-delete-zone b,.message-delete-zone small{@apply block}.message-delete-zone b{@apply text-[10px] text-red-700}.message-delete-zone small{@apply mt-0.5 text-[9px] text-red-700/60}.message-delete-zone form{@apply m-0}.message-delete-button{@apply m-0 min-h-8 rounded-lg border border-red-200 bg-white px-3 py-1 text-[10px] text-red-700 shadow-none hover:bg-red-500 hover:text-white}@media(max-width:639px){.message-menu-panel{position:fixed;right:.75rem!important;bottom:5rem;left:.75rem!important;top:auto;width:auto;max-height:calc(100dvh - 7rem);overflow:auto}}.conversation-empty{@apply grid h-full min-h-64 place-content-center text-center}.conversation-empty>span{@apply mx-auto mb-3 grid size-12 place-items-center rounded-full bg-mint text-sea}.conversation-empty p{@apply mt-1 text-xs text-ink/45}
|
||||
.ticket-workspace .composer{position:relative;z-index:15;margin:0;border:0;border-top:1px solid rgba(8,55,107,.08);border-radius:0;padding:.65rem .85rem max(.65rem,env(safe-area-inset-bottom));box-shadow:0 -14px 40px -30px rgba(8,55,107,.55)}.composer-context{@apply mb-2 flex items-start justify-between}.composer-context b,.composer-context small{@apply block}.composer-context b{@apply text-xs}.composer-context small,.composer-context>[data-draft-status]{@apply mt-0.5 text-[9px] text-ink/40}.ticket-workspace .composer textarea{max-height:9rem;min-height:2.75rem;resize:none;border-radius:13px;background:var(--color-cream);padding:.7rem .85rem;line-height:1.7}.ticket-workspace input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.composer-bar{@apply mt-2 flex items-center gap-2}.composer-tools{@apply flex items-center gap-1}.tool-button{@apply mb-0 inline-flex min-h-10 cursor-pointer items-center gap-1 rounded-xl border border-ink/8 bg-paper px-3 text-xs font-bold text-ink shadow-none hover:border-sea/30 hover:bg-mint}.tool-button span{@apply hidden sm:inline}.composer-hint{@apply hidden flex-1 text-center text-[9px] text-ink/30 lg:block}.send-button{@apply mr-auto min-h-10 rounded-xl bg-sea px-4 py-2}.compact-recorder{@apply my-2 rounded-xl p-3}.compact-recorder[hidden],.composer-extra[hidden]{display:none}.composer-extra{@apply mt-2 rounded-xl border border-ink/8 bg-cream p-3}.composer-extra label{@apply text-xs}.new-message-jump{@apply absolute bottom-36 left-1/2 z-20 min-h-9 -translate-x-1/2 rounded-full bg-ink px-4 py-2 text-[10px] shadow-xl}.new-message-jump[hidden]{display:none}.staff-composer .mode{@apply mb-2}.staff-composer.note-mode{background:var(--theme-note);border-top-color:color-mix(in srgb,var(--color-coral) 45%,transparent)}.staff-composer.note-mode textarea{@apply bg-white}.staff-composer.note-mode .send-button{@apply bg-coral text-ink}.file-preview:empty{display:none}.ticket-workspace .file-preview{@apply mb-2 mt-2 grid grid-cols-2 gap-2 sm:grid-cols-4}.ticket-workspace .file-chip{@apply text-[9px]}
|
||||
.workspace-side{min-height:0;overflow-y:auto;padding:.75rem;background:var(--color-cream)}.workspace-side .info-card{@apply mb-3 rounded-[14px] p-4 shadow-none}.panel-close{@apply hidden}.ticket-operations form{@apply mt-3 border-t border-ink/6 pt-3}.ticket-operations form button{@apply w-full}.ticket-operations details{@apply mt-3 rounded-xl border border-ink/8 p-3}.ticket-operations summary{@apply cursor-pointer text-xs font-bold}
|
||||
@media(max-width:1023px){body:has(.ticket-workspace) .mobile-dock,body:has(.ticket-workspace) .staff-mobile-dock{display:none}.ticket-workspace{height:calc(100dvh - 4.25rem)}.staff-conversation-grid,.customer-grid{grid-template-columns:minmax(0,1fr)}.workspace-side{position:fixed;inset:4.25rem 0 0 auto;z-index:60;width:min(88vw,22rem);transform:translateX(105%);border-left:1px solid rgba(8,55,107,.1);box-shadow:-20px 0 60px -35px rgba(8,55,107,.7);transition:transform .25s ease}.workspace-side.panel-open{transform:translateX(0)}.panel-close{@apply mb-3 grid size-10 place-items-center rounded-xl bg-ink text-white}.message-bubble{max-width:86%}}
|
||||
@media(max-width:639px){.site-header{display:none}.customer-main:has(.ticket-workspace){padding:0}.ticket-workspace{height:100dvh}.ticket-workspace-head{@apply min-h-16}.workspace-grid{height:calc(100% - 4rem)}.ticket-title h1{@apply max-w-[48vw] text-sm}.ticket-head-actions .badge{@apply max-w-24 truncate}.conversation-toolbar{@apply min-h-10}.ticket-workspace .conversation{@apply px-2.5 py-3}.message-avatar{@apply size-7 rounded-lg}.message-bubble{max-width:88%;padding:.6rem .7rem}.message.note .message-bubble{width:96%}.ticket-workspace .composer{@apply px-2.5 pt-2}.composer-context small{max-width:70vw}.composer-hint{display:none}.send-button{@apply px-3}.new-message-jump{bottom:8.5rem}.ticket-head-actions form{display:none}}
|
||||
@media(prefers-reduced-motion:reduce){.ticket-workspace .conversation{scroll-behavior:auto}.workspace-side{transition:none}}
|
||||
.load-older{@apply mx-auto my-3 flex min-h-9 rounded-full border border-ink/10 bg-paper px-4 py-2 text-[10px] font-bold text-sea shadow-sm hover:bg-mint}.load-older.htmx-request{@apply pointer-events-none opacity-60}
|
||||
|
||||
/* Ticket correspondence: deliberate long-form replies, not instant chat. */
|
||||
.ticket-workspace .conversation{background:var(--color-cream)}.ticket-workspace .message,.ticket-workspace .message.mine{display:grid;grid-template-columns:2.25rem minmax(0,1fr);align-items:start;gap:.75rem;margin:1rem auto;max-width:58rem}.ticket-workspace .message.mine{flex-direction:initial}.message-bubble,.message.mine .message-bubble{width:100%;max-width:none;border-radius:10px;border-right:3px solid var(--color-sea);background:var(--color-paper);padding:1rem 1.1rem;box-shadow:0 8px 24px -24px rgba(8,55,107,.7)}.message.mine .message-bubble{border-right-color:var(--color-ink);background:var(--color-paper)}.message.note{display:grid;justify-content:initial}.message.note .message-bubble{width:100%;max-width:none;border:1px solid color-mix(in srgb,var(--color-coral) 45%,transparent);border-right:3px solid var(--color-coral);border-radius:10px;background:var(--theme-note)}.message-bubble>p{font-size:.875rem;line-height:2;text-align:justify}.message-bubble header{padding-bottom:.5rem;border-bottom:1px solid rgba(8,55,107,.06)}.message-avatar{border-radius:9px}.ticket-workspace .composer{padding:1rem 1.1rem max(1rem,env(safe-area-inset-bottom));border-top:3px solid var(--color-sea);background:var(--color-paper)}.composer-context{margin-bottom:.75rem}.composer-context b{font-size:.875rem}.composer-context small{margin-top:.25rem;font-size:.6875rem;line-height:1.7}.ticket-workspace .composer textarea{min-height:7rem;max-height:15rem;border-radius:10px;background:#fff;border-color:rgba(8,55,107,.14);padding:.9rem 1rem}.ticket-workspace .composer textarea:focus{background:#fff}.composer-bar{margin-top:.75rem;padding-top:.75rem;border-top:1px solid rgba(8,55,107,.06)}.send-button{min-height:2.75rem;border-radius:10px;padding-inline:1.1rem}.staff-composer.note-mode{border-top:3px solid var(--color-coral)}.mode{max-width:30rem}.mode button{border-radius:9px}.date-divider{position:static}.date-divider span{background:transparent;border:0;box-shadow:none}.new-message-jump{bottom:17rem}
|
||||
@media(max-width:639px){.ticket-workspace .message,.ticket-workspace .message.mine{grid-template-columns:1.75rem minmax(0,1fr);gap:.5rem;margin:.75rem 0}.message-bubble,.message.mine .message-bubble{max-width:none;padding:.8rem}.message-bubble>p{text-align:start}.ticket-workspace .composer textarea{min-height:6rem}.composer-bar{flex-wrap:wrap}.composer-tools{order:2}.send-button{order:1;width:100%;margin:0}.composer-hint{display:block;order:3;width:100%;text-align:right}.new-message-jump{bottom:19rem}}
|
||||
|
||||
/* Collapsible reply panel keeps the correspondence history dominant. */
|
||||
.ticket-workspace .composer.is-collapsed{padding:.55rem .85rem;border-top:1px solid rgba(8,55,107,.1);background:var(--color-paper)}.composer.is-collapsed>form,.composer.is-collapsed>.mode{display:none}.composer-launch{display:none;width:100%;min-height:3.5rem;align-items:center;justify-content:flex-start;gap:.75rem;border:1px solid rgba(8,55,107,.1);border-radius:11px;background:linear-gradient(135deg,var(--color-paper),var(--color-mint));padding:.55rem .75rem;color:var(--color-ink);box-shadow:none;text-align:right}.composer.is-collapsed .composer-launch{display:flex}.composer-launch:hover{transform:none;border-color:color-mix(in srgb,var(--color-sea) 35%,transparent);background:var(--color-mint)}.composer-launch-icon{@apply grid size-9 shrink-0 place-items-center rounded-lg bg-sea text-lg text-white}.composer-launch b,.composer-launch small{display:block}.composer-launch b{@apply text-xs}.composer-launch small{@apply mt-0.5 text-[9px] font-medium text-ink/45}.composer-launch-arrow{@apply mr-auto text-sm text-sea}.composer-close{@apply text-ink/55}.composer:not(.is-collapsed) .composer-launch{display:none}.composer.is-collapsed~*{transition:none}.composer.is-collapsed+.new-message-jump{bottom:5rem}.ticket-workspace .composer.is-collapsed{box-shadow:0 -10px 30px -28px rgba(8,55,107,.65)}
|
||||
@media(max-width:639px){.ticket-workspace .composer.is-collapsed{@apply px-2.5 py-2}.composer-launch{min-height:3.25rem}.composer-launch small{max-width:65vw}.composer-close{order:3}.new-message-jump{bottom:5.5rem}.ticket-workspace .composer:not(.is-collapsed){max-height:62dvh;overflow-y:auto}}
|
||||
.conversation-pane:has(.composer.is-collapsed) .new-message-jump{bottom:5rem}.conversation-pane:not(:has(.composer.is-collapsed)) .new-message-jump{bottom:17rem}@media(max-width:639px){.conversation-pane:has(.composer.is-collapsed) .new-message-jump{bottom:5.5rem}.conversation-pane:not(:has(.composer.is-collapsed)) .new-message-jump{bottom:19rem}}
|
||||
body:has(.ticket-workspace) .flash{position:fixed;top:5rem;left:50%;z-index:100;width:min(calc(100% - 2rem),42rem);margin:0;transform:translateX(-50%);box-shadow:0 18px 50px -25px rgba(8,55,107,.55);animation:flash-in .22s ease-out}.flash{position:relative;padding-left:3rem}.flash-close{position:absolute;left:.5rem;top:50%;min-height:2rem;width:2rem;transform:translateY(-50%);border-radius:.5rem;background:transparent;padding:0;color:currentColor;box-shadow:none}.flash-close:hover{transform:translateY(-50%);background:rgba(255,255,255,.6)}.flash-leaving{opacity:0;transform:translate(-50%,-.5rem)!important;transition:.25s ease}@keyframes flash-in{from{opacity:0;transform:translate(-50%,-.5rem)}to{opacity:1;transform:translate(-50%,0)}}
|
||||
.flash.flash-leaving{transform:none!important}body:has(.ticket-workspace) .flash.flash-leaving{transform:translate(-50%,-.5rem)!important}
|
||||
|
||||
/* Searchable Iran province/city fields shared by profile and new-ticket forms. */
|
||||
.location-fields{@apply mb-6 rounded-2xl border border-sea/15 bg-mint/40 p-4 sm:p-5}.location-heading{@apply mb-4 flex items-start justify-between gap-3}.location-heading p{@apply mt-1 text-xs text-ink/50}.location-heading>span{@apply shrink-0 rounded-full bg-sea/10 px-3 py-1 text-[10px] font-black text-sea}.location-fields .field{@apply mb-0}.location-fields input:disabled{@apply cursor-not-allowed bg-slate-100 text-ink/40}.location-hint{@apply mb-0 mt-3 text-[11px] font-medium text-ink/50}.location-hint.is-error{@apply text-red-700}
|
||||
|
||||
/* Staff operations UI: compact queues, explicit state, and consistent navigation. */
|
||||
.staff-shell{@apply bg-soft lg:grid-cols-[264px_minmax(0,1fr)]}.staff-sidebar{position:sticky;top:0;height:100dvh;overflow-y:auto;background:linear-gradient(180deg,var(--color-ink),#06284d);padding:1.25rem}.staff-brand{@apply mb-8 rounded-2xl p-2 text-white hover:bg-white/5}.staff-menu-label{@apply mb-2 px-3 text-[10px] font-black tracking-wider text-white/35}.staff-menu{@apply gap-1}.staff-menu a{position:relative;min-height:2.9rem;border:1px solid transparent;border-radius:.75rem;padding:.65rem .75rem;color:rgba(255,255,255,.62)}.staff-menu a>span{@apply grid size-8 shrink-0 place-items-center rounded-lg bg-white/7 text-base}.staff-menu a>b{@apply text-xs}.staff-menu a:hover{@apply bg-white/7 text-white}.staff-menu a.active{background:linear-gradient(135deg,var(--color-sea),var(--color-blue));border-color:rgba(255,255,255,.15);box-shadow:0 14px 28px -18px rgba(6,147,227,.8)}.staff-menu a.active:after{position:absolute;right:-1.25rem;width:.22rem;height:1.75rem;border-radius:.25rem 0 0 .25rem;background:var(--color-coral);content:''}.staff-menu a.active>span{@apply bg-white/15}.staff-profile{@apply flex items-center gap-3 border border-white/8 bg-white/5 p-3}.staff-profile-avatar{@apply grid size-10 shrink-0 place-items-center rounded-xl bg-coral font-black text-ink}.staff-profile>div>span{@apply block}.staff-topbar{@apply h-[4.5rem] border-ink/7 bg-paper/90}.staff-topbar>div:first-child small{@apply text-[9px] font-bold text-sea}.staff-topbar h2{@apply mt-0.5 text-sm}.staff-content{@apply max-w-[1560px] pt-5 lg:px-8}
|
||||
.staff-page-head{@apply mb-5 flex flex-col justify-between gap-4 rounded-2xl border border-ink/7 bg-paper p-5 shadow-panel sm:flex-row sm:items-end sm:p-6}.staff-page-head h1{@apply mt-1 text-2xl sm:text-3xl}.staff-page-head p:last-child{@apply mt-2 max-w-2xl text-xs text-ink/50 sm:text-sm}.staff-sync{@apply flex shrink-0 items-center gap-3 rounded-xl border border-sea/10 bg-mint px-4 py-2.5}.staff-sync b,.staff-sync small{@apply block}.staff-sync b{@apply text-xs text-sea-dark}.staff-sync small{@apply mt-0.5 text-[9px] text-ink/40}
|
||||
.stats-grid{@apply gap-3}.stat-card{position:relative;overflow:hidden;border-radius:1rem;padding:1rem;color:var(--color-ink);box-shadow:0 10px 30px -28px rgba(8,55,107,.8);transition:.2s ease}.stat-card[href]:hover{@apply -translate-y-0.5 border-sea/25 shadow-lift}.stat-card.is-active{@apply border-sea bg-mint}.stat-card.is-active:after{position:absolute;inset:auto 0 0;height:.2rem;background:var(--color-sea);content:''}.stat-head{@apply flex items-center gap-2}.stat-icon{@apply grid size-7 place-items-center rounded-lg bg-mint text-xs font-black text-sea}.stat-card.alert .stat-icon{@apply bg-coral/15 text-coral}.stat-value{@apply mt-3}.stat-card small{@apply text-[10px] text-ink/45}
|
||||
.queue-switcher{@apply mb-4 flex gap-1 overflow-x-auto rounded-xl border border-ink/7 bg-paper p-1.5 shadow-sm}.queue-switcher a{@apply shrink-0 rounded-lg px-3 py-2 text-[10px] font-bold text-ink/50 hover:bg-mint hover:text-sea-dark}.queue-switcher a.active{@apply bg-ink text-white shadow-sm}.dashboard{@apply items-start xl:grid-cols-[260px_minmax(0,1fr)]}.filters{@apply border-ink/8}.filter-heading{@apply mb-3}.filter-form{@apply gap-2.5}.filter-form label{@apply mb-0}.filter-form button{@apply mt-1 w-full rounded-xl}.search-field input{background-image:linear-gradient(transparent,transparent)}.stream-meta{@apply flex items-center gap-2}.stream-meta>span:first-child{@apply hidden text-[10px] font-bold text-ink/40 sm:inline}.ticket-stream{@apply border-ink/8}.stream-head{@apply min-h-16 bg-cream/45}.stream-head h2{@apply text-base}
|
||||
.ticket-stream .staff-ticket{position:relative;grid-template-columns:minmax(0,1fr) auto;min-height:7.25rem;padding:1rem 1.15rem;border-right:3px solid var(--color-sea)}.ticket-stream .staff-ticket.priority-edge-important{border-right-color:var(--color-blue)}.ticket-stream .staff-ticket.priority-edge-urgent{border-right-color:var(--color-coral)}.ticket-stream .staff-ticket:hover{background:linear-gradient(90deg,var(--color-paper),var(--color-mint))}.staff-ticket-head time{@apply text-[9px] font-medium text-ink/35}.staff-ticket h2{@apply mt-2.5 truncate text-[15px]}.ticket-row-meta{@apply mt-3 flex flex-wrap items-center gap-x-3 gap-y-1 text-[10px] text-ink/45}.ticket-row-meta span{position:relative}.ticket-row-meta span+span:before{position:absolute;right:-.45rem;content:'•';color:rgba(8,55,107,.25)}.ticket-locked{@apply mt-3 rounded-lg bg-coral/10 px-3 py-2 text-[10px] font-bold text-ink/60}.staff-ticket-side{@apply min-w-32}.staff-ticket-badges{@apply flex-nowrap}.ticket-owner{@apply max-w-40 truncate text-[9px] font-bold text-ink/40}.ticket-open{@apply flex items-center gap-1 text-[10px] font-black text-sea}.ticket-open b{@apply transition}.staff-ticket:hover .ticket-open b{@apply -translate-x-1}.staff-list .empty{@apply rounded-none border-0 py-16 shadow-none}
|
||||
.staff-mobile-dock{@apply grid-cols-4}.staff-mobile-dock a{@apply rounded-xl px-1}.staff-mobile-dock a.active{background:linear-gradient(135deg,var(--color-sea),var(--color-blue))}
|
||||
@media(max-width:639px){.staff-content{@apply px-3 pt-3}.staff-page-head{@apply mb-3 p-4}.staff-page-head h1{@apply text-xl}.staff-sync{@apply w-full}.stats-grid{@apply mb-3}.stat-card{@apply p-3}.stat-value{@apply text-xl}.queue-switcher{@apply -mx-1}.dashboard{@apply gap-3}.filters{@apply p-3}.filter-form{@apply grid-cols-2}.filter-form .search-field,.filter-form .check,.filter-form button{@apply col-span-2}.ticket-stream .staff-ticket{@apply grid-cols-1 gap-3 p-3.5}.staff-ticket-side{@apply min-w-0 flex-row items-center}.ticket-owner{display:none}.ticket-open{@apply mr-auto}.staff-ticket-badges{@apply justify-start}.stream-head{@apply px-3}.stream-status{display:none}}
|
||||
|
||||
/* High-contrast staff typography and semantic states. Keep critical text opaque. */
|
||||
.staff-shell{--staff-text:#123a63;--staff-muted:#526b85;--staff-subtle:#60758b;--staff-border:#ccd8e5;--status-new-bg:#e4f4ff;--status-new-fg:#07517f;--status-open-bg:#e6ebff;--status-open-fg:#263d8f;--status-staff-bg:#fff0cf;--status-staff-fg:#754000;--status-customer-bg:#dff1ff;--status-customer-fg:#07518b;--status-reopened-bg:#ffe4d8;--status-reopened-fg:#8a3511;--status-resolved-bg:#dff5e9;--status-resolved-fg:#17613c;--status-closed-bg:#e9edf2;--status-closed-fg:#44576b;color:var(--staff-text)}
|
||||
.staff-menu a{color:#d3e1f0}.staff-menu a:hover{color:#fff}.staff-menu a.active{background:linear-gradient(135deg,var(--color-sea),var(--color-sea-dark))}.staff-menu-label{color:#b6c9dd;font-size:.75rem}.staff-brand small,.staff-profile>div>span{color:#c2d2e3;font-size:.75rem}.staff-menu a>b{font-size:.875rem;line-height:1.6}.staff-menu a em{margin-right:auto;min-width:1.55rem;border-radius:999px;background:var(--color-coral);padding:.15rem .4rem;color:#3d2900;font-size:.75rem;font-style:normal;text-align:center}.staff-action-link:not(.active){background:rgba(250,159,0,.1);border-color:rgba(250,159,0,.22)}
|
||||
.staff-topbar>div:first-child small{color:#1977ce;font-size:.75rem}.staff-topbar h2{font-size:1rem}.staff-topbar-actions>span{color:var(--staff-muted)!important;font-size:.8rem}.staff-topbar a{color:var(--staff-text);font-size:.8rem}
|
||||
.staff-page-head .eyebrow{color:#1977ce;font-size:.75rem}.staff-page-head h1{color:#08376b;font-size:1.75rem;line-height:1.5}.staff-page-head p:last-child{color:var(--staff-muted);font-size:.875rem;line-height:1.9}.staff-sync b{color:#07517f;font-size:.8125rem}.staff-sync small{color:var(--staff-muted);font-size:.75rem}
|
||||
.stat-label{color:var(--staff-muted);font-size:.8125rem}.stat-card small{color:var(--staff-muted);font-size:.75rem}.stat-value{color:#08376b}.panel-index{color:var(--staff-muted);font-family:Vazirmatn,ui-sans-serif,system-ui;font-size:.75rem;letter-spacing:0}.queue-switcher a{color:var(--staff-muted);font-size:.8125rem}.queue-switcher a.active{color:#fff}
|
||||
.dashboard{grid-template-columns:minmax(0,1fr)}@media(min-width:1024px){.dashboard{grid-template-columns:280px minmax(0,1fr)}.filters{position:sticky;top:5.75rem}}
|
||||
.filters{border-color:var(--staff-border);background:#fff}.filter-heading{align-items:center}.filter-title{display:flex;align-items:center;gap:.65rem}.filter-icon{display:grid;width:2.25rem;height:2.25rem;place-items:center;border-radius:.65rem;background:#e4f4ff;color:#07517f;font-size:1.15rem}.filter-heading h3{margin-top:.15rem;color:#08376b;font-size:.9rem}.filter-heading>a{color:#1269ad;font-size:.75rem;text-decoration:underline;text-underline-offset:3px}.filter-form label{color:#244b72;font-size:.8125rem}.filter-form input,.filter-form select{border-color:#b9c9d9;color:#123a63;font-size:.8125rem}.check{color:#244b72!important}.check span{font-size:.8125rem}
|
||||
.stream-head .panel-index{color:#526b85}.stream-head h2{color:#08376b;font-size:1.05rem}.stream-meta>span:first-child{color:var(--staff-muted);font-size:.75rem}.stream-status{color:#07517f;font-size:.75rem}
|
||||
.ticket-stream .staff-ticket{border-bottom-color:#d5dee8;border-right-width:4px;color:var(--staff-text)}.ticket-stream .staff-ticket.status-row-waiting_staff,.ticket-stream .staff-ticket.status-row-reopened{background:linear-gradient(90deg,#fff,#fff9ec);border-right-color:#e58d00}.ticket-stream .staff-ticket.status-row-waiting_staff:hover,.ticket-stream .staff-ticket.status-row-reopened:hover{background:linear-gradient(90deg,#fff9ec,#fff2d6)}.staff-ticket-head{gap:.55rem}.staff-ticket-head .ticket-number{color:#365a7d;font-family:Vazirmatn,ui-sans-serif,system-ui;font-size:.75rem;font-weight:800}.staff-ticket-head time{margin-right:auto;color:var(--staff-muted);font-size:.75rem;font-weight:600}.staff-ticket h2{color:#08376b;font-size:1.05rem;line-height:1.8;white-space:normal}.action-required{border:1px solid #e7a027;border-radius:999px;background:#fff0cf;padding:.2rem .55rem;color:#754000;font-size:.7rem;font-weight:900}.ticket-row-meta{gap:.45rem;margin-top:.65rem;color:var(--staff-muted);font-size:.75rem}.ticket-row-meta span{display:inline-flex;align-items:center;min-height:1.8rem;border:1px solid #d3dde7;border-radius:.5rem;background:#f6f8fa;padding:.25rem .55rem;line-height:1.5}.ticket-row-meta span+span:before{display:none}.ticket-locked{color:#65420b;font-size:.75rem}.ticket-owner{max-width:11rem;color:#526b85;font-size:.75rem}.ticket-open{color:#1269ad;font-size:.78rem}.staff-ticket-badges{gap:.35rem}.staff-ticket-badges .badge{border:1px solid transparent;padding:.3rem .65rem;font-size:.75rem;line-height:1.4}.staff-ticket-badges .badge:before{width:.42rem;height:.42rem}.staff-ticket-badges .priority-normal{border-color:#cbd7e2;background:#f0f4f7;color:#3f566d}.staff-ticket-badges .priority-normal:before{background:#60758b}.staff-ticket-badges .priority-important{border-color:#e5b44e;background:#fff3d6;color:#704800}.staff-ticket-badges .priority-urgent{border-color:#e79b91;background:#ffebe8;color:#8b2d22}
|
||||
.staff-ticket-badges .status-new{border-color:#93c8e8;background:var(--status-new-bg);color:var(--status-new-fg)}.staff-ticket-badges .status-new:before{background:var(--status-new-fg)}.staff-ticket-badges .status-open{border-color:#aebbed;background:var(--status-open-bg);color:var(--status-open-fg)}.staff-ticket-badges .status-open:before{background:var(--status-open-fg)}.staff-ticket-badges .status-waiting_staff{border-color:#e3b35b;background:var(--status-staff-bg);color:var(--status-staff-fg)}.staff-ticket-badges .status-waiting_staff:before{background:#d98200}.staff-ticket-badges .status-waiting_customer{border-color:#8fc5e9;background:var(--status-customer-bg);color:var(--status-customer-fg)}.staff-ticket-badges .status-waiting_customer:before{background:#1977ce}.staff-ticket-badges .status-reopened{border-color:#e9a184;background:var(--status-reopened-bg);color:var(--status-reopened-fg)}.staff-ticket-badges .status-reopened:before{background:#b64d20}.staff-ticket-badges .status-resolved{border-color:#8dceb0;background:var(--status-resolved-bg);color:var(--status-resolved-fg)}.staff-ticket-badges .status-resolved:before{background:#218653}.staff-ticket-badges .status-closed{border-color:#bdc8d3;background:var(--status-closed-bg);color:var(--status-closed-fg)}.staff-ticket-badges .status-closed:before{background:#60758b}
|
||||
.staff-mobile-dock{grid-template-columns:repeat(6,minmax(0,1fr))}.staff-mobile-dock a{color:#c7d6e6;font-size:.6875rem}.staff-mobile-dock a.active{color:#fff;background:linear-gradient(135deg,var(--color-sea),var(--color-sea-dark))}
|
||||
@media(max-width:639px){.staff-page-head h1{font-size:1.35rem}.staff-page-head p:last-child{font-size:.8125rem}.stats-grid{grid-template-columns:repeat(2,minmax(0,1fr))}.filter-form label{font-size:.8rem}.staff-ticket h2{font-size:.95rem}.ticket-row-meta{font-size:.72rem}.staff-ticket-head time{margin-right:0}.staff-ticket-side{flex-wrap:wrap}.staff-ticket-badges .badge{font-size:.7rem}.staff-mobile-dock{inset-inline:.5rem;bottom:.5rem}.staff-mobile-dock a{font-size:.625rem}}
|
||||
|
||||
/* Company identity */
|
||||
.header-company-logo{display:block;width:5.5rem;height:auto;max-height:2.4rem;flex-shrink:0;object-fit:contain}
|
||||
.staff-brand{display:flex;flex-direction:column;align-items:stretch;gap:.8rem;margin-bottom:1.75rem;padding:.5rem;text-align:center}
|
||||
.staff-logo-panel{display:flex;width:100%;min-height:4.5rem;align-items:center;justify-content:center;border:1px solid rgba(255,255,255,.42);border-radius:.9rem;background:#fff;padding:.65rem .9rem}
|
||||
.staff-company-logo{display:block;width:8.75rem;height:auto;max-height:3.35rem;object-fit:contain}
|
||||
.staff-brand-copy{display:block;min-width:0;padding-inline:.35rem}.staff-brand b{display:block;color:#fff;font-size:.92rem;font-weight:900;line-height:1.8}.staff-brand small{display:block;margin-top:.1rem;color:#c7d7e8;font-size:.72rem;font-weight:600;line-height:1.7}.staff-brand:hover .staff-logo-panel{border-color:rgba(6,147,227,.75)}.staff-brand:hover .staff-brand-copy b{color:#fff}.logo-copy{line-height:1.45}
|
||||
.auth-panel{width:100%;max-width:28rem;margin-inline:auto}.auth-brand{display:flex;align-items:center;flex-direction:column;gap:.55rem;margin-bottom:1.35rem;padding-bottom:1rem;border-bottom:1px solid rgba(8,55,107,.09);text-align:center}
|
||||
.auth-brand img{display:block;width:8.5rem;height:auto;max-height:3.7rem;object-fit:contain;flex-shrink:0}
|
||||
.auth-brand strong{display:block;color:var(--color-ink);font-size:.82rem;font-weight:900;line-height:1.6}
|
||||
.auth-brand small{display:block;margin-top:.1rem;color:#526b85;font-size:.67rem;font-weight:600}
|
||||
.auth-footer{margin:.65rem auto 0;padding:.2rem .75rem;color:#60758b;font-size:.65rem;font-weight:500;line-height:1.8;text-align:center}
|
||||
.ticket-company-logo{display:block;width:3.25rem;height:auto;max-height:1.45rem;flex-shrink:0;object-fit:contain}
|
||||
.site-footer{display:flex;min-height:2rem;align-items:center;justify-content:center;gap:.35rem;padding:.4rem 1rem;color:#60758b;font-size:.68rem;font-weight:500;text-align:center}
|
||||
.staff-main>.site-footer{border-top:1px solid rgba(8,55,107,.06)}
|
||||
body:has(.ticket-workspace) .ticket-workspace{height:calc(100dvh - 4.25rem - 2rem)}
|
||||
@media(max-width:639px){.logo-copy{font-size:.82rem}.header-company-logo{width:4.75rem;max-height:2.1rem}.auth-brand{gap:.5rem}.auth-brand img{width:7rem;max-height:3.1rem}.auth-brand>div{min-width:0}.auth-footer{font-size:.6rem}.ticket-company-logo{width:2.5rem;max-height:1.1rem}.site-footer{padding-inline:3.5rem;font-size:.62rem;line-height:1.6}body:has(.ticket-workspace) .ticket-workspace{height:calc(100dvh - 2rem)}}
|
||||
|
||||
/* Session actions, staff-created tickets and install prompt */
|
||||
.desktop-nav form,.staff-topbar-actions form{margin:0}.logout-button{min-height:auto;border:0;background:transparent;padding:.5rem .75rem;color:var(--color-coral);box-shadow:none}.logout-button:hover{transform:none;background:#fff;color:#b45309;box-shadow:none}
|
||||
.customer-mobile-dock{grid-template-columns:repeat(4,minmax(0,1fr))}.customer-mobile-dock form{margin:0}.customer-mobile-dock form button{display:flex;width:100%;min-height:3rem;flex-direction:column;align-items:center;justify-content:center;gap:.125rem;border-radius:1rem;background:transparent;padding:0;color:rgba(255,255,255,.6);font-size:.625rem;box-shadow:none}.customer-mobile-dock form button:hover{transform:none;background:rgba(255,255,255,.08);box-shadow:none}
|
||||
.staff-create-card{max-width:48rem;margin-inline:auto}.staff-create-card form{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.25rem 1rem}.staff-create-card form>p:has(textarea),.staff-create-card form>p:has(input[type=file]),.staff-create-card form>button,.staff-create-card .errorlist{grid-column:1/-1}.staff-create-card textarea{min-height:10rem}
|
||||
.pwa-install{position:fixed;right:1rem;bottom:1rem;z-index:80;display:flex;width:min(30rem,calc(100vw - 2rem));align-items:center;justify-content:space-between;gap:1rem;border:1px solid rgba(6,147,227,.25);border-radius:1rem;background:#fff;padding:1rem;box-shadow:0 20px 60px -30px rgba(8,55,107,.7)}.pwa-install[hidden]{display:none}.pwa-install b,.pwa-install small{display:block}.pwa-install small{margin-top:.2rem;color:#526b85;font-size:.72rem}.pwa-install>div:last-child{display:flex;gap:.4rem}.pwa-install button{min-height:2.4rem;padding:.45rem .75rem;background:#eaeaea;color:#526b85;box-shadow:none}.pwa-install button.primary{background:var(--color-sea);color:#fff}
|
||||
@media(max-width:639px){.staff-create-card form{grid-template-columns:1fr}.pwa-install{right:.65rem;bottom:5.5rem;width:calc(100vw - 1.3rem);align-items:stretch;flex-direction:column}.pwa-install>div:last-child button{flex:1}}
|
||||
|
||||
/* Media capture, image inspection and message read receipts */
|
||||
.customer-mobile-dock a.primary{background:transparent;color:rgba(255,255,255,.6)}.customer-mobile-dock a.active{background:linear-gradient(135deg,var(--color-sea),var(--color-sea-dark));color:#fff}@media(max-width:639px){body:has(.customer-mobile-dock)>.site-footer{margin-bottom:calc(5.5rem + env(safe-area-inset-bottom))}}
|
||||
.composer-context{gap:.75rem}.composer-context-actions{display:flex;flex:none;align-items:center;gap:.5rem}.composer-context-actions>[data-draft-status]{color:#60758b;font-size:.58rem}.composer-send-icon{display:grid;width:2.5rem;height:2.5rem;min-height:2.5rem;flex:none;place-items:center;border:1px solid rgba(6,147,227,.25);border-radius:999px;background:var(--color-sea);padding:0;color:#fff;box-shadow:none}.composer-send-icon:hover{transform:none;background:var(--color-sea-dark);box-shadow:none}.composer-send-icon svg{width:1.2rem;height:1.2rem;fill:currentColor}@keyframes submit-attention{0%,100%{outline:0 solid transparent;background-color:var(--color-sea)}45%{outline:4px solid rgba(250,159,0,.24);background-color:var(--color-coral)}}.send-button.submit-attention{animation:submit-attention .7s ease-out 1}@media(prefers-reduced-motion:reduce){.send-button.submit-attention{animation:none;outline:3px solid rgba(250,159,0,.28)}}
|
||||
.media-picker-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.65rem}.media-picker-button{display:flex;min-height:3rem;align-items:center;justify-content:center;border:1px solid #9ec8e5;border-radius:.85rem;background:#fff;padding:.7rem;color:#0b5f9b;font-size:.78rem;font-weight:900;cursor:pointer}.media-picker-button.gallery-button{border-color:#0693e3;background:#e9f7ff}.media-picker>[data-gallery-input],.media-picker>[data-document-input],.canonical-files,.canonical-file-input{position:absolute!important;width:1px!important;height:1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important}.compression-note{display:block;margin-top:.65rem;color:#526b85;font-size:.68rem}.recorder-error{display:block;margin-top:.6rem;color:#9b2c2c;font-size:.7rem}.attachment-image{display:grid!important;gap:.45rem}.attachment-image>button{display:block;min-height:0;background:transparent;padding:0;color:#08376b;box-shadow:none}.attachment-image>button:hover{transform:none;background:transparent;box-shadow:none}.attachment-image img{display:block;width:min(24rem,100%);max-height:18rem;border-radius:.65rem;object-fit:cover}.attachment-image span{display:block;padding:.45rem .25rem;text-align:right;font-size:.68rem}.attachment-download{padding:.35rem;color:#1977ce;font-size:.68rem}.image-viewer{width:min(70rem,calc(100vw - 2rem));max-width:none;border:0;border-radius:1rem;background:#fff;padding:0;color:#08376b;box-shadow:0 25px 80px #031b33aa}.image-viewer::backdrop{background:#031b33d9;backdrop-filter:blur(4px)}.image-viewer header,.image-viewer footer{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem}.image-viewer header{border-bottom:1px solid #dae6ef}.image-viewer header button{min-height:2.3rem;border-radius:.65rem;padding:.3rem .75rem}.image-viewer-stage{display:grid;min-height:14rem;max-height:75vh;place-items:center;overflow:auto;background:#0c2236}.image-viewer-stage img{display:block;max-width:100%;max-height:75vh;object-fit:contain}.image-viewer footer{justify-content:flex-end}.message-receipts{margin-top:.45rem!important;border-top:1px solid #d5e3ec;padding-top:.35rem}.message-receipts summary{color:#526b85;font-size:.62rem;font-weight:700}.message-receipts ul{display:grid;gap:.25rem;margin:.4rem 0 0;padding:0;list-style:none}.message-receipts li{display:flex;justify-content:space-between;gap:.7rem;color:#526b85;font-size:.6rem}.message-receipts time{color:#647b91}
|
||||
@media(max-width:639px){.media-picker-actions{grid-template-columns:1fr}.image-viewer{width:calc(100vw - .75rem)}.image-viewer-stage{max-height:78vh}}
|
||||
|
||||
/* Ticket media and staff sidebar refinements */
|
||||
.image-viewer{position:fixed;inset:0;margin:auto;max-height:min(90dvh,56rem)}.image-viewer[open]{display:flex;flex-direction:column}.image-viewer-stage{flex:1;min-height:0}.reply-media-picker{margin:.75rem 0;border:1px dashed #9fc3dc;border-radius:1rem;background:#f6fbff;padding:.75rem}.reply-media-picker>[data-gallery-input],.reply-media-picker>[data-document-input]{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap}.staff-developer-credit{margin:.65rem .4rem 0;border-top:1px solid rgba(255,255,255,.12);padding:.7rem .25rem 0;color:#c7d7e8;font-size:.62rem;line-height:1.8;text-align:center}
|
||||
|
||||
/* Staff customer directory and assisted ticket creation */
|
||||
.customer-page-head{align-items:flex-end}.customer-directory{padding:0;overflow:hidden}.customer-directory-search{display:grid;grid-template-columns:minmax(0,1fr) auto auto;align-items:end;gap:.75rem;padding:1.25rem;background:linear-gradient(135deg,#f5faff,#fff)}.customer-directory-search label{display:grid;gap:.4rem;color:var(--color-navy);font-size:.8rem;font-weight:800}.customer-directory-search input{width:100%;min-height:3rem}.customer-directory-search a{padding:.8rem;color:#526b85;font-weight:700}.customer-result-head{display:flex;justify-content:space-between;gap:1rem;padding:1rem 1.25rem;border-top:1px solid #dbe8f4;border-bottom:1px solid #dbe8f4;color:#526b85}.customer-result-head span{color:var(--color-navy);font-weight:900}.customer-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:1rem;padding:1.25rem;background:#f7fafc}.customer-card{display:grid;gap:1rem;border:1px solid #d7e5f2;border-radius:1rem;background:#fff;padding:1.15rem;box-shadow:0 10px 28px -24px #08376b}.customer-card header{display:flex;align-items:center;gap:.75rem}.customer-card header h2{margin:0;color:#173a5e;font-size:1rem}.customer-card header a{display:inline-block;margin-top:.2rem;color:#1977ce;font-size:.8rem}.customer-avatar{display:grid;width:2.75rem;height:2.75rem;place-items:center;border-radius:.8rem;background:#dff2ff;color:#08376b;font-weight:900}.customer-location{margin:0;color:#526b85;font-size:.78rem}.customer-ticket-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:.45rem}.customer-ticket-stats span{display:grid;gap:.15rem;border-radius:.65rem;background:#f1f5f9;padding:.55rem;text-align:center;color:#526b85;font-size:.65rem}.customer-ticket-stats b{color:#08376b;font-size:1rem}.customer-ticket-stats .needs-action{background:#fff4dd;color:#985f00}.customer-ticket-stats .needs-action b{color:#c67600}.customer-new-ticket{border-top:1px solid #e4edf5;padding-top:.8rem;color:#1977ce;font-size:.78rem;font-weight:900}.customer-ticket-create{display:block}.customer-picker-head{display:flex;align-items:start;justify-content:space-between;gap:1rem;margin-bottom:1rem;border-bottom:1px solid #dbe8f4;padding-bottom:1rem}.customer-picker-head h2{margin:.2rem 0;color:#173a5e;font-size:1.1rem}.customer-picker-head p{margin:0;color:#526b85;font-size:.78rem}.customer-picker-head a{white-space:nowrap;color:#1977ce;font-size:.75rem;font-weight:800}.customer-search-box{display:grid;gap:.4rem;margin-bottom:.75rem;color:#173a5e;font-size:.8rem;font-weight:900}.customer-search-box small{color:#647b91;font-size:.68rem;font-weight:500}.customer-search-results{position:relative;z-index:4;display:grid;gap:.35rem;max-height:18rem;margin-bottom:.8rem;overflow:auto;border:1px solid #cdddeb;border-radius:.75rem;background:#fff;padding:.4rem;box-shadow:0 18px 35px -28px #08376b}.customer-search-results[hidden]{display:none}.customer-search-results button{display:grid;grid-template-columns:1fr auto;gap:.15rem .75rem;width:100%;min-height:auto;border:0;border-radius:.55rem;background:#f7fafc;padding:.7rem;text-align:right;box-shadow:none;color:#173a5e}.customer-search-results button:hover{background:#e8f5ff}.customer-search-results button span{grid-row:1;grid-column:2}.customer-search-results button small{grid-column:1/-1;color:#647b91}.selected-customer{display:grid;grid-template-columns:1fr 1fr auto;align-items:center;gap:1rem;margin-bottom:.8rem;border:1px solid #93d4fa;border-radius:.8rem;background:#eef9ff;padding:.8rem}.selected-customer[hidden]{display:none}.selected-customer div{display:grid;gap:.2rem}.selected-customer b{color:#08376b}.selected-customer span,.selected-customer small{color:#526b85;font-size:.75rem}.selected-customer button{min-height:auto;background:transparent;color:#1977ce;box-shadow:none;padding:.5rem}.customer-lookup-status{margin-bottom:1rem;border-radius:.65rem;background:#f1f5f9;padding:.65rem .8rem;color:#526b85;font-size:.75rem}.customer-lookup-status.is-found{background:#eaf8f0;color:#17603a}.customer-lookup-status.is-new{background:#fff5df;color:#805300}.customer-lookup-status.is-error{background:#fff0f0;color:#a32929}
|
||||
@media(max-width:900px){.customer-grid{grid-template-columns:1fr}.customer-ticket-stats{grid-template-columns:repeat(2,1fr)}}
|
||||
@media(max-width:639px){.customer-page-head{align-items:stretch}.customer-directory-search{grid-template-columns:1fr}.customer-directory-search button{width:100%}.customer-result-head{align-items:start;flex-direction:column;gap:.2rem}.customer-grid{padding:.7rem}.customer-picker-head{flex-direction:column}.selected-customer{grid-template-columns:1fr}.customer-ticket-create{padding:1rem}}
|
||||
|
||||
/* Structured staff ticket creation */
|
||||
.staff-create-page{max-width:76rem;margin-inline:auto}.create-page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:2rem;margin-bottom:1.25rem}.create-page-head h1{margin:.2rem 0;color:#08376b;font-size:1.8rem;line-height:1.5}.create-page-head p:last-child{max-width:45rem;margin:0;color:#526b85;font-size:.85rem;line-height:1.9}.create-back{display:inline-flex;margin-bottom:.65rem;color:#1977ce;font-size:.75rem;font-weight:800}.customer-directory-link{display:flex;min-width:13rem;align-items:center;gap:.7rem;border:1px solid #cbddec;border-radius:1rem;background:#fff;padding:.8rem 1rem;color:#08376b;box-shadow:0 12px 28px -26px #08376b}.customer-directory-link>span{display:grid;width:2.4rem;height:2.4rem;place-items:center;border-radius:.7rem;background:#e7f5ff;color:#1977ce;font-size:1.2rem}.customer-directory-link b,.customer-directory-link small{display:block}.customer-directory-link b{font-size:.8rem}.customer-directory-link small{margin-top:.12rem;color:#60758b;font-size:.65rem}.create-progress{display:grid;grid-template-columns:repeat(3,1fr);margin:0 0 1.25rem;padding:0;overflow:hidden;border:1px solid #d8e5f0;border-radius:1rem;background:#fff;list-style:none}.create-progress li{position:relative;display:flex;align-items:center;gap:.65rem;padding:.75rem 1rem}.create-progress li+li{border-right:1px solid #e0e9f1}.create-progress li>span{display:grid;width:2rem;height:2rem;place-items:center;border-radius:.65rem;background:#eef3f7;color:#526b85;font-size:.75rem;font-weight:900}.create-progress li.active>span{background:#08376b;color:#fff}.create-progress b,.create-progress small{display:block}.create-progress b{color:#173a5e;font-size:.75rem}.create-progress small{margin-top:.1rem;color:#667d92;font-size:.62rem}.assisted-ticket-form{display:grid;grid-template-columns:minmax(0,1fr) 18.5rem;align-items:start;gap:1.25rem}.create-form-errors{grid-column:1/-1;border:1px solid #e9a6a6;border-radius:.8rem;background:#fff2f2;padding:.75rem;color:#8e2d2d}.create-form-main{display:grid;gap:1rem}.create-section{border:1px solid #d5e2ee;border-radius:1.1rem;background:#fff;padding:1.25rem;box-shadow:0 18px 40px -36px rgba(8,55,107,.7)}.create-section-head{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:1.15rem;border-bottom:1px solid #e4edf4;padding-bottom:1rem}.section-number{display:grid;width:2.25rem;height:2.25rem;flex:0 0 auto;place-items:center;border-radius:.7rem;background:linear-gradient(135deg,#08376b,#1977ce);color:#fff;font-size:.8rem;font-weight:900}.create-section-head h2{margin:0;color:#123a63;font-size:1rem}.create-section-head p{margin:.25rem 0 0;color:#60758b;font-size:.72rem;line-height:1.75}.field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.9rem}.field-control{display:grid;align-content:start;gap:.4rem;color:#244b72;font-size:.78rem;font-weight:800}.field-control>span{display:flex;align-items:center;gap:.35rem}.field-control em{color:#d36a00;font-style:normal}.field-control i{border-radius:999px;background:#eef3f7;padding:.12rem .4rem;color:#60758b;font-size:.58rem;font-style:normal;font-weight:600}.field-control input,.field-control select,.field-control textarea,.search-input-shell{width:100%;border:1px solid #b9cada;border-radius:.75rem;background:#fbfdff;color:#123a63}.field-control input,.field-control select{min-height:2.85rem}.field-control textarea{min-height:12rem;resize:vertical;line-height:1.9}.field-control input:focus,.field-control select:focus,.field-control textarea:focus,.search-input-shell:focus-within{border-color:#0693e3;outline:3px solid rgba(6,147,227,.12);background:#fff}.field-control small{color:#6a8094;font-size:.62rem;font-weight:500}.field-control .errorlist,.attachment-field .errorlist{margin:0;padding:0;color:#a32929;font-size:.68rem;list-style:none}.search-input-shell{display:flex;align-items:center;padding-inline:.75rem}.search-input-shell>span{color:#1977ce;font-size:1.2rem}.search-input-shell input{min-height:2.9rem;border:0!important;background:transparent!important;outline:0!important;box-shadow:none!important}.customer-search-box{margin-bottom:.65rem}.selected-customer{grid-template-columns:auto 1fr 1fr auto}.selected-customer-icon{display:grid;width:2rem;height:2rem;place-items:center;border-radius:999px;background:#1f8b58;color:#fff;font-weight:900}.customer-lookup-status{border-right:3px solid #8ba4ba}.customer-lookup-status.is-found{border-right-color:#25875a}.customer-lookup-status.is-new{border-right-color:#e38a00}.location-hint{margin:.65rem 0 0;color:#647b91;font-size:.65rem}.message-field{margin-bottom:1rem}.attachment-field{position:relative;display:flex;align-items:center;gap:.75rem;border:1px dashed #91b4d0;border-radius:.85rem;background:#f6fbff;padding:.9rem;color:#173a5e;cursor:pointer}.attachment-field:hover{border-color:#0693e3;background:#edf8ff}.attachment-field .attachment-icon{display:grid;width:2.35rem;height:2.35rem;flex:0 0 auto;place-items:center;border-radius:.7rem;backgrLine truncated
|
||||
@media(max-width:1000px){.assisted-ticket-form{grid-template-columns:1fr}.create-summary{order:-1}.summary-sticky{position:static}.summary-sticky dl{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem}.summary-sticky dl div{border-bottom:0}.secure-delivery{display:none}.create-submit{width:auto}.create-cancel{padding-bottom:.9rem}}
|
||||
@media(max-width:639px){.create-page-head{align-items:stretch;flex-direction:column;gap:1rem}.create-page-head h1{font-size:1.4rem}.customer-directory-link{min-width:0}.create-progress{grid-template-columns:1fr}.create-progress li{padding:.65rem .8rem}.create-progress li+li{border-top:1px solid #e0e9f1;border-right:0}.create-progress small{display:none}.create-section{padding:1rem}.field-grid{grid-template-columns:1fr}.field-spacer{display:none}.selected-customer{grid-template-columns:auto 1fr}.selected-customer>div:nth-of-type(2){grid-column:2}.selected-customer button{grid-column:1/-1;border-top:1px solid #bee0f3}.summary-sticky dl{grid-template-columns:1fr}.summary-sticky dl div{padding:.45rem 0}.attachment-field{align-items:flex-start;flex-wrap:wrap}.attachment-field input[type=file]{width:100%;max-width:none;margin:0}.create-summary{order:initial}.summary-sticky>header,.summary-sticky dl,.secure-delivery{display:none}.summary-sticky{position:sticky;bottom:4.7rem;z-index:20;border-color:#acd2eb;box-shadow:0 -12px 35px -25px #08376b}.create-submit{margin:.45rem}.create-cancel{display:none}}
|
||||
|
||||
/* Profile completion guidance and truthful PWA installation states */
|
||||
.profile-completion-notice{display:grid;grid-template-columns:auto minmax(0,1fr);gap:1rem;margin:-.5rem 0 1.5rem;border:1px solid #a9d5ef;border-right:4px solid var(--color-sea);border-radius:1.15rem;background:linear-gradient(135deg,#fff,#edf8ff);padding:1.15rem;box-shadow:0 16px 38px -34px #08376b}.profile-completion-icon{display:grid;width:2.75rem;height:2.75rem;place-items:center;border-radius:.8rem;background:#dff2ff;color:#1977ce;font-size:1.25rem;font-weight:900}.profile-completion-notice h2{margin:0;color:#08376b;font-size:1rem}.profile-completion-notice p{margin:.35rem 0 0;color:#405d78;font-size:.78rem;line-height:1.9}.profile-completion-actions{display:flex;align-items:center;gap:1rem;margin-top:.85rem}.profile-completion-actions .button{min-height:2.55rem;padding:.5rem 1rem}.profile-completion-actions>a:last-child{color:#526b85;font-size:.7rem;font-weight:700}.pwa-install-icon{width:3.5rem;height:3.5rem;flex:none;border-radius:.85rem;object-fit:cover}.pwa-install-copy{min-width:0;flex:1}.pwa-install-actions{display:flex;gap:.4rem}.pwa-install-guidance{border-color:#fac66c}.pwa-install-guidance .pwa-install-copy small{color:#805300}
|
||||
@media(max-width:639px){.profile-completion-notice{grid-template-columns:1fr;margin-top:0}.profile-completion-icon{width:2.4rem;height:2.4rem}.profile-completion-actions{align-items:stretch;flex-direction:column;gap:.65rem}.profile-completion-actions>a{text-align:center}.pwa-install{display:grid;grid-template-columns:auto 1fr;align-items:center}.pwa-install-actions{grid-column:1/-1}.pwa-install-actions button{flex:1}}
|
||||
.composer-send-icon{cursor:pointer;user-select:none}.composer-send-icon:focus-visible{outline:3px solid rgba(6,147,227,.25);outline-offset:2px}
|
||||
|
||||
/* Non-blocking guidance when current-page timing/length signals resemble rapid chat. */
|
||||
.chat-coach{@apply mt-2 grid grid-cols-[auto_1fr_auto] items-start gap-2.5 rounded-xl border border-amber-400/45 bg-amber-50 px-3 py-2.5 text-right;animation:chat-coach-in .2s ease-out}.chat-coach[hidden]{display:none}.chat-coach-icon{@apply grid size-7 place-items-center rounded-lg bg-amber-400/20 text-sm text-amber-800}.chat-coach b{@apply block text-[11px] text-amber-800}.chat-coach p{@apply mt-0.5 text-[10px] leading-5 text-amber-800/80}.chat-coach button{@apply grid size-7 min-h-0 place-items-center rounded-full bg-transparent p-0 text-base font-normal text-amber-800/60 shadow-none hover:bg-amber-400/15 hover:text-amber-800}@keyframes chat-coach-in{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}
|
||||
.chat-coach-floating{position:fixed;z-index:90;left:1rem;bottom:1rem;width:min(28rem,calc(100vw - 2rem));margin:0;box-shadow:0 18px 50px -24px rgba(8,55,107,.7)}
|
||||
@media(max-width:639px){.chat-coach-floating{right:.65rem;bottom:5.65rem;left:.65rem;width:auto;padding:.65rem .75rem}}
|
||||
|
||||
/* Comfortable close target for the short-lived chat guidance toast. */
|
||||
.chat-coach [data-chat-coach-dismiss]{width:2.5rem;height:2.5rem;min-height:2.5rem;border:1px solid rgba(217,119,6,.2);background:rgba(255,255,255,.65);font-size:1.5rem;line-height:1;color:rgba(120,53,15,.78);touch-action:manipulation;transition:background-color .15s ease,border-color .15s ease,color .15s ease}
|
||||
.chat-coach [data-chat-coach-dismiss]:hover{border-color:rgba(217,119,6,.4);background:rgba(251,191,36,.22);color:#78350f}
|
||||
.chat-coach [data-chat-coach-dismiss]:focus-visible{outline:2px solid #d97706;outline-offset:2px}
|
||||
|
||||
/* Compact message actions: lower-left trigger, two choices, focused editor. */
|
||||
.message-menu{top:auto!important;right:auto!important;bottom:.35rem!important;left:.35rem!important}.message-menu-panel{top:auto;right:auto!important;bottom:calc(100% + .35rem);left:0!important;margin:0;width:15rem}.message-menu-choices{@apply grid gap-1 p-1.5}.message-menu-choices form{@apply m-0}.message-choice{@apply m-0 flex min-h-12 w-full items-center justify-start gap-2.5 rounded-xl bg-transparent px-3 py-2 text-right text-ink shadow-none hover:bg-mint hover:text-sea}.message-choice>span:nth-child(2){@apply min-w-0 flex-1}.message-choice b,.message-choice small{@apply block}.message-choice b{@apply text-xs}.message-choice small{@apply mt-0.5 text-[9px] font-medium text-ink/45}.message-choice-icon{@apply grid size-8 shrink-0 place-items-center rounded-lg bg-mint text-base text-sea}.message-choice-arrow{@apply text-lg text-ink/25}.message-choice-delete{@apply text-red-700 hover:bg-red-50 hover:text-red-700}.message-choice-delete .message-choice-icon{@apply bg-red-50 text-red-700}.message-editor-back{@apply grid size-8 min-h-0 place-items-center rounded-full bg-transparent p-0 text-base text-ink/50 shadow-none hover:bg-ink/5 hover:text-ink}.message-edit-meta{@apply mt-1.5 flex justify-between gap-2 text-[8px] text-ink/40}@media(max-width:639px){.message-menu-panel{top:auto!important;right:.75rem!important;bottom:5rem!important;left:.75rem!important;width:auto}.message-menu-choices{@apply p-2}.message-choice{@apply min-h-14}}
|
||||
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
(()=>{var nt=!1,it=!1,W=[],ot=-1;function Ut(e){Rn(e)}function Rn(e){W.includes(e)||W.push(e),Mn()}function Wt(e){let t=W.indexOf(e);t!==-1&&t>ot&&W.splice(t,1)}function Mn(){!it&&!nt&&(nt=!0,queueMicrotask(Nn))}function Nn(){nt=!1,it=!0;for(let e=0;e<W.length;e++)W[e](),ot=e;W.length=0,ot=-1,it=!1}var T,N,$,at,st=!0;function Gt(e){st=!1,e(),st=!0}function Jt(e){T=e.reactive,$=e.release,N=t=>e.effect(t,{scheduler:r=>{st?Ut(r):r()}}),at=e.raw}function ct(e){N=e}function Yt(e){let t=()=>{};return[n=>{let i=N(n);return e._x_effects||(e._x_effects=new Set,e._x_runEffects=()=>{e._x_effects.forEach(o=>o())}),e._x_effects.add(i),t=()=>{i!==void 0&&(e._x_effects.delete(i),$(i))},i},()=>{t()}]}function ve(e,t){let r=!0,n,i=N(()=>{let o=e();JSON.stringify(o),r?n=o:queueMicrotask(()=>{t(o,n),n=o}),r=!1});return()=>$(i)}var Xt=[],Zt=[],Qt=[];function er(e){Qt.push(e)}function te(e,t){typeof t=="function"?(e._x_cleanups||(e._x_cleanups=[]),e._x_cleanups.push(t)):(t=e,Zt.push(t))}function Ae(e){Xt.push(e)}function Oe(e,t,r){e._x_attributeCleanups||(e._x_attributeCleanups={}),e._x_attributeCleanups[t]||(e._x_attributeCleanups[t]=[]),e._x_attributeCleanups[t].push(r)}function lt(e,t){e._x_attributeCleanups&&Object.entries(e._x_attributeCleanups).forEach(([r,n])=>{(t===void 0||t.includes(r))&&(n.forEach(i=>i()),delete e._x_attributeCleanups[r])})}function tr(e){for(e._x_effects?.forEach(Wt);e._x_cleanups?.length;)e._x_cleanups.pop()()}var ut=new MutationObserver(mt),ft=!1;function ue(){ut.observe(document,{subtree:!0,childList:!0,attributes:!0,attributeOldValue:!0}),ft=!0}function dt(){kn(),ut.disconnect(),ft=!1}var le=[];function kn(){let e=ut.takeRecords();le.push(()=>e.length>0&&mt(e));let t=le.length;queueMicrotask(()=>{if(le.length===t)for(;le.length>0;)le.shift()()})}function m(e){if(!ft)return e();dt();let t=e();return ue(),t}var pt=!1,Se=[];function rr(){pt=!0}function nr(){pt=!1,mt(Se),Se=[]}function mt(e){if(pt){Se=Se.concat(e);return}let t=[],r=new Set,n=new Map,i=new Map;for(let o=0;o<e.length;o++)if(!e[o].target._x_ignoreMutationObserver&&(e[o].type==="childList"&&(e[o].removedNodes.forEach(s=>{s.nodeType===1&&s._x_marker&&r.add(s)}),e[o].addedNodes.forEach(s=>{if(s.nodeType===1){if(r.has(s)){r.delete(s);return}s._x_marker||t.push(s)}})),e[o].type==="attributes")){let s=e[o].target,a=e[o].attributeName,c=e[o].oldValue,l=()=>{n.has(s)||n.set(s,[]),n.get(s).push({name:a,value:s.getAttribute(a)})},u=()=>{i.has(s)||i.set(s,[]),i.get(s).push(a)};s.hasAttribute(a)&&c===null?l():s.hasAttribute(a)?(u(),l()):u()}i.forEach((o,s)=>{lt(s,o)}),n.forEach((o,s)=>{Xt.forEach(a=>a(s,o))});for(let o of r)t.some(s=>s.contains(o))||Zt.forEach(s=>s(o));for(let o of t)o.isConnected&&Qt.forEach(s=>s(o));t=null,r=null,n=null,i=null}function Ce(e){return z(B(e))}function k(e,t,r){return e._x_dataStack=[t,...B(r||e)],()=>{e._x_dataStack=e._x_dataStack.filter(n=>n!==t)}}function B(e){return e._x_dataStack?e._x_dataStack:typeof ShadowRoot=="function"&&e instanceof ShadowRoot?B(e.host):e.parentNode?B(e.parentNode):[]}function z(e){return new Proxy({objects:e},Dn)}var Dn={ownKeys({objects:e}){return Array.from(new Set(e.flatMap(t=>Object.keys(t))))},has({objects:e},t){return t==Symbol.unscopables?!1:e.some(r=>Object.prototype.hasOwnProperty.call(r,t)||Reflect.has(r,t))},get({objects:e},t,r){return t=="toJSON"?Pn:Reflect.get(e.find(n=>Reflect.has(n,t))||{},t,r)},set({objects:e},t,r,n){let i=e.find(s=>Object.prototype.hasOwnProperty.call(s,t))||e[e.length-1],o=Object.getOwnPropertyDescriptor(i,t);return o?.set&&o?.get?o.set.call(n,r)||!0:Reflect.set(i,t,r)}};function Pn(){return Reflect.ownKeys(this).reduce((t,r)=>(t[r]=Reflect.get(this,r),t),{})}function Te(e){let t=n=>typeof n=="object"&&!Array.isArray(n)&&n!==null,r=(n,i="")=>{Object.entries(Object.getOwnPropertyDescriptors(n)).forEach(([o,{value:s,enumerable:a}])=>{if(a===!1||s===void 0||typeof s=="object"&&s!==null&&s.__v_skip)return;let c=i===""?o:`${i}.${o}`;typeof s=="object"&&s!==null&&s._x_interceptor?n[o]=s.initialize(e,c,o):t(s)&&s!==n&&!(s instanceof Element)&&r(s,c)})};return r(e)}function Re(e,t=()=>{}){let r={initialValue:void 0,_x_interceptor:!0,initialize(n,i,o){return e(this.initialValue,()=>In(n,i),s=>ht(n,i,s),i,o)}};return t(r),n=>{if(typeof n=="object"&&n!==null&&n._x_interceptor){let i=r.initialize.bind(r);r.initialize=(o,s,a)=>{let c=n.initialize(o,s,a);return r.initialValue=c,i(o,s,a)}}else r.initialValue=n;return r}}function In(e,t){return t.split(".").reduce((r,n)=>r[n],e)}function ht(e,t,r){if(typeof t=="string"&&(t=t.split(".")),t.length===1)e[t[0]]=r;else{if(t.length===0)throw error;return e[t[0]]||(e[t[0]]={}),ht(e[t[0]],t.slice(1),r)}}var ir={};function y(e,t){ir[e]=t}function fe(e,t){let r=Ln(t);return Object.entries(ir).forEach(([n,i])=>{Object.defineProperty(e,`$${n}`,{get(){return i(t,r)},enumerable:!1})}),e}function Ln(e){let[t,r]=_t(e),n={interceptor:Re,...t};return te(e,r),n}function or(e,t,r,...n){try{return r(...n)}catch(i){re(i,e,t)}}function re(e,tLine truncated
|
||||
|
||||
${r?'Expression: "'+r+`"
|
||||
|
||||
`:""}`,t),setTimeout(()=>{throw e},0)}var Me=!0;function ke(e){let t=Me;Me=!1;let r=e();return Me=t,r}function R(e,t,r={}){let n;return x(e,t)(i=>n=i,r),n}function x(...e){return sr(...e)}var sr=xt;function ar(e){sr=e}function xt(e,t){let r={};fe(r,e);let n=[r,...B(e)],i=typeof t=="function"?$n(n,t):Fn(n,t,e);return or.bind(null,e,t,i)}function $n(e,t){return(r=()=>{},{scope:n={},params:i=[]}={})=>{let o=t.apply(z([n,...e]),i);Ne(r,o)}}var gt={};function jn(e,t){if(gt[e])return gt[e];let r=Object.getPrototypeOf(async function(){}).constructor,n=/^[\n\s]*if.*\(.*\)/.test(e.trim())||/^(let|const)\s/.test(e.trim())?`(async()=>{ ${e} })()`:e,o=(()=>{try{let s=new r(["__self","scope"],`with (scope) { __self.result = ${n} }; __self.finished = true; return __self.result;`);return Object.defineProperty(s,"name",{value:`[Alpine] ${e}`}),s}catch(s){return re(s,t,e),Promise.resolve()}})();return gt[e]=o,o}function Fn(e,t,r){let n=jn(t,r);return(i=()=>{},{scope:o={},params:s=[]}={})=>{n.result=void 0,n.finished=!1;let a=z([o,...e]);if(typeof n=="function"){let c=n(n,a).catch(l=>re(l,r,t));n.finished?(Ne(i,n.result,a,s,r),n.result=void 0):c.then(l=>{Ne(i,l,a,s,r)}).catch(l=>re(l,r,t)).finally(()=>n.result=void 0)}}}function Ne(e,t,r,n,i){if(Me&&typeof t=="function"){let o=t.apply(r,n);o instanceof Promise?o.then(s=>Ne(e,s,r,n)).catch(s=>re(s,i,t)):e(o)}else typeof t=="object"&&t instanceof Promise?t.then(o=>e(o)):e(t)}var wt="x-";function C(e=""){return wt+e}function cr(e){wt=e}var De={};function d(e,t){return De[e]=t,{before(r){if(!De[r]){console.warn(String.raw`Cannot find directive \`${r}\`. \`${e}\` will use the default order of execution`);return}let n=G.indexOf(r);G.splice(n>=0?n:G.indexOf("DEFAULT"),0,e)}}}function lr(e){return Object.keys(De).includes(e)}function pe(e,t,r){if(t=Array.from(t),e._x_virtualDirectives){let o=Object.entries(e._x_virtualDirectives).map(([a,c])=>({name:a,value:c})),s=Et(o);o=o.map(a=>s.find(c=>c.name===a.name)?{name:`x-bind:${a.name}`,value:`"${a.value}"`}:a),t=t.concat(o)}let n={};return t.map(dr((o,s)=>n[o]=s)).filter(mr).map(zn(n,r)).sort(Kn).map(o=>Bn(e,o))}function Et(e){return Array.from(e).map(dr()).filter(t=>!mr(t))}var yt=!1,de=new Map,ur=Symbol();function fr(e){yt=!0;let t=Symbol();ur=t,de.set(t,[]);let r=()=>{for(;de.get(t).length;)de.get(t).shift()();de.delete(t)},n=()=>{yt=!1,r()};e(r),n()}function _t(e){let t=[],r=a=>t.push(a),[n,i]=Yt(e);return t.push(i),[{Alpine:K,effect:n,cleanup:r,evaluateLater:x.bind(x,e),evaluate:R.bind(R,e)},()=>t.forEach(a=>a())]}function Bn(e,t){let r=()=>{},n=De[t.type]||r,[i,o]=_t(e);Oe(e,t.original,o);let s=()=>{e._x_ignore||e._x_ignoreSelf||(n.inline&&n.inline(e,t,i),n=n.bind(n,e,t,i),yt?de.get(ur).push(n):n())};return s.runCleanups=o,s}var Pe=(e,t)=>({name:r,value:n})=>(r.startsWith(e)&&(r=r.replace(e,t)),{name:r,value:n}),Ie=e=>e;function dr(e=()=>{}){return({name:t,value:r})=>{let{name:n,value:i}=pr.reduce((o,s)=>s(o),{name:t,value:r});return n!==t&&e(n,t),{name:n,value:i}}}var pr=[];function ne(e){pr.push(e)}function mr({name:e}){return hr().test(e)}var hr=()=>new RegExp(`^${wt}([^:^.]+)\\b`);function zn(e,t){return({name:r,value:n})=>{let i=r.match(hr()),o=r.match(/:([a-zA-Z0-9\-_:]+)/),s=r.match(/\.[^.\]]+(?=[^\]]*$)/g)||[],a=t||e[r]||r;return{type:i?i[1]:null,value:o?o[1]:null,modifiers:s.map(c=>c.replace(".","")),expression:n,original:a}}}var bt="DEFAULT",G=["ignore","ref","data","id","anchor","bind","init","for","model","modelable","transition","show","if",bt,"teleport"];function Kn(e,t){let r=G.indexOf(e.type)===-1?bt:e.type,n=G.indexOf(t.type)===-1?bt:t.type;return G.indexOf(r)-G.indexOf(n)}function J(e,t,r={}){e.dispatchEvent(new CustomEvent(t,{detail:r,bubbles:!0,composed:!0,cancelable:!0}))}function D(e,t){if(typeof ShadowRoot=="function"&&e instanceof ShadowRoot){Array.from(e.children).forEach(i=>D(i,t));return}let r=!1;if(t(e,()=>r=!0),r)return;let n=e.firstElementChild;for(;n;)D(n,t,!1),n=n.nextElementSibling}function E(e,...t){console.warn(`Alpine Warning: ${e}`,...t)}var _r=!1;function gr(){_r&&E("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."),_r=!0,document.body||E("Unable to initialize. Trying to load Alpine before `<body>` is available. Did you forget to add `defer` in Alpine's `<script>` tag?"),J(document,"alpine:init"),J(document,"alpine:initializing"),ue(),er(t=>S(t,D)),te(t=>P(t)),Ae((t,r)=>{pe(t,r).forEach(n=>n())});let e=t=>!Y(t.parentElement,!0);Array.from(document.querySelectorAll(br().join(","))).filter(e).forEach(t=>{S(t)}),J(document,"alpine:initialized"),setTimeout(()=>{Vn()})}var vt=[],xr=[];function yr(){return vt.map(e=>e())}function br(){return vt.concat(xr).map(e=>e())}function Le(e){vt.push(e)}function $e(e){xr.push(e)}function Y(e,t=!1){return j(e,r=>{if((t?br():yr()).some(i=>r.matches(i)))return!0})}function j(e,t){if(e){if(t(e))return e;if(e._x_teleportBack&&(e=e._x_teleportBack),!!e.parentElement)return j(e.parentElement,t)}}function wrLine truncated
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
/*!
|
||||
* Compressor.js v1.3.0
|
||||
* https://fengyuanchen.github.io/compressorjs
|
||||
*
|
||||
* Copyright 2018-present Chen Fengyuan
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Date: 2026-04-06T07:12:45.816Z
|
||||
*/
|
||||
((e,t)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Compressor=t()})(this,function(){function a(e,t){for(var r=0;r<t.length;r++){var i=t[r];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,o(i.key),i)}}function s(){return(s=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r,i=arguments[t];for(r in i)!{}.hasOwnProperty.call(i,r)||(e[r]=i[r])}return e}).apply(null,arguments)}function t(t,e){var r,i=Object.keys(t);return Object.getOwnPropertySymbols&&(r=Object.getOwnPropertySymbols(t),e&&(r=r.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),i.push.apply(i,r)),i}function n(i){for(var e=1;e<arguments.length;e++){var a=null!=arguments[e]?arguments[e]:{};e%2?t(Object(a),!0).forEach(function(e){var t,r;t=i,r=a[e=e],(e=o(e))in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r}):Object.getOwnPropertyDescriptors?Object.defineProperties(i,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach(function(e){Object.defineProperty(i,e,Object.getOwnPropertyDescriptor(a,e))})}return i}function o(e){e=((e,t)=>{if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0===r)return("string"===t?String:Number)(e);if("object"!=typeof(r=r.call(e,t||"default")))return r;throw new TypeError("@@toPrimitive must return a primitive value.")})(e,"string");return"symbol"==typeof e?e:e+""}function x(e){return 0<e&&e<1/0}var e,r,l,c,h,u,f,d,i={exports:{}},O=(e=i,"undefined"!=typeof window&&(l=(r=window).HTMLCanvasElement&&r.HTMLCanvasElement.prototype,c=r.Blob&&(()=>{try{return Boolean(new Blob)}catch(e){return!1}})(),h=c&&r.Uint8Array&&(()=>{try{return 100===new Blob([new Uint8Array(100)]).size}catch(e){return!1}})(),u=r.BlobBuilder||r.WebKitBlobBuilder||r.MozBlobBuilder||r.MSBlobBuilder,f=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,d=(c||u)&&r.atob&&r.ArrayBuffer&&r.Uint8Array&&function(e){var t,r,i,a,n,o=e.match(f);if(!o)throw new Error("invalid data URI");for(t=o[2]?o[1]:"text/plain"+(o[3]||";charset=US-ASCII"),n=!!o[4],e=e.slice(o[0].length),r=(n?atob:decodeURIComponent)(e),o=new ArrayBuffer(r.length),i=new Uint8Array(o),a=0;a<r.length;a+=1)i[a]=r.charCodeAt(a);return c?new Blob([h?i:o],{type:t}):((n=new u).append(o),n.getBlob(t))},r.HTMLCanvasElement&&!l.toBlob&&(l.mozGetAsFile?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){r&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.mozGetAsFile("blob",t))})}:l.toDataURL&&d&&(l.msToBlob?l.toBlob=function(e,t,r){var i=this;setTimeout(function(){(t&&"image/png"!==t||r)&&l.toDataURL&&d?e(d(i.toDataURL(t,r))):e(i.msToBlob(t))})}:l.toBlob=function(e,t,r){var i=this;setTimeout(function(){e(d(i.toDataURL(t,r)))})})),e.exports?e.exports=d:r.dataURLtoBlob=d),i.exports),m={strict:!0,checkOrientation:!0,retainExif:!1,maxWidth:1/0,maxHeight:1/0,minWidth:0,minHeight:0,width:void 0,height:void 0,resize:"none",quality:.8,mimeType:"auto",convertTypes:["image/png"],convertSize:5e6,beforeDraw:null,drew:null,success:null,error:null},g="undefined"!=typeof window&&void 0!==window.document?window:{},p=Array.prototype.slice;function j(e){return Array.from?Array.from(e):p.call(e)}var b=/^image\/.+$/;function T(e){return b.test(e)}var y=String.fromCharCode;var w=g.btoa;function A(e,t){for(var r=[],i=new Uint8Array(e);0<i.length;)r.push(y.apply(null,j(i.subarray(0,8192)))),i=i.subarray(8192);return"data:".concat(t,";base64,").concat(w(r.join("")))}function v(e){var t,r,i,a,n,o,l,s=new DataView(e);try{if(255===s.getUint8(0)&&216===s.getUint8(1))for(var c=s.byteLength,h=2;h+1<c;){if(255===s.getUint8(h)&&225===s.getUint8(h+1)){r=h;break}h+=1}if(i=r&&(a=r+10,"Exif"===((e,t,r)=>{var i,a="";for(r+=t,i=t;i<r;i+=1)a+=y(e.getUint8(i));return a})(s,r+4,4))&&((l=18761===(n=s.getUint16(a)))||19789===n)&&42===s.getUint16(a+2,l)&&8<=(o=s.getUint32(a+4,l))?a+o:i)for(var u,f=s.getUint16(i,l),d=0;d<f;d+=1)if(u=i+12*d+2,274===s.getUint16(u,l)){u+=8,t=s.getUint16(u,l),s.setUint16(u,1,l);break}}catch(e){t=1}return t}var B=/\.\d*(?:0|9){12}\d*$/;function R(e,t){t=1<arguments.length&&void 0!==t?t:1e11;return B.test(e)?Math.round(e*t)/t:e}function E(e,t){var r,i=e.aspectRatio,a=e.height,e=e.width,t=1<arguments.length&&void 0!==t?t:"none",n=x(e),o=x(a);return n&&o?(r=a*i,("contain"===t||"none"===t)&&e<r||"cover"===t&&r<e?a=e/i:e=a*i):n?a=e/i:o&&(e=a*i),{width:e,height:a}}var U=g.ArrayBuffer,k=g.FileReader,D=g.URL||g.webkitURL,M=/\.\w+$/,L=g.Compressor;return(()=>{function r(e,t){if(!(this instanceof r))throw new TypeError("Cannot call a class as a function");this.file=e,this.exif=[],this.image=new Image,this.options=n(n({},m),t),this.aborted=!1,this.result=null,this.init()}return e=r,i=[{key:"noConflict",value:function(){return window.Compressor=L,r}},{key:"setDefaults",value:function(e){s(m,e)}}],(t=[{key:"init",value:function(){var i,a,n,eLine truncated
|
||||
Vendored
+1
@@ -0,0 +1 @@
|
||||
var htmx=function(){"use strict";const Q={onLoad:null,process:null,on:null,off:null,trigger:null,ajax:null,find:null,findAll:null,closest:null,values:function(e,t){const n=cn(e,t||"post");return n.values},remove:null,addClass:null,removeClass:null,toggleClass:null,takeClass:null,swap:null,defineExtension:null,removeExtension:null,logAll:null,logNone:null,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",inlineStyleNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",scrollBehavior:"instant",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get","delete"],selfRequestsOnly:true,ignoreTitle:false,scrollIntoViewOnBoost:true,triggerSpecsCache:null,disableInheritance:false,responseHandling:[{code:"204",swap:false},{code:"[23]..",swap:true},{code:"[45]..",swap:false,error:true}],allowNestedOobSwaps:true},parseInterval:null,_:null,version:"2.0.3"};Q.onLoad=j;Q.process=kt;Q.on=ye;Q.off=be;Q.trigger=de;Q.ajax=Rn;Q.find=r;Q.findAll=x;Q.closest=g;Q.remove=z;Q.addClass=K;Q.removeClass=G;Q.toggleClass=W;Q.takeClass=Z;Q.swap=$e;Q.defineExtension=Fn;Q.removeExtension=Bn;Q.logAll=V;Q.logNone=_;Q.parseInterval=h;Q._=e;const n={addTriggerHandler:St,bodyContains:le,canAccessLocalStorage:B,findThisElement:Se,filterValues:dn,swap:$e,hasAttribute:s,getAttributeValue:te,getClosestAttributeValue:re,getClosestMatch:i,getExpressionVars:En,getHeaders:fn,getInputValues:cn,getInternalData:ie,getSwapSpecification:gn,getTriggerSpecs:st,getTarget:Ee,makeFragment:P,mergeObjects:ce,makeSettleInfo:xn,oobSwap:He,querySelectorExt:ae,settleImmediately:Kt,shouldCancel:dt,triggerEvent:de,triggerErrorEvent:fe,withExtensions:Ft};const o=["get","post","put","delete","patch"];const R=o.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function h(e){if(e==undefined){return undefined}let t=NaN;if(e.slice(-2)=="ms"){t=parseFloat(e.slice(0,-2))}else if(e.slice(-1)=="s"){t=parseFloat(e.slice(0,-1))*1e3}else if(e.slice(-1)=="m"){t=parseFloat(e.slice(0,-1))*1e3*60}else{t=parseFloat(e)}return isNaN(t)?undefined:t}function ee(e,t){return e instanceof Element&&e.getAttribute(t)}function s(e,t){return!!e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function te(e,t){return ee(e,t)||ee(e,"data-"+t)}function c(e){const t=e.parentElement;if(!t&&e.parentNode instanceof ShadowRoot)return e.parentNode;return t}function ne(){return document}function m(e,t){return e.getRootNode?e.getRootNode({composed:t}):ne()}function i(e,t){while(e&&!t(e)){e=c(e)}return e||null}function H(e,t,n){const r=te(t,n);const o=te(t,"hx-disinherit");var i=te(t,"hx-inherit");if(e!==t){if(Q.config.disableInheritance){if(i&&(i==="*"||i.split(" ").indexOf(n)>=0)){return r}else{return null}}if(o&&(o==="*"||o.split(" ").indexOf(n)>=0)){return"unset"}}return r}function re(t,n){let r=null;i(t,function(e){return!!(r=H(t,ue(e),n))});if(r!=="unset"){return r}}function d(e,t){const n=e instanceof Element&&(e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector);return!!n&&n.call(e,t)}function T(e){const t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;const n=t.exec(e);if(n){return n[1].toLowerCase()}else{return""}}function q(e){const t=new DOMParser;return t.parseFromString(e,"text/html")}function L(e,t){while(t.childNodes.length>0){e.append(t.childNodes[0])}}function N(e){const t=ne().createElement("script");se(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(Q.config.inlineScriptNonce){t.nonce=Q.config.inlineScriptNonce}return t}function A(e){return e.matches("script")&&(e.type==="text/javascript"||e.type==="module"||e.type==="")}function I(e){Array.from(e.querySelectorAll("script")).forEach(e=>{if(A(e)){const t=N(e);const n=e.parentNode;try{n.insertBefore(t,e)}catch(e){C(e)}finally{e.remove()}}})}function P(e){const t=e.replace(/<head(\s[^>]*)?>[\s\S]*?<\/head>/i,"");const n=T(t);let r;if(n==="html"){r=new DocumentFragment;const i=q(e);L(r,i.body);r.title=i.title}else if(n==="body"){r=new DocumentFragment;const i=q(t);L(r,i.body);r.title=i.title}else{const i=q('<body><template class="internal-htmx-wrapper">'+t+"</template></body>");r=i.querySelector("template").content;r.title=i.title;var o=r.querySelector("title");if(o&&o.parentNode===r){o.remove();r.title=o.innerText}}if(r){if(Q.config.allowScriptTags){I(r)}else{r.querySelectorAll("script").forEach(e=>e.remove())}}return r}function oe(e){if(e){e()}}function t(e,t){return Object.prototype.toStrinLine truncated
|
||||
Reference in new issue
Block a user