Plugin Directory

Changeset 3493462


Ignore:
Timestamp:
03/28/2026 04:42:21 PM (10 hours ago)
Author:
nikanwp
Message:

Release version 3.0.0

Location:
wc-reports-lite/trunk
Files:
28 added
28 deleted
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • wc-reports-lite/trunk/assets/css/admin-style-rtl.css

    r2413794 r3493462  
    1 .wcrl_filterBox .form-field{
     1.WR_filterBox .form-field{
     2    float: right;
     3    overflow: hidden;
     4}
     5div.dt-buttons{
    26    float: right;
    37}
    4 .woo_pro_content,span.wooreports_logo{float: right;}
    5 .woo_pro_content{width: 27%;margin-right: 30px;}
    6 .woo_pro_features{margin-top: 30px;display: flex;flex-wrap: wrap;}
    7 .woo_pro_features .wcrl_col {flex: 0 0 28.9%;margin: 2.2%;}
    8 .woo_pro_features .wcrl_col img{border:1px solid #dee2e6!important;max-width: 100%;height: auto;}
     8
     9.wr-report-filter-bar {
     10  border-left: none;
     11  border-right: 3px solid var(--wr-accent);
     12}
     13
     14.wr-report-filter-bar__label {
     15  margin-right: 0;
     16  margin-left: 10px;
     17}
     18
     19/* Insights panel: slide from left in RTL */
     20.wr-insights-panel__drawer {
     21  right: auto;
     22  left: 0;
     23  transform: translateX(-100%);
     24}
     25.wr-insights-panel--open .wr-insights-panel__drawer {
     26  transform: translateX(0);
     27}
     28
     29/* Footer link arrow points left in RTL */
     30.wr-report-card__footer-link-icon {
     31  transform: scaleX(-1);
     32}
  • wc-reports-lite/trunk/assets/css/admin-style.css

    r2413794 r3493462  
    1 .wcrl_w_10{width: 10% !important;}
    2 .wcrl_w_25{width: 25% !important;}
     1.wr_w_25{width: 25% !important;}
    32.wooreport_hide{
    43    display: none;
     
    7675
    7776/*Overview admin page style*/
    78 #wcrl_overviewOrders{
     77#WR_overviewOrders{
    7978    background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
    8079    border: 1px none;
    8180    margin: 0 0 10px;
    8281}
    83 #wcrl_overviewOrders tbody tr th span {
     82#WR_overviewOrders tbody tr th span {
    8483    color: #21759B !important;
    8584    font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
    8685    font-size: 18px;
    8786}
    88 .wcrl_overviewTableStyle{
     87.WR_overviewTableStyle{
    8988    border: none !important;
    9089}
    91 .wcrl_overviewTableStyle thead tr th{
     90.WR_overviewTableStyle thead tr th{
    9291    font-weight: bold;
    9392    border-bottom: none !important;
     
    9594    font-size: 13px;
    9695}
    97 .wcrl_filterBox{
     96.WR_filterBox{
    9897    background: #fff;
    9998    padding: 15px;
     
    101100    border: 1px solid #e5e5e5;
    102101}
    103 .wcrl_filterBox .form-field{
     102.WR_filterBox .form-field{
    104103    width: 50%;
    105104    float: left;
    106105    margin-bottom: 16px;
    107 }
    108 .wcrl_filterBox .form-field label{
     106    overflow: hidden;
     107}
     108.WR_filterBox .form-field label{
    109109    display: block;
    110110    padding-bottom: 4px;
    111111}
    112 .wcrl_filterBox .form-field input {
     112.WR_filterBox .form-field input {
    113113    padding: 5px;
    114114}
    115 .wcrl_filterBox .form-field select {
     115.WR_filterBox .form-field select {
    116116    width: 95%;
    117117}
    118 .wcrl-settings-container ul.tabs {
     118.dt-buttons{
     119    margin-bottom: 12px;
     120}
     121.dt-buttons .dt-button{
     122    text-decoration: none;
     123    border-radius: 4px;
     124    border-bottom: 1px solid rgba(0, 0, 0, .05);
     125    padding: 7px;
     126    margin: 2px;
     127}
     128.dt-buttons .dt-button:first-child,.dt-buttons .dt-button:last-child{
     129    margin: 0;
     130}
     131.dt-buttons .dt-button:hover,.dt-buttons .dt-button:active,.dt-buttons .dt-button:visited{
     132    border-bottom: 1px solid rgba(0, 0, 0, .05) !important;
     133    border-top: none !important;
     134    border-right: none !important;
     135    border-left: none !important;
     136    box-shadow: none !important;
     137}
     138.dt-buttons .buttons-copy,.dt-buttons .buttons-excel:hover{
     139    background: #e5e5e5 !important;
     140    color: #777;
     141}
     142.dt-buttons .buttons-copy:before {
     143    content: "";
     144    display: block;
     145    background-image: url(../images/copy.svg);
     146    background-size: 17px 17px;
     147    height: 17px;
     148    width: 17px;
     149    float: left;
     150    margin-right: 10px;
     151    vertical-align: middle;
     152    margin-top: 2px;
     153}
     154.dt-buttons .buttons-excel,.dt-buttons .buttons-excel:hover{
     155    background: #c6e1c6 !important;
     156    color: #5b841b;
     157}
     158.dt-buttons .buttons-excel:before {
     159    content: "";
     160    display: block;
     161    background-image: url(../images/excel.svg);
     162    background-size: 17px 17px;
     163    height: 17px;
     164    width: 17px;
     165    float: left;
     166    margin-right: 10px;
     167    vertical-align: middle;
     168    margin-top: 2px;
     169}
     170.dt-buttons .buttons-csv,.dt-buttons .buttons-csv:hover{
     171    background: #eba3a3 !important;;
     172    color: #761919;
     173}
     174.dt-buttons .buttons-csv:before {
     175    content: "";
     176    display: block;
     177    background-image: url(../images/csv.svg);
     178    background-size: 17px 17px;
     179    height: 17px;
     180    width: 17px;
     181    float: left;
     182    margin-right: 10px;
     183    vertical-align: middle;
     184    margin-top: 2px;
     185}
     186.dt-buttons .buttons-pdf,.dt-buttons .buttons-pdf:hover{
     187    background: #f8dda7 !important;
     188    color: #94660c;
     189}
     190.dt-buttons .buttons-pdf:before {
     191    content: "";
     192    display: block;
     193    background-image: url(../images/pdf.svg);
     194    background-size: 17px 17px;
     195    height: 17px;
     196    width: 17px;
     197    float: left;
     198    margin-right: 10px;
     199    vertical-align: middle;
     200    margin-top: 2px;
     201}
     202.dt-buttons .buttons-print,.dt-buttons .buttons-print:hover{
     203    background: #c8d7e1 !important;
     204    color: #2e4453;
     205}
     206.dt-buttons .buttons-print:before {
     207    content: "";
     208    display: block;
     209    background-image: url(../images/printer.svg);
     210    background-size: 17px 17px;
     211    height: 17px;
     212    width: 17px;
     213    float: left;
     214    margin-right: 10px;
     215    vertical-align: middle;
     216    margin-top: 2px;
     217}
     218.wr-settings-container ul.tabs {
    119219    margin: 0;
    120220    padding: 0;
    121221    list-style: none;
    122222}
    123 .wcrl-settings-container ul.tabs li {
     223
     224.wr-settings-container ul.tabs li {
    124225    background: none;
    125226    color: #222;
     
    131232}
    132233
    133 .wcrl-settings-container ul.tabs li.current {
     234.wr-settings-container ul.tabs li.current {
    134235    background: #ffffff;
    135236    color: #222;
     
    141242}
    142243
    143 .wcrl-settings-container .tab-content {
     244.wr-settings-container .tab-content {
    144245    display: none;
    145246    background: #ffffff;
     
    151252}
    152253
    153 .wcrl-settings-container .tab-content.current {
     254.wr-settings-container .tab-content.current {
    154255    display: inherit;
    155256}
    156 .wcrl_customer_products_list{display: none}
    157 .wcrl_customer_products_list {
     257.WR_email_form_settings{
     258    display: none;
     259}
     260.wr_customer_products_list{display: none}
     261.wr_customer_products_list {
    158262    background: #dfedf5;
    159263    padding: 7px;
     
    162266    margin-bottom: 8px;
    163267}
    164 .woo_pro_content,span.wooreports_logo{float: left;}
    165 span.wooreports_logo{
    166     background: url(../images/wooreports.png);
    167     background-position: center;
    168     background-repeat: no-repeat;
    169     width: 150px;
    170     height: 150px;
    171     margin: 0 auto;
    172 }
    173 .woo_pro_content{width: 27%;margin-left: 30px;}
    174 .woo_pro_features{margin-top: 30px;display: flex;flex-wrap: wrap;}
    175 .woo_pro_features .wcrl_col {flex: 0 0 28.9%;margin: 2.2%;}
    176 .woo_pro_features .wcrl_col img{border:1px solid #dee2e6!important;max-width: 100%;height: auto;}
     268.w-70{width: 70%;}
     269.w-30{width: 30%;}
     270.d-flex{display: flex;}
     271.mr-3{margin-right: 1.5em;}
     272.ml-3{margin-left: 1.5em;}
     273.table-striped tbody tr:nth-of-type(odd) {background-color: rgba(0,0,0,.05);}
     274.table td, .table th {padding: .75rem;vertical-align: top;border-top: 1px solid #dee2e6;}
     275.table {width: 100%;max-width: 100%;margin-bottom: 1rem;background-color: transparent;}
     276.select2-container .select2-search--inline .select2-search__field {box-sizing: border-box;border: none;font-size: 100%;margin-top: 0;margin-left: 5px;padding: 0;max-width: 100%;resize: none;height: 18px;vertical-align: bottom;font-family: sans-serif;overflow: hidden;word-break: keep-all;}
     277.nw_export_button{ text-decoration: none; border-radius: 4px; border-bottom: 1px solid rgba(0, 0, 0, .05); padding: 7px; margin: 2px 2px 10px 2px; position: relative; display: inline-block; box-sizing: border-box; cursor: pointer; font-size: 13px; line-height: 1.6em;  }
     278.nw_export_excel{ background: #c6e1c6 !important; color: #5b841b; }
     279.nw_export_pdf{ background: #f8dda7 !important; color: #94660c; }
     280.nw_export_excel:before { content: ""; display: block; background-image: url(../images/excel.svg); background-size: 17px 17px; height: 17px; width: 17px; float: left; margin-right: 10px; vertical-align: middle; margin-top: 2px; }
     281.nw_export_pdf:before { content: ""; display: block; background-image: url(../images/pdf.svg); background-size: 17px 17px; height: 17px; width: 17px; float: left; margin-right: 10px; vertical-align: middle; margin-top: 2px; }
     282
     283/* Consistent hover for export buttons (all reports) */
     284.nw_export_excel:hover {
     285  background: #b7d8b7 !important;
     286  color: #4c6f16;
     287}
     288.nw_export_pdf:hover {
     289  background: #f0d08a !important;
     290  color: #7a5208;
     291}
     292.tablenav{ height: 55px; }
     293@media (max-width: 768px) {
     294    .wr-before-report-table{flex-direction: column;gap:10px;}
     295    .wr-before-report-table > .w-70,.wr-before-report-table > .w-30,.wr-before-report-table .WR_filterBox .form-field{width: 100% !important;}
     296    .wr-before-report-table > .w-30{padding: 0}
     297}
     298
     299/* ========== WooReports: shared report pages (Overview and others) ========== */
     300/* Dark topbar, light content area, white cards. Single CSS for all report menus. */
     301
     302body.wr-report-admin {
     303  overflow-x: hidden;
     304}
     305
     306.wr-report-page {
     307  --wr-topbar-bg: #1e2a38;
     308  --wr-topbar-text: #ffffff;
     309  --wr-topbar-muted: rgba(255, 255, 255, 0.85);
     310  --wr-content-bg: #f0f2f5;
     311  --wr-card-bg: #ffffff;
     312  --wr-card-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
     313  --wr-card-radius: 8px;
     314  --wr-text: #202124;
     315  --wr-text-secondary: #5f6368;
     316  --wr-accent: #1a73e8;
     317  --wr-border: #dadce0;
     318  --wr-font: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
     319  padding: 0;
     320  font-family: var(--wr-font);
     321  box-sizing: border-box;
     322  max-width: 100%;
     323  overflow-x: hidden;
     324  background: var(--wr-content-bg);
     325}
     326
     327/* Constrain width and align with report cards */
     328.wr-report-page__inner {
     329  max-width: 1400px;
     330  margin: 0 auto;
     331  padding: 24px;
     332  box-sizing: border-box;
     333}
     334
     335/* Single card containing filter + KPIs + quick links */
     336.wr-report-top-card {
     337  background: var(--wr-card-bg);
     338  border-radius: var(--wr-card-radius);
     339  box-shadow: var(--wr-card-shadow);
     340  overflow: hidden;
     341  margin-bottom: 24px;
     342}
     343
     344.wr-report-topbar {
     345  display: flex;
     346  align-items: center;
     347  justify-content: space-between;
     348  flex-wrap: wrap;
     349  gap: 12px;
     350  min-height: 56px;
     351  padding: 0 24px;
     352  background: var(--wr-topbar-bg);
     353  color: var(--wr-topbar-text);
     354  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
     355}
     356
     357.wr-report-topbar__left {
     358  display: flex;
     359  align-items: center;
     360  gap: 12px;
     361}
     362
     363.wr-report-topbar__logo {
     364  width: 24px;
     365  height: 24px;
     366  background: var(--wr-accent);
     367  border-radius: 6px;
     368  flex-shrink: 0;
     369}
     370
     371.wr-report-topbar__title {
     372  font-size: 18px;
     373  font-weight: 600;
     374  color: var(--wr-topbar-text);
     375}
     376
     377.wr-report-topbar__page {
     378  font-size: 14px;
     379  color: var(--wr-topbar-muted);
     380  font-weight: 500;
     381}
     382
     383.wr-report-topbar__center {
     384  display: flex;
     385  align-items: center;
     386}
     387
     388.wr-report-topbar__center .daterangeactions {
     389  margin: 0;
     390}
     391
     392/* Filter bar — inside top card */
     393.wr-report-filter-bar {
     394  display: flex;
     395  align-items: center;
     396  justify-content: space-between;
     397  gap: 16px;
     398  padding: 16px 20px;
     399  margin: 0;
     400  background: #f8f9fa;
     401  border-bottom: 1px solid var(--wr-border);
     402  border-left: 3px solid var(--wr-accent);
     403  font-family: var(--wr-font);
     404}
     405
     406/* Insights trigger in filter bar (opens slide-out panel) */
     407.wr-insights-trigger {
     408  flex-shrink: 0;
     409  display: inline-flex;
     410  align-items: center;
     411  justify-content: center;
     412  gap: 7px;
     413  height: 38px;
     414  padding: 0 18px;
     415  margin-right: 20px;
     416  border: none;
     417  border-radius: 10px;
     418  background: linear-gradient(135deg, #fbbf24, #f59e0b);
     419  color: #78350f;
     420  font-size: 13px;
     421  font-weight: 600;
     422  cursor: pointer;
     423  box-shadow: 0 2px 8px rgba(245, 158, 11, 0.25);
     424  transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
     425  letter-spacing: 0.2px;
     426}
     427
     428.wr-insights-trigger:hover {
     429  color: #78350f;
     430  background: linear-gradient(135deg, #f59e0b, #d97706);
     431  box-shadow: 0 4px 14px rgba(245, 158, 11, 0.35);
     432  transform: translateY(-1px);
     433}
     434
     435.wr-insights-trigger:focus {
     436  box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.4);
     437  outline: none;
     438}
     439
     440.wr-insights-trigger:active {
     441  transform: translateY(0);
     442  box-shadow: 0 1px 4px rgba(245, 158, 11, 0.2);
     443}
     444
     445.wr-insights-trigger__icon {
     446  display: block;
     447  width: 18px;
     448  height: 18px;
     449  flex-shrink: 0;
     450}
     451
     452.wr-report-filter-bar__label {
     453  font-size: 13px;
     454  font-weight: 500;
     455  color: var(--wr-text-secondary);
     456  margin-left: 0;
     457  margin-right: 10px;
     458}
     459
     460.wr-date-input {
     461  font-size: 13px;
     462  padding: 6px 8px;
     463  border: 1px solid var(--wr-border);
     464  border-radius: 4px;
     465  background: var(--wr-card-bg);
     466}
     467
     468.wr-report-filter-bar__sep {
     469  color: var(--wr-text-secondary);
     470  font-size: 13px;
     471}
     472
     473.wr-compare-label {
     474  display: inline-flex;
     475  align-items: center;
     476  gap: 6px;
     477  font-size: 13px;
     478  color: var(--wr-text-secondary);
     479  cursor: pointer;
     480  white-space: nowrap;
     481}
     482
     483.wr-report-filter-form {
     484  display: flex;
     485  align-items: center;
     486  gap: 12px;
     487  flex-wrap: wrap;
     488  padding: 0;
     489  margin: 0;
     490  background: transparent;
     491  border: none;
     492  border-radius: 0;
     493  box-shadow: none;
     494  font-family: var(--wr-font);
     495}
     496
     497/* Report filter layout (all pages) */
     498.wr-report-filter-form .WR_filterBox {
     499  display: flex;
     500  flex-wrap: nowrap;
     501  align-items: flex-start;
     502  gap: 12px 16px;
     503}
     504
     505.wr-report-filter-form .form-field {
     506  margin-bottom: 0;
     507  display: flex;
     508  flex-direction: column;
     509  align-items: flex-start;
     510  gap: 4px;
     511}
     512
     513.wr-report-filter-form input[name="WR_fromDate"],
     514.wr-report-filter-form input[name="WR_toDate"] {
     515  width: 170px;
     516}
     517
     518.wr-report-filter-form select[name="WR_orderStatuses[]"] {
     519  min-width: 280px;
     520  max-width: 320px;
     521}
     522
     523.wr-report-filter-form input[name="order_number"] {
     524  width: 180px;
     525}
     526
     527.wr-report-filter-form .wr-filter-actions {
     528  display: flex;
     529  align-items: center;
     530  gap: 8px;
     531}
     532
     533/* KPI row — Orders, Sales, AOV, Items sold (clickable, optional % change) */
     534.wr-report-kpis {
     535  display: grid;
     536  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
     537  gap: 16px;
     538  padding: 20px;
     539  margin: 0;
     540  background: var(--wr-card-bg);
     541  border-bottom: 1px solid var(--wr-border);
     542}
     543
     544.wr-kpi-card {
     545  position: relative;
     546  padding: 20px 20px 16px;
     547  background: var(--wr-content-bg);
     548  border-radius: 12px;
     549  border: 1px solid var(--wr-border);
     550  text-align: left;
     551  display: flex;
     552  flex-direction: column;
     553  gap: 6px;
     554  overflow: hidden;
     555  transition: border-color 0.2s, box-shadow 0.2s, transform 0.2s;
     556}
     557
     558.wr-kpi-card::before {
     559  content: '';
     560  position: absolute;
     561  top: 0;
     562  left: 0;
     563  right: 0;
     564  height: 3px;
     565  background: linear-gradient(90deg, var(--wr-accent), rgba(26,115,232,0.3));
     566  border-radius: 12px 12px 0 0;
     567  opacity: 0;
     568  transition: opacity 0.2s;
     569}
     570
     571.wr-kpi-card:hover::before {
     572  opacity: 1;
     573}
     574
     575.wr-kpi-card--link {
     576  text-decoration: none;
     577  color: inherit;
     578  cursor: pointer;
     579}
     580
     581.wr-kpi-card--link:hover,
     582.wr-kpi-card--nolink:hover {
     583  border-color: rgba(26,115,232,0.35);
     584  box-shadow: 0 4px 16px rgba(26, 115, 232, 0.10), 0 1px 4px rgba(0,0,0,0.04);
     585  transform: translateY(-2px);
     586}
     587
     588.wr-kpi-card__label {
     589  font-size: 12px;
     590  color: var(--wr-text-secondary);
     591  font-weight: 500;
     592  text-transform: uppercase;
     593  letter-spacing: 0.4px;
     594  line-height: 1.3;
     595  order: -1;
     596}
     597
     598.wr-kpi-card__value {
     599  display: block;
     600  font-size: 26px;
     601  font-weight: 700;
     602  color: var(--wr-text);
     603  line-height: 1.2;
     604  letter-spacing: -0.5px;
     605}
     606
     607.wr-kpi-card__value .woocommerce-Price-currencySymbol {
     608  font-size: 0.7em;
     609  font-weight: 600;
     610  opacity: 0.6;
     611  margin-inline-end: 1px;
     612}
     613
     614.wr-kpi-card__change {
     615  display: inline-flex;
     616  align-items: center;
     617  gap: 3px;
     618  font-size: 12px;
     619  font-weight: 600;
     620  margin-top: 2px;
     621  padding: 3px 8px;
     622  border-radius: 20px;
     623  width: fit-content;
     624}
     625
     626.wr-kpi-card__change--up {
     627  color: #0d7c43;
     628  background: rgba(52, 168, 83, 0.12);
     629}
     630
     631.wr-kpi-card__change--up::before {
     632  content: '↑';
     633  font-size: 11px;
     634}
     635
     636.wr-kpi-card__change--down {
     637  color: #c5221f;
     638  background: rgba(234, 67, 53, 0.10);
     639}
     640
     641.wr-kpi-card__change--down::before {
     642  content: '↓';
     643  font-size: 11px;
     644}
     645
     646.wr-kpi-card__period {
     647  font-weight: 400;
     648  opacity: 0.7;
     649  font-size: 11px;
     650  text-transform: none;
     651  letter-spacing: 0;
     652}
     653
     654/* Styled tooltip for KPI period (replaces native title on hover) */
     655.wr-kpi-card__tooltip {
     656  position: absolute;
     657  bottom: calc(100% + 4px);
     658  left: 50%;
     659  transform: translateX(-50%) translateY(4px);
     660  padding: 8px 14px;
     661  background: #1e293b;
     662  color: #fff;
     663  font-size: 12px;
     664  font-weight: 500;
     665  line-height: 1.4;
     666  white-space: nowrap;
     667  border-radius: 8px;
     668  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
     669  opacity: 0;
     670  pointer-events: none;
     671  transition: opacity 0.2s ease, transform 0.2s ease;
     672  z-index: 10;
     673}
     674
     675.wr-kpi-card__tooltip::after {
     676  content: '';
     677  position: absolute;
     678  top: 100%;
     679  left: 50%;
     680  margin-left: -6px;
     681  border: 6px solid transparent;
     682  border-top-color: #1e293b;
     683}
     684
     685.wr-kpi-card--link:hover .wr-kpi-card__tooltip,
     686.wr-kpi-card--nolink:hover .wr-kpi-card__tooltip {
     687  opacity: 1;
     688  transform: translateX(-50%) translateY(0);
     689}
     690
     691/* Report card footer: link to full report page */
     692.wr-report-card__footer {
     693  display: flex;
     694  align-items: center;
     695  gap: 10px;
     696  padding: 14px 20px;
     697  border-top: 1px solid var(--wr-border);
     698  background: var(--wr-card-bg);
     699  border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius);
     700}
     701
     702.wr-report-card__footer-link {
     703  display: inline-flex;
     704  align-items: center;
     705  gap: 6px;
     706  font-size: 12px;
     707  font-weight: 600;
     708  color: var(--wr-accent);
     709  text-decoration: none;
     710  padding: 6px 14px;
     711  border: 1px solid rgba(26, 115, 232, 0.25);
     712  border-radius: 8px;
     713  background: rgba(26, 115, 232, 0.06);
     714  transition: background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.15s;
     715  white-space: nowrap;
     716  letter-spacing: 0.15px;
     717}
     718
     719.wr-report-card__footer-link:hover {
     720  text-decoration: none;
     721  background: rgba(26, 115, 232, 0.12);
     722  border-color: rgba(26, 115, 232, 0.45);
     723  box-shadow: 0 2px 8px rgba(26, 115, 232, 0.12);
     724  transform: translateY(-1px);
     725  color: var(--wr-accent);
     726}
     727
     728.wr-report-card__footer-link:active {
     729  transform: translateY(0);
     730  box-shadow: none;
     731}
     732
     733.wr-report-card__footer-link-icon {
     734  flex-shrink: 0;
     735  width: 14px;
     736  height: 14px;
     737}
     738
     739.wr-export-csv-link::before {
     740  content: '';
     741  display: inline-block;
     742  width: 14px;
     743  height: 14px;
     744  background: currentColor;
     745  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E");
     746  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpolyline points='7 10 12 15 17 10'/%3E%3Cline x1='12' y1='15' x2='12' y2='3'/%3E%3C/svg%3E");
     747  mask-size: contain;
     748  -webkit-mask-size: contain;
     749  mask-repeat: no-repeat;
     750  -webkit-mask-repeat: no-repeat;
     751  flex-shrink: 0;
     752}
     753
     754/* Native select (fallback when Select2 not yet init) */
     755.wr-report-filter-form select {
     756  background: #fff;
     757  border: 1px solid var(--wr-border);
     758  color: var(--wr-text);
     759  padding: 8px 12px;
     760  border-radius: 6px;
     761  font-size: 13px;
     762  min-width: 200px;
     763  height: 38px;
     764  line-height: 1.4;
     765}
     766
     767.wr-report-filter-form select:focus {
     768  border-color: var(--wr-accent);
     769  outline: none;
     770  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
     771}
     772
     773.wr-report-filter-form option {
     774  background: #fff;
     775  color: var(--wr-text);
     776}
     777
     778/* Select2 container — fixed height to match button (38px) */
     779.wr-report-filter-form .select2-container {
     780  min-width: 220px;
     781  height: 38px !important;
     782}
     783
     784.wr-report-filter-form .select2-container .select2-selection--multiple {
     785  height: 38px !important;
     786  min-height: 38px !important;
     787  max-height: 38px !important;
     788  padding: 0 8px;
     789  border: 1px solid var(--wr-border);
     790  border-radius: 6px;
     791  background: #fff;
     792  box-sizing: border-box;
     793  display: flex !important;
     794  align-items: center;
     795  overflow: hidden;
     796}
     797
     798.wr-report-filter-form .select2-container .select2-selection--single {
     799  height: 38px !important;
     800  min-height: 38px !important;
     801  padding: 0 8px;
     802  border: 1px solid var(--wr-border);
     803  border-radius: 6px;
     804  background: #fff;
     805  box-sizing: border-box;
     806  display: flex !important;
     807  align-items: center;
     808}
     809
     810.wr-report-filter-form .select2-container .select2-selection--single .select2-selection__rendered {
     811  padding: 0;
     812  line-height: 36px;
     813  color: var(--wr-text);
     814  font-size: 13px;
     815}
     816
     817.wr-report-filter-form .select2-container .select2-selection--single .select2-selection__arrow {
     818  height: 36px;
     819  top: 0;
     820}
     821
     822.wr-report-filter-form .select2-container.select2-container--focus .select2-selection--multiple,
     823.wr-report-filter-form .select2-container.select2-container--open .select2-selection--multiple,
     824.wr-report-filter-form .select2-container.select2-container--focus .select2-selection--single,
     825.wr-report-filter-form .select2-container.select2-container--open .select2-selection--single {
     826  border-color: var(--wr-accent);
     827  outline: none;
     828  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
     829}
     830
     831.wr-report-filter-form .select2-container .select2-selection__rendered {
     832  padding: 0;
     833  display: flex;
     834  align-items: center;
     835  flex-wrap: wrap;
     836  gap: 4px;
     837  min-height: 36px;
     838}
     839
     840.wr-report-filter-form .select2-container .select2-search__field {
     841  margin: 0;
     842  padding: 4px 4px;
     843  font-size: 13px;
     844  color: var(--wr-text);
     845  height: 28px;
     846  line-height: 28px;
     847  min-height: 0;
     848}
     849
     850.wr-report-filter-form .select2-container .select2-selection__choice {
     851  background: var(--wr-content-bg);
     852  border: 1px solid var(--wr-border);
     853  border-radius: 4px;
     854  padding: 2px 8px;
     855  font-size: 12px;
     856  color: var(--wr-text);
     857}
     858
     859/* Filter button — same height as Select2 (38px) */
     860.wr-report-filter-form .button {
     861  height: 38px !important;
     862  min-height: 38px !important;
     863  padding: 0 18px !important;
     864  line-height: 36px !important;
     865  font-size: 13px !important;
     866  font-weight: 500;
     867  border-radius: 6px;
     868  cursor: pointer;
     869  box-sizing: border-box;
     870  transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
     871  display: inline-flex;
     872  align-items: center;
     873  justify-content: center;
     874}
     875
     876.wr-report-filter-form .button-primary {
     877  border-color: var(--wr-accent);
     878  background: var(--wr-accent);
     879}
     880
     881.wr-report-filter-form .button-primary:hover {
     882  background: #1557b0;
     883  border-color: #1557b0;
     884  box-shadow: 0 1px 3px rgba(26, 115, 232, 0.35);
     885}
     886
     887.wr-report-filter-form .button-primary:focus {
     888  border-color: var(--wr-accent);
     889  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.35);
     890}
     891
     892.wr-report-topbar__btn {
     893  background: rgba(255, 255, 255, 0.2) !important;
     894  border: 1px solid rgba(255, 255, 255, 0.4) !important;
     895  color: var(--wr-topbar-text) !important;
     896  padding: 8px 18px !important;
     897  border-radius: 6px !important;
     898  font-size: 13px !important;
     899  font-weight: 500 !important;
     900  cursor: pointer;
     901}
     902
     903.wr-report-topbar__btn:hover {
     904  background: rgba(255, 255, 255, 0.3) !important;
     905  border-color: rgba(255, 255, 255, 0.5) !important;
     906  color: #fff !important;
     907}
     908
     909.wr-report-topbar__right {
     910  display: flex;
     911  align-items: center;
     912  gap: 8px;
     913}
     914
     915.wr-report-topbar__icon {
     916  width: 36px;
     917  height: 36px;
     918  border-radius: 50%;
     919  background: rgba(255, 255, 255, 0.1);
     920  display: inline-flex;
     921  align-items: center;
     922  justify-content: center;
     923  color: var(--wr-topbar-text);
     924  cursor: pointer;
     925}
     926
     927.wr-report-topbar__icon:hover {
     928  background: rgba(255, 255, 255, 0.2);
     929}
     930
     931.wr-report-topbar__icon--help:before {
     932  content: "?";
     933  font-size: 16px;
     934  font-weight: 600;
     935}
     936
     937/* Trend chart block */
     938#wr-card-trend .wr-report-card__body {
     939  min-height: 200px;
     940}
     941
     942.wr-sales-by-source-chart-wrap {
     943  max-width: 320px;
     944  margin: 0 auto;
     945  padding: 8px 0 0;
     946  position: relative;
     947}
     948
     949#wr-card-trend #WR_ChartTrend {
     950  max-width: 100%;
     951}
     952
     953/* Insights slide-out panel (right side, like Google Analytics) */
     954.wr-insights-panel {
     955  position: fixed;
     956  top: 0;
     957  left: 0;
     958  right: 0;
     959  bottom: 0;
     960  z-index: 99999;
     961  pointer-events: none;
     962  visibility: hidden;
     963  transition: visibility 0.25s ease;
     964}
     965
     966.wr-insights-panel--open {
     967  pointer-events: auto;
     968  visibility: visible;
     969}
     970
     971.wr-insights-panel__backdrop {
     972  position: absolute;
     973  top: 0;
     974  left: 0;
     975  right: 0;
     976  bottom: 0;
     977  background: rgba(0, 0, 0, 0.35);
     978  opacity: 0;
     979  transition: opacity 0.25s ease;
     980  z-index: 0;
     981}
     982
     983.wr-insights-panel--open .wr-insights-panel__backdrop {
     984  opacity: 1;
     985}
     986
     987.wr-insights-panel__drawer {
     988  position: absolute;
     989  top: 0;
     990  right: 0;
     991  width: 100%;
     992  max-width: 380px;
     993  height: 100%;
     994  background: #ffffff;
     995  box-shadow: -4px 0 24px rgba(0, 0, 0, 0.12);
     996  transform: translateX(100%);
     997  transition: transform 0.25s ease;
     998  display: flex;
     999  flex-direction: column;
     1000  overflow: hidden;
     1001  z-index: 1;
     1002}
     1003
     1004.wr-insights-panel--open .wr-insights-panel__drawer {
     1005  transform: translateX(0);
     1006}
     1007
     1008.wr-insights-panel__header {
     1009  flex-shrink: 0;
     1010  display: flex;
     1011  align-items: center;
     1012  gap: 12px;
     1013  padding: 20px;
     1014  border-bottom: 1px solid var(--wr-border);
     1015  background: var(--wr-card-bg);
     1016}
     1017
     1018.wr-insights-panel__header-icon {
     1019  flex-shrink: 0;
     1020  color: var(--wr-accent);
     1021}
     1022
     1023.wr-insights-panel__header-text {
     1024  flex: 1;
     1025  min-width: 0;
     1026}
     1027
     1028.wr-insights-panel__title {
     1029  margin: 0;
     1030  font-size: 18px;
     1031  font-weight: 600;
     1032  color: var(--wr-text);
     1033  font-family: var(--wr-font);
     1034}
     1035
     1036.wr-insights-panel__context {
     1037  margin: 4px 0 0;
     1038  font-size: 12px;
     1039  font-weight: 400;
     1040  color: var(--wr-text-secondary);
     1041  line-height: 1.3;
     1042}
     1043
     1044.wr-insights-panel__close {
     1045  flex-shrink: 0;
     1046  width: 36px;
     1047  height: 36px;
     1048  padding: 0;
     1049  border: none;
     1050  border-radius: 50%;
     1051  background: transparent;
     1052  color: var(--wr-text-secondary);
     1053  cursor: pointer;
     1054  font-size: 24px;
     1055  line-height: 1;
     1056  display: inline-flex;
     1057  align-items: center;
     1058  justify-content: center;
     1059  transition: background 0.15s ease, color 0.15s ease;
     1060}
     1061
     1062.wr-insights-panel__close:hover {
     1063  background: var(--wr-content-bg);
     1064  color: var(--wr-text);
     1065}
     1066
     1067.wr-insights-panel__body {
     1068  flex: 1;
     1069  overflow-y: auto;
     1070  padding: 20px;
     1071  background: #ffffff;
     1072}
     1073
     1074.wr-insights-panel__loading {
     1075  display: flex;
     1076  align-items: center;
     1077  gap: 8px;
     1078  font-size: 14px;
     1079  color: var(--wr-text-secondary);
     1080}
     1081
     1082.wr-insights-panel__loading .spinner {
     1083  float: none;
     1084  margin: 0;
     1085}
     1086
     1087.wr-insights-list {
     1088  margin: 0;
     1089  padding: 0;
     1090  list-style: none;
     1091  font-size: 14px;
     1092}
     1093
     1094.wr-insight-item {
     1095  padding: 8px 0;
     1096  border-bottom: 1px solid var(--wr-border);
     1097  display: flex;
     1098  flex-wrap: wrap;
     1099  gap: 6px 8px;
     1100  align-items: baseline;
     1101}
     1102
     1103.wr-insight-item:last-child {
     1104  border-bottom: none;
     1105}
     1106
     1107.wr-insight-item__label {
     1108  font-weight: 500;
     1109  color: var(--wr-text-secondary);
     1110}
     1111
     1112.wr-insight-item__value {
     1113  color: var(--wr-text);
     1114}
     1115
     1116.wr-report-content {
     1117  background: transparent;
     1118  min-height: 0;
     1119  padding: 0;
     1120  box-sizing: border-box;
     1121  overflow-x: hidden;
     1122  width: 100%;
     1123}
     1124
     1125/* 2 columns max so cards are wide; prevents horizontal scroll from grid */
     1126.wr-report-cards {
     1127  display: grid;
     1128  grid-template-columns: repeat(2, 1fr);
     1129  gap: 24px;
     1130  width: 100%;
     1131  min-width: 0;
     1132}
     1133
     1134/* Top row: Sales trend then Overview Orders, both full width stacked */
     1135.wr-report-cards__top-row {
     1136  grid-column: 1 / -1;
     1137  display: grid;
     1138  grid-template-columns: 1fr 1.25fr;
     1139  gap: 24px;
     1140  min-width: 0;
     1141}
     1142.wr-report-cards__top-row--stack {
     1143  grid-template-columns: 1fr;
     1144}
     1145
     1146/* Two-column row: Overview Orders + Sales by source side by side */
     1147.wr-report-cards__two-col {
     1148  grid-column: 1 / -1;
     1149  display: grid;
     1150  grid-template-columns: 1fr 1fr;
     1151  gap: 24px;
     1152  min-width: 0;
     1153}
     1154
     1155/* Section heading above "Top" report cards */
     1156.wr-report-cards__heading {
     1157  grid-column: 1 / -1;
     1158  margin: 32px 0 8px;
     1159  padding: 0;
     1160  font-size: 18px;
     1161  font-weight: 600;
     1162  color: var(--wr-text);
     1163  font-family: var(--wr-font);
     1164}
     1165.wr-report-cards__heading:first-child {
     1166  margin-top: 0;
     1167}
     1168
     1169.wr-report-card {
     1170  background: var(--wr-card-bg);
     1171  border-radius: var(--wr-card-radius);
     1172  box-shadow: var(--wr-card-shadow);
     1173  overflow: hidden;
     1174  min-width: 0;
     1175}
     1176
     1177.wr-report-card__header {
     1178  display: flex;
     1179  align-items: center;
     1180  justify-content: space-between;
     1181  flex-wrap: wrap;
     1182  gap: 8px;
     1183  margin: 0;
     1184  padding: 16px 20px;
     1185  background: var(--wr-card-bg);
     1186  border-bottom: 1px solid var(--wr-border);
     1187  font-size: 15px;
     1188  font-weight: 600;
     1189  color: var(--wr-text);
     1190  font-family: var(--wr-font);
     1191}
     1192
     1193.wr-report-card__title {
     1194  margin: 0;
     1195}
     1196
     1197.wr-report-card__description {
     1198  width: 100%;
     1199  margin: 6px 0 0;
     1200  font-size: 13px;
     1201  font-weight: 400;
     1202  color: var(--wr-text-secondary);
     1203  line-height: 1.4;
     1204}
     1205
     1206.wr-report-card__header:has(.wr-report-card__description) {
     1207  flex-direction: column;
     1208  align-items: flex-start;
     1209}
     1210
     1211.wr-report-card__header:has(.wr-report-card__description) .wr-report-card__actions {
     1212  margin-top: 4px;
     1213}
     1214
     1215.wr-report-card__actions {
     1216  display: flex;
     1217  align-items: center;
     1218  gap: 4px;
     1219}
     1220
     1221/* Card actions: make Export + Summary buttons same size in one row */
     1222.wr-report-card__actions .nw_export_button,
     1223.wr-report-card__actions .wr-summary-trigger {
     1224  height: 36px;
     1225  min-height: 36px;
     1226  padding: 0 14px;
     1227  font-size: 13px;
     1228  font-weight: 500;
     1229  border-radius: 6px;
     1230  display: inline-flex;
     1231  align-items: center;
     1232  justify-content: center;
     1233  box-sizing: border-box;
     1234  line-height: 1;
     1235}
     1236
     1237/* Remove old margins/line-height from generic export style inside card header */
     1238.wr-report-card__actions .nw_export_button {
     1239  margin: 0;
     1240  border-bottom: none;
     1241}
     1242
     1243.wr-report-card__actions .wr-chart-btn,
     1244.wr-report-card__actions .wr-table-btn {
     1245  padding: 6px 10px;
     1246  border: 1px solid transparent;
     1247  border-radius: 6px;
     1248  background: transparent;
     1249  color: var(--wr-text-secondary);
     1250  cursor: pointer;
     1251  font-size: 13px;
     1252  transition: color 0.15s, background 0.15s, border-color 0.15s, box-shadow 0.15s;
     1253}
     1254
     1255.wr-report-card__actions .wr-chart-btn:hover,
     1256.wr-report-card__actions .wr-table-btn:hover {
     1257  color: var(--wr-accent);
     1258  background: rgba(26, 115, 232, 0.08);
     1259}
     1260
     1261.wr-report-card__actions .wr-chart-btn.is-active,
     1262.wr-report-card__actions .wr-table-btn.is-active {
     1263  color: var(--wr-accent);
     1264  background: rgba(26, 115, 232, 0.10);
     1265  border-color: var(--wr-accent);
     1266  box-shadow: 0 1px 3px rgba(26, 115, 232, 0.15);
     1267}
     1268
     1269/* Segment card chart wrapper */
     1270.wr-report-card__body .wr-segment-chart-wrap {
     1271  position: relative;
     1272  padding: 16px 20px 12px;
     1273  min-height: 260px;
     1274}
     1275.wr-report-card__body .wr-segment-chart-wrap canvas {
     1276  max-width: 100%;
     1277}
     1278
     1279.wr-report-card__body {
     1280  padding: 20px;
     1281  font-size: 14px;
     1282  color: var(--wr-text);
     1283}
     1284
     1285.wr-report-card--full {
     1286  grid-column: 1 / -1;
     1287}
     1288
     1289/* Empty state for report tables with no data */
     1290.wr-report-page .wr-report-table-empty {
     1291  text-align: center;
     1292  padding: 24px 16px;
     1293  color: var(--wr-text-secondary);
     1294  font-size: 14px;
     1295}
     1296
     1297.wr-report-page .wr-report-error {
     1298  padding: 16px;
     1299  color: var(--wr-text-secondary);
     1300  background: rgba(0, 0, 0, 0.04);
     1301  border-left: 4px solid var(--wr-accent);
     1302  border-radius: 0 4px 4px 0;
     1303  margin: 8px 0;
     1304}
     1305
     1306/* Tables inside report cards; contain overflow to prevent horizontal scroll */
     1307.wr-report-page .wr-report-card__body {
     1308  overflow-x: auto;
     1309}
     1310.wr-report-page .WR_overviewTableStyle,
     1311.wr-report-page .widefat.table-stats,
     1312.wr-report-page #WR_overviewOrders {
     1313  border: none;
     1314  border-bottom: none;
     1315  margin: 0;
     1316  width: 100%;
     1317  max-width: 100%;
     1318  background: transparent;
     1319}
     1320
     1321/* Remove any gray border at bottom of Overview Orders table (override WP .widefat) */
     1322#wr-card-overview-orders #WR_overviewOrders,
     1323#wr-card-overview-orders #WR_overviewOrders thead,
     1324#wr-card-overview-orders #WR_overviewOrders tbody,
     1325#wr-card-overview-orders #WR_overviewOrders th,
     1326#wr-card-overview-orders #WR_overviewOrders td,
     1327#wr-card-overview-orders #WR_overviewOrders thead th,
     1328#wr-card-overview-orders #WR_overviewOrders tbody th,
     1329#wr-card-overview-orders #WR_overviewOrders tbody td,
     1330#wr-card-overview-orders #WR_overviewOrders tbody tr:last-child th,
     1331#wr-card-overview-orders #WR_overviewOrders tbody tr:last-child td {
     1332  border-bottom: none !important;
     1333  border-top: none !important;
     1334}
     1335
     1336#wr-card-overview-orders #WR_overviewOrders {
     1337  border: none !important;
     1338  box-shadow: none !important;
     1339  outline: none !important;
     1340}
     1341
     1342/* Remove bottom border from Overview Orders card body (in case line is from container) */
     1343#wr-card-overview-orders .wr-report-card__body {
     1344  border-bottom: none !important;
     1345}
     1346.wr-report-page .wr-report-card__body canvas {
     1347  max-width: 100%;
     1348}
     1349
     1350.wr-report-page .WR_overviewTableStyle thead th,
     1351.wr-report-page #WR_overviewOrders thead th {
     1352  font-size: 11px;
     1353  font-weight: 600;
     1354  text-transform: uppercase;
     1355  letter-spacing: 0.04em;
     1356  color: var(--wr-text-secondary);
     1357  padding: 10px 14px;
     1358  border: none;
     1359  background: transparent;
     1360}
     1361
     1362.wr-report-page .WR_overviewTableStyle thead th {
     1363  border-bottom: none;
     1364}
     1365
     1366.wr-report-page .WR_overviewTableStyle tbody td,
     1367.wr-report-page #WR_overviewOrders tbody th,
     1368.wr-report-page #WR_overviewOrders tbody td {
     1369  padding: 12px 14px;
     1370  border: none;
     1371  border-bottom: none;
     1372  font-size: 14px;
     1373  color: var(--wr-text);
     1374  background: transparent;
     1375}
     1376
     1377/* Simple tables in cards: no row background, no border-bottom */
     1378.wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr,
     1379.wr-report-page .wr-report-card .widefat tbody tr {
     1380  background: transparent;
     1381}
     1382
     1383/* No gray border at end of table or on last row */
     1384.wr-report-page .wr-report-card .wr-report-card__body .widefat,
     1385.wr-report-page .wr-report-card .wr-report-card__body .WR_overviewTableStyle,
     1386.wr-report-page .wr-report-card .wr-report-card__body .widefat tbody tr:last-child td,
     1387.wr-report-page .wr-report-card .wr-report-card__body .WR_overviewTableStyle tbody tr:last-child td {
     1388  border-bottom: none !important;
     1389}
     1390
     1391/* Odd rows (1st, 3rd, 5th…): very light gray for clearer tables */
     1392.wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr:nth-of-type(odd),
     1393.wr-report-page .wr-report-card .widefat.striped tbody tr:nth-of-type(odd),
     1394.wr-report-page .wr-report-card .widefat tbody tr:nth-of-type(odd),
     1395.wr-report-page #WR_overviewOrders tbody tr:nth-of-type(odd) {
     1396  background: rgba(0, 0, 0, 0.02);
     1397}
     1398
     1399.wr-report-page .WR_overviewTableStyle tbody tr:hover,
     1400.wr-report-page .wr-report-card .WR_overviewTableStyle tbody tr:hover,
     1401.wr-report-page .wr-report-card .widefat tbody tr:hover,
     1402.wr-report-page #WR_overviewOrders tbody tr:hover {
     1403  background: transparent;
     1404}
     1405
     1406.wr-report-page #WR_overviewOrders tbody th span {
     1407  color: var(--wr-accent) !important;
     1408  font-size: 16px !important;
     1409  font-weight: 600;
     1410}
     1411
     1412.wr-report-page .wr-report-filter-bar__label--small {
     1413  font-size: 12px;
     1414  margin-left: 12px;
     1415}
     1416
     1417.wr-report-page .wr-select--small {
     1418  min-width: 100px;
     1419  max-width: 140px;
     1420  padding: 2px 6px;
     1421  font-size: 13px;
     1422}
     1423
     1424.wr-report-page .wr-export-csv-link {
     1425  margin-left: 8px;
     1426}
     1427
     1428.wr-report-page .wr-report-card__footer .wr-export-csv-link {
     1429  margin-right: 0;
     1430}
     1431
     1432.wr-report-page .wr-kpi-card--nolink {
     1433  cursor: default;
     1434  text-decoration: none;
     1435}
     1436
     1437.wr-report-page .wr-kpi-card--nolink:hover {
     1438  text-decoration: none;
     1439  transform: none;
     1440  box-shadow: 0 1px 4px rgba(0,0,0,0.04);
     1441}
     1442
     1443.wr-report-page .wr-report-card__loading {
     1444  padding: 24px;
     1445  text-align: center;
     1446  color: var(--wr-text-secondary);
     1447  font-size: 14px;
     1448}
     1449
     1450.wr-report-page .wr-report-card .widefat a {
     1451  color: var(--wr-accent);
     1452  text-decoration: none;
     1453}
     1454
     1455.wr-report-page .wr-report-card .widefat a:hover {
     1456  text-decoration: underline;
     1457}
     1458
     1459/* ----- Report filter bar: modern style for all pages ----- */
     1460.wr-report-page .wr-report-filter-bar {
     1461  padding: 0;
     1462  margin: 0;
     1463  display: flex;
     1464  align-items: center;
     1465  justify-content: space-between;
     1466  gap: 16px;
     1467}
     1468
     1469.wr-report-page .wr-report-filter-bar form {
     1470  display: flex;
     1471  flex-wrap: wrap;
     1472  align-items: center;
     1473  gap: 12px 16px;
     1474  padding: 16px 20px;
     1475  margin: 0;
     1476  background: #f8f9fa;
     1477  border: none;
     1478  border-left: 3px solid var(--wr-accent);
     1479  box-shadow: none;
     1480  width: 100%;
     1481  max-width: 100%;
     1482  box-sizing: border-box;
     1483  flex: 1;
     1484}
     1485
     1486.wr-report-page .wr-report-filter-bar .WR_filterBox {
     1487  padding: 0;
     1488  margin: 0;
     1489  width: 100%;
     1490  background: transparent;
     1491  border: none;
     1492  box-shadow: none;
     1493}
     1494
     1495.wr-report-page .wr-report-filter-bar .form-field {
     1496  width: auto;
     1497  float: none;
     1498  margin: 0;
     1499  display: flex;
     1500  align-items: center;
     1501  gap: 6px;
     1502}
     1503
     1504.wr-report-page .wr-report-filter-bar .form-field label {
     1505  margin: 0;
     1506  padding: 0;
     1507  font-size: 13px;
     1508  font-weight: 500;
     1509  color: var(--wr-text);
     1510  white-space: nowrap;
     1511}
     1512
     1513/* Filter labels above inputs */
     1514.wr-report-page .wr-report-filter-bar form.wr-report-filter-form .form-field {
     1515  flex-direction: column;
     1516  align-items: flex-start;
     1517  gap: 4px;
     1518}
     1519
     1520/* Search + Reset actions on one horizontal row */
     1521.wr-report-page .wr-report-filter-bar form.wr-report-filter-form .wr-filter-actions {
     1522  flex-direction: row;
     1523  align-items: center;
     1524  margin-top: 22px; /* پایین‌تر تا هم‌تراز با inputها شود */
     1525}
     1526
     1527/* Orders filter: same input/select/button style as Overview (.wr-report-filter-form) */
     1528.wr-report-page .wr-report-filter-bar form input[type="text"],
     1529.wr-report-page .wr-report-filter-bar form input[type="number"] {
     1530  background: #fff;
     1531  border: 1px solid var(--wr-border);
     1532  color: var(--wr-text);
     1533  padding: 8px 12px;
     1534  border-radius: 6px;
     1535  font-size: 13px;
     1536  min-width: 120px;
     1537  height: 38px;
     1538  line-height: 1.4;
     1539  box-sizing: border-box;
     1540}
     1541
     1542.wr-report-page .wr-report-filter-bar form input:focus {
     1543  border-color: var(--wr-accent);
     1544  outline: none;
     1545  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
     1546}
     1547
     1548.wr-report-page .wr-report-filter-bar form select {
     1549  background: #fff;
     1550  border: 1px solid var(--wr-border);
     1551  color: var(--wr-text);
     1552  padding: 8px 12px;
     1553  border-radius: 6px;
     1554  font-size: 13px;
     1555  min-width: 200px;
     1556  height: 38px;
     1557  line-height: 1.4;
     1558}
     1559
     1560.wr-report-page .wr-report-filter-bar form select:focus {
     1561  border-color: var(--wr-accent);
     1562  outline: none;
     1563  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
     1564}
     1565
     1566.wr-report-page .wr-report-filter-bar form .select2-container {
     1567  min-width: 220px;
     1568  height: 38px !important;
     1569}
     1570
     1571.wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--multiple {
     1572  height: 38px !important;
     1573  min-height: 38px !important;
     1574  max-height: 38px !important;
     1575  padding: 0 8px;
     1576  border: 1px solid var(--wr-border);
     1577  border-radius: 6px;
     1578  background: #fff;
     1579}
     1580
     1581.wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single {
     1582  height: 38px !important;
     1583  min-height: 38px !important;
     1584  padding: 0 8px;
     1585  border: 1px solid var(--wr-border);
     1586  border-radius: 6px;
     1587  background: #fff;
     1588  display: flex !important;
     1589  align-items: center;
     1590}
     1591
     1592.wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single .select2-selection__rendered {
     1593  padding: 0;
     1594  line-height: 36px;
     1595  color: var(--wr-text, #1e1e1e);
     1596  font-size: 13px;
     1597}
     1598
     1599.wr-report-page .wr-report-filter-bar form .select2-container .select2-selection--single .select2-selection__arrow {
     1600  height: 36px;
     1601  top: 0;
     1602}
     1603
     1604.wr-report-page .wr-report-filter-bar form .select2-container.select2-container--focus .select2-selection--single,
     1605.wr-report-page .wr-report-filter-bar form .select2-container.select2-container--open .select2-selection--single {
     1606  border-color: var(--wr-accent, #1a73e8);
     1607  outline: none;
     1608  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.2);
     1609}
     1610
     1611.wr-report-page .wr-report-filter-bar form .button {
     1612  height: 38px !important;
     1613  min-height: 38px !important;
     1614  padding: 0 18px !important;
     1615  line-height: 36px !important;
     1616  font-size: 13px !important;
     1617  font-weight: 500;
     1618  border-radius: 6px;
     1619  cursor: pointer;
     1620  box-sizing: border-box;
     1621}
     1622
     1623.wr-report-page .wr-report-filter-bar form .button-primary {
     1624  border-color: var(--wr-accent);
     1625  background: var(--wr-accent);
     1626  margin-left: 0;
     1627}
     1628
     1629.wr-report-page .wr-report-filter-bar form .button-primary:hover {
     1630  background: #1557b0;
     1631  border-color: #1557b0;
     1632  box-shadow: 0 1px 3px rgba(26, 115, 232, 0.35);
     1633}
     1634
     1635.wr-report-page .wr-report-filter-bar form .button-primary:focus {
     1636  border-color: var(--wr-accent);
     1637  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.35);
     1638}
     1639
     1640/* Modern filter form layout for all report pages */
     1641.wr-report-filter-form--modern .WR_filterBox {
     1642  display: flex;
     1643  flex-wrap: wrap;
     1644  align-items: flex-end;
     1645  gap: 12px;
     1646}
     1647
     1648.wr-report-filter-form--modern .form-field {
     1649  display: flex;
     1650  flex-direction: column;
     1651  align-items: flex-start;
     1652  gap: 4px;
     1653}
     1654
     1655.wr-report-filter-form--modern .form-field label {
     1656  font-size: 11px;
     1657  font-weight: 600;
     1658  text-transform: uppercase;
     1659  letter-spacing: 0.04em;
     1660  color: var(--wr-text-secondary);
     1661  white-space: nowrap;
     1662}
     1663
     1664.wr-report-filter-form--modern .wr-filter-actions {
     1665  flex-direction: row !important;
     1666  align-items: flex-end !important;
     1667  gap: 8px !important;
     1668  margin-top: 0;
     1669}
     1670
     1671.wr-report-filter-form--modern .clear {
     1672  display: none;
     1673}
     1674
     1675/* Keep Summary trigger aligned on the right side of Orders filter bar */
     1676.wr-report-page .wr-report-filter-bar--orders .wr-orders-summary-trigger {
     1677  flex-shrink: 0;
     1678}
     1679
     1680/* Chart card (all reports) */
     1681.wr-report-page .wr-report-card .wr-report-card__body--chart {
     1682  position: relative;
     1683  padding: 16px 20px 12px;
     1684  height: 320px;
     1685}
     1686.wr-report-page .wr-report-card .wr-report-card__body--chart canvas {
     1687  max-width: 100%;
     1688}
     1689
     1690/* ── Generic report table card ── */
     1691.wr-report-page .wr-report-card .wr-report-card__body--table {
     1692  padding: 0;
     1693  overflow-x: auto;
     1694  border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius);
     1695}
     1696
     1697.wr-report-page .wr-report-card .wp-list-table.widefat {
     1698  border: none;
     1699  box-shadow: none;
     1700  border-collapse: separate;
     1701  border-spacing: 0;
     1702  width: max-content;
     1703  min-width: 100%;
     1704  table-layout: auto;
     1705  font-size: 13px;
     1706}
     1707
     1708.wr-report-page .wr-report-card .wp-list-table.fixed {
     1709  table-layout: auto;
     1710}
     1711
     1712.wr-report-page .wr-report-card .wp-list-table.widefat thead th {
     1713  font-size: 11px;
     1714  font-weight: 600;
     1715  text-transform: uppercase;
     1716  letter-spacing: 0.06em;
     1717  color: var(--wr-text-secondary);
     1718  padding: 14px 16px;
     1719  border: none;
     1720  border-bottom: 2px solid var(--wr-border);
     1721  background: #f8f9fa;
     1722  white-space: nowrap;
     1723}
     1724
     1725.wr-report-page .wr-report-card .wp-list-table.widefat thead th a {
     1726  color: var(--wr-accent);
     1727  text-decoration: none;
     1728  font-weight: 600;
     1729}
     1730
     1731.wr-report-page .wr-report-card .wp-list-table.widefat thead th a:hover {
     1732  text-decoration: underline;
     1733}
     1734
     1735.wr-report-page .wr-report-card .wp-list-table.widefat tfoot {
     1736  display: none;
     1737}
     1738
     1739.wr-report-page .wr-report-card .wp-list-table.widefat tbody td {
     1740  padding: 14px 16px;
     1741  border: none;
     1742  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
     1743  color: var(--wr-text);
     1744  vertical-align: middle;
     1745  white-space: nowrap;
     1746}
     1747
     1748.wr-report-page .wr-report-card .wp-list-table.widefat tbody tr {
     1749  transition: background 0.15s ease;
     1750}
     1751
     1752.wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:nth-of-type(odd) {
     1753  background: rgba(0, 0, 0, 0.02);
     1754}
     1755
     1756.wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:hover {
     1757  background: rgba(26, 115, 232, 0.04);
     1758}
     1759
     1760.wr-report-page .wr-report-card .wp-list-table.widefat tbody tr:last-child td {
     1761  border-bottom: none;
     1762}
     1763
     1764.wr-report-page .wr-report-card .wp-list-table.widefat tbody td a {
     1765  color: var(--wr-accent);
     1766  text-decoration: none;
     1767  font-weight: 500;
     1768}
     1769
     1770.wr-report-page .wr-report-card .wp-list-table.widefat tbody td a:hover {
     1771  text-decoration: underline;
     1772}
     1773
     1774.wr-report-page .wr-report-card .wp-list-table.widefat .order-status {
     1775  display: inline-block;
     1776  padding: 4px 10px;
     1777  font-size: 12px;
     1778  font-weight: 600;
     1779  border-radius: 20px;
     1780  border: none;
     1781  line-height: 1.3;
     1782}
     1783
     1784.wr-report-page .wr-report-card .wp-list-table.widefat .order-status span {
     1785  border: none;
     1786  padding: 0;
     1787  background: none;
     1788}
     1789
     1790/* Modern buttons inside report tables */
     1791.wr-report-page .wr-report-card .wp-list-table.widefat td .button,
     1792.wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary {
     1793  display: inline-flex;
     1794  align-items: center;
     1795  gap: 4px;
     1796  padding: 5px 12px;
     1797  font-size: 12px;
     1798  font-weight: 500;
     1799  line-height: 1.4;
     1800  border: 1px solid var(--wr-accent);
     1801  border-radius: 6px;
     1802  background: rgba(26, 115, 232, 0.06);
     1803  color: var(--wr-accent);
     1804  text-decoration: none;
     1805  cursor: pointer;
     1806  box-shadow: none;
     1807  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
     1808  white-space: nowrap;
     1809}
     1810.wr-report-page .wr-report-card .wp-list-table.widefat td .button:hover,
     1811.wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary:hover {
     1812  background: var(--wr-accent);
     1813  color: #fff;
     1814  box-shadow: 0 2px 6px rgba(26, 115, 232, 0.25);
     1815  text-decoration: none;
     1816}
     1817.wr-report-page .wr-report-card .wp-list-table.widefat td .button:focus,
     1818.wr-report-page .wr-report-card .wp-list-table.widefat td .button.button-primary:focus {
     1819  outline: none;
     1820  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.3);
     1821}
     1822
     1823/* Stock action buttons (Edit/View) */
     1824.wr-report-page .wr-report-card .wp-list-table.widefat td .button.tips {
     1825  padding: 4px 10px;
     1826  font-size: 12px;
     1827  margin-right: 4px;
     1828}
     1829
     1830/* ── Products Popover ── */
     1831.wr-products-popover-wrap {
     1832  display: inline-block;
     1833}
     1834
     1835.wr-products-trigger {
     1836  display: inline-flex;
     1837  align-items: center;
     1838  gap: 4px;
     1839  padding: 4px 10px;
     1840  font-size: 12px;
     1841  font-weight: 500;
     1842  color: var(--wr-accent);
     1843  background: rgba(26, 115, 232, 0.06);
     1844  border: 1px solid rgba(26, 115, 232, 0.18);
     1845  border-radius: 20px;
     1846  cursor: pointer;
     1847  transition: all 0.15s ease;
     1848  white-space: nowrap;
     1849  line-height: 1.5;
     1850}
     1851
     1852.wr-products-trigger:hover {
     1853  background: rgba(26, 115, 232, 0.12);
     1854  border-color: rgba(26, 115, 232, 0.35);
     1855}
     1856
     1857.wr-products-trigger[aria-expanded="true"] {
     1858  background: var(--wr-accent);
     1859  color: #fff;
     1860  border-color: var(--wr-accent);
     1861}
     1862
     1863.wr-products-trigger__count {
     1864  font-weight: 700;
     1865}
     1866
     1867.wr-products-trigger__chevron {
     1868  width: 14px;
     1869  height: 14px;
     1870  transition: transform 0.2s ease;
     1871  flex-shrink: 0;
     1872}
     1873
     1874.wr-products-trigger[aria-expanded="true"] .wr-products-trigger__chevron {
     1875  transform: rotate(180deg);
     1876}
     1877
     1878/* Popover card */
     1879.wr-products-popover {
     1880  display: none;
     1881  position: fixed;
     1882  z-index: 100000;
     1883  min-width: 260px;
     1884  max-width: 340px;
     1885  background: #fff;
     1886  border: 1px solid var(--wr-border);
     1887  border-radius: 12px;
     1888  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 6px rgba(0, 0, 0, 0.06);
     1889  animation: wr-popover-in 0.15s ease-out;
     1890}
     1891
     1892.wr-products-popover[aria-hidden="false"] {
     1893  display: block;
     1894}
     1895
     1896@keyframes wr-popover-in {
     1897  from { opacity: 0; transform: translateY(-4px); }
     1898  to   { opacity: 1; transform: translateY(0); }
     1899}
     1900
     1901.wr-products-popover--above {
     1902  animation: wr-popover-in-above 0.15s ease-out;
     1903}
     1904@keyframes wr-popover-in-above {
     1905  from { opacity: 0; transform: translateY(4px); }
     1906  to   { opacity: 1; transform: translateY(0); }
     1907}
     1908
     1909/* Arrow */
     1910.wr-products-popover::before {
     1911  content: '';
     1912  position: absolute;
     1913  top: -6px;
     1914  left: var(--wr-popover-arrow, 50%);
     1915  transform: translateX(-50%) rotate(45deg);
     1916  width: 10px;
     1917  height: 10px;
     1918  background: #fff;
     1919  border-top: 1px solid var(--wr-border);
     1920  border-left: 1px solid var(--wr-border);
     1921}
     1922.wr-products-popover--above::before {
     1923  top: auto;
     1924  bottom: -6px;
     1925  border-top: none;
     1926  border-left: none;
     1927  border-bottom: 1px solid var(--wr-border);
     1928  border-right: 1px solid var(--wr-border);
     1929}
     1930
     1931.wr-products-popover__header {
     1932  display: flex;
     1933  align-items: center;
     1934  justify-content: space-between;
     1935  padding: 10px 14px;
     1936  border-bottom: 1px solid var(--wr-border);
     1937  font-size: 12px;
     1938  font-weight: 600;
     1939  color: var(--wr-text-secondary);
     1940}
     1941
     1942.wr-products-popover__close {
     1943  display: flex;
     1944  align-items: center;
     1945  justify-content: center;
     1946  width: 22px;
     1947  height: 22px;
     1948  border: none;
     1949  background: transparent;
     1950  color: var(--wr-text-secondary);
     1951  font-size: 16px;
     1952  border-radius: 6px;
     1953  cursor: pointer;
     1954  transition: background 0.12s ease;
     1955}
     1956
     1957.wr-products-popover__close:hover {
     1958  background: rgba(0, 0, 0, 0.06);
     1959  color: var(--wr-text);
     1960}
     1961
     1962.wr-products-popover__list {
     1963  list-style: none;
     1964  margin: 0;
     1965  padding: 6px 0;
     1966  max-height: 220px;
     1967  overflow-y: auto;
     1968}
     1969
     1970.wr-products-popover__item {
     1971  display: flex;
     1972  align-items: center;
     1973  justify-content: space-between;
     1974  gap: 12px;
     1975  padding: 8px 14px;
     1976  transition: background 0.1s ease;
     1977}
     1978
     1979.wr-products-popover__item:hover {
     1980  background: rgba(0, 0, 0, 0.02);
     1981}
     1982
     1983.wr-products-popover__name {
     1984  font-size: 13px;
     1985  font-weight: 500;
     1986  color: var(--wr-text);
     1987  white-space: nowrap;
     1988  overflow: hidden;
     1989  text-overflow: ellipsis;
     1990}
     1991
     1992.wr-products-popover__meta {
     1993  font-size: 12px;
     1994  color: var(--wr-text-secondary);
     1995  white-space: nowrap;
     1996  flex-shrink: 0;
     1997}
     1998
     1999/* ── Tablenav: generic for all report pages ── */
     2000.wr-report-page .wr-report-card .tablenav {
     2001  display: flex;
     2002  align-items: center;
     2003  flex-wrap: wrap;
     2004  gap: 10px;
     2005  padding: 8px 16px;
     2006  margin: 0;
     2007  background: transparent;
     2008  border: none;
     2009}
     2010
     2011.wr-report-page .wr-report-card .tablenav.top {
     2012  display: none;
     2013}
     2014
     2015.wr-report-page .wr-report-card .tablenav.bottom {
     2016  justify-content: flex-end;
     2017  border-top: 1px solid var(--wr-border);
     2018  margin-top: 0;
     2019  padding: 10px 16px;
     2020  background: #ffffff;
     2021  border-radius: 0 0 var(--wr-card-radius) var(--wr-card-radius);
     2022}
     2023
     2024.wr-report-page .wr-report-card .tablenav .actions {
     2025  display: flex;
     2026  align-items: center;
     2027  gap: 6px;
     2028}
     2029
     2030.wr-report-page .wr-report-card .tablenav .bulkactions {
     2031  display: none;
     2032}
     2033
     2034.wr-report-page .wr-report-card .nw_export_button {
     2035  display: inline-flex;
     2036  align-items: center;
     2037  gap: 6px;
     2038  padding: 6px 12px;
     2039  font-size: 13px;
     2040  font-weight: 500;
     2041  border-radius: 8px;
     2042  border: 1px solid var(--wr-border);
     2043  background: #fff;
     2044  color: var(--wr-text);
     2045  text-decoration: none;
     2046  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
     2047}
     2048
     2049.wr-report-page .wr-report-card .nw_export_button:hover {
     2050  border-color: var(--wr-accent);
     2051  background: rgba(26, 115, 232, 0.06);
     2052  color: var(--wr-accent);
     2053}
     2054
     2055.wr-report-page .wr-report-card .nw_export_excel:hover {
     2056  background: #b7d8b7 !important;
     2057  color: #4c6f16 !important;
     2058  border-color: #9ac29a !important;
     2059}
     2060.wr-report-page .wr-report-card .nw_export_pdf:hover {
     2061  background: #f0d08a !important;
     2062  color: #7a5208 !important;
     2063  border-color: #d8b96d !important;
     2064}
     2065
     2066/* Orders summary side panel: show totals as stacked list, not table */
     2067#wr-orders-summary-panel .table.table-striped {
     2068  width: 100%;
     2069  border: none;
     2070  border-collapse: collapse;
     2071  margin: 0;
     2072  font-size: 13px;
     2073}
     2074
     2075#wr-orders-summary-panel .table.table-striped tbody tr {
     2076  display: flex;
     2077  justify-content: space-between;
     2078  align-items: baseline;
     2079  padding: 10px 0;
     2080  border: none;
     2081  border-bottom: 1px solid var(--wr-border);
     2082  background: transparent !important;
     2083}
     2084
     2085#wr-orders-summary-panel .table.table-striped tbody tr:last-child {
     2086  border-bottom: none;
     2087}
     2088
     2089#wr-orders-summary-panel .table.table-striped td {
     2090  padding: 0;
     2091  border: none;
     2092  background: transparent;
     2093}
     2094
     2095#wr-orders-summary-panel .table.table-striped td:first-child {
     2096  font-size: 12px;
     2097  font-weight: 500;
     2098  color: var(--wr-text-secondary);
     2099}
     2100
     2101#wr-orders-summary-panel .table.table-striped td:last-child {
     2102  font-size: 14px;
     2103  font-weight: 600;
     2104  color: var(--wr-text);
     2105  text-align: right;
     2106}
     2107
     2108/* ── Modern Pagination (all report pages) ── */
     2109.wr-report-page .wr-report-card .tablenav .tablenav-pages {
     2110  margin-left: auto;
     2111  display: flex;
     2112  align-items: center;
     2113  gap: 8px;
     2114}
     2115
     2116.wr-report-page .wr-report-card .tablenav-pages .displaying-num {
     2117  font-size: 13px;
     2118  font-weight: 500;
     2119  color: var(--wr-text-secondary);
     2120  margin-right: 4px;
     2121}
     2122
     2123.wr-report-page .wr-report-card .tablenav-pages .pagination-links {
     2124  display: flex;
     2125  align-items: center;
     2126  gap: 4px;
     2127}
     2128
     2129.wr-report-page .wr-report-card .tablenav-pages .pagination-links .tablenav-paging-text {
     2130  font-size: 13px;
     2131  color: var(--wr-text-secondary);
     2132}
     2133
     2134.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button,
     2135.wr-report-page .wr-report-card .tablenav-pages .pagination-links a.button {
     2136  display: inline-flex;
     2137  align-items: center;
     2138  justify-content: center;
     2139  min-width: 32px;
     2140  height: 32px;
     2141  padding: 0 8px;
     2142  font-size: 13px;
     2143  font-weight: 500;
     2144  color: var(--wr-text);
     2145  background: #ffffff;
     2146  border: 1px solid var(--wr-border);
     2147  border-radius: 8px;
     2148  cursor: pointer;
     2149  text-decoration: none;
     2150  transition: all 0.15s ease;
     2151  box-shadow: none;
     2152}
     2153
     2154.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button:hover,
     2155.wr-report-page .wr-report-card .tablenav-pages .pagination-links a.button:hover {
     2156  background: var(--wr-accent);
     2157  color: #ffffff;
     2158  border-color: var(--wr-accent);
     2159}
     2160
     2161.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button.disabled,
     2162.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button[disabled] {
     2163  opacity: 0.35;
     2164  cursor: not-allowed;
     2165  background: #f5f5f5;
     2166  color: var(--wr-text-secondary);
     2167  border-color: var(--wr-border);
     2168}
     2169
     2170.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button.disabled:hover,
     2171.wr-report-page .wr-report-card .tablenav-pages .pagination-links .button[disabled]:hover {
     2172  background: #f5f5f5;
     2173  color: var(--wr-text-secondary);
     2174  border-color: var(--wr-border);
     2175}
     2176
     2177.wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input {
     2178  display: inline-flex;
     2179  align-items: center;
     2180  gap: 6px;
     2181  font-size: 13px;
     2182  color: var(--wr-text-secondary);
     2183}
     2184
     2185.wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input .current-page {
     2186  width: 48px;
     2187  height: 32px;
     2188  padding: 0 6px;
     2189  font-size: 13px;
     2190  font-weight: 500;
     2191  text-align: center;
     2192  color: var(--wr-text);
     2193  background: #ffffff;
     2194  border: 1px solid var(--wr-border);
     2195  border-radius: 8px;
     2196  outline: none;
     2197  transition: border-color 0.15s ease, box-shadow 0.15s ease;
     2198}
     2199
     2200.wr-report-page .wr-report-card .tablenav-pages .pagination-links .paging-input .current-page:focus {
     2201  border-color: var(--wr-accent);
     2202  box-shadow: 0 0 0 2px rgba(26, 115, 232, 0.15);
     2203}
     2204
     2205.wr-report-page .wr-report-card .tablenav-pages .pagination-links .total-pages {
     2206  font-weight: 600;
     2207  color: var(--wr-text);
     2208}
     2209
     2210/* Orders summary card: small table */
     2211.wr-report-page .wr-report-card .table.table-striped {
     2212  width: 100%;
     2213  border: none;
     2214  border-collapse: collapse;
     2215  margin: 0;
     2216  font-size: 13px;
     2217}
     2218
     2219.wr-report-page .wr-report-card .table.table-striped td {
     2220  padding: 10px 12px;
     2221  border: none;
     2222  border-bottom: 1px solid var(--wr-border);
     2223}
     2224
     2225.wr-report-page .wr-report-card .table.table-striped tbody tr:nth-of-type(odd) {
     2226  background: rgba(0, 0, 0, 0.02);
     2227}
     2228
     2229.wr-report-page .wr-report-card .table.table-striped tbody tr:last-child td {
     2230  border-bottom: none;
     2231}
     2232
     2233.wr-report-page .wr-report-cards--orders {
     2234  display: grid;
     2235  grid-template-columns: 1fr;
     2236  gap: 24px;
     2237}
     2238
     2239.wr-report-page .wr-report-cards__two-col--orders {
     2240  grid-template-columns: 1fr 1fr;
     2241  gap: 24px;
     2242}
     2243
     2244@media screen and (max-width: 782px) {
     2245  .wr-report-filter-form--modern .WR_filterBox {
     2246    gap: 8px;
     2247  }
     2248  .wr-report-filter-form--modern .form-field {
     2249    width: 100%;
     2250  }
     2251  .wr-report-page .wr-report-filter-bar--orders .wr-orders-summary-trigger {
     2252    align-self: flex-end;
     2253  }
     2254  .wr-report-page .wr-report-cards__two-col--orders {
     2255    grid-template-columns: 1fr;
     2256  }
     2257}
     2258
     2259@media screen and (max-width: 960px) {
     2260  .wr-report-topbar {
     2261    padding: 12px 16px;
     2262  }
     2263  .wr-report-topbar__center {
     2264    order: 3;
     2265    width: 100%;
     2266  }
     2267  .wr-report-page__inner {
     2268    padding-left: 16px;
     2269    padding-right: 16px;
     2270  }
     2271  .wr-report-filter-bar {
     2272    padding-left: 16px;
     2273    padding-right: 16px;
     2274  }
     2275  .wr-report-kpis {
     2276    grid-template-columns: repeat(2, 1fr);
     2277    gap: 12px;
     2278    padding: 16px;
     2279  }
     2280  .wr-report-filter-form {
     2281    width: 100%;
     2282  }
     2283  .wr-report-cards {
     2284    grid-template-columns: 1fr;
     2285  }
     2286  .wr-report-cards__top-row {
     2287    grid-template-columns: 1fr;
     2288  }
     2289  .wr-report-cards__two-col {
     2290    grid-template-columns: 1fr;
     2291  }
     2292}
     2293
     2294@media screen and (max-width: 480px) {
     2295  .wr-report-kpis {
     2296    grid-template-columns: 1fr;
     2297  }
     2298}
  • wc-reports-lite/trunk/assets/js/admin.js

    r2413794 r3493462  
    11
    22(function($) {
    3 "use strict"; 
     3"use strict";
    44$(document).ready(function () {
    5     //Display products btn
    6     $('.wcrl_customer_products a').on('click',function () {
    7         $(this).next().toggle();
     5    // Products popover (fixed positioning to escape overflow containers)
     6    function wrCloseAllPopovers($except) {
     7        $('.wr-products-trigger[aria-expanded="true"]').not($except || $())
     8            .attr('aria-expanded', 'false')
     9            .closest('.wr-products-popover-wrap')
     10            .find('.wr-products-popover').attr('aria-hidden', 'true').removeClass('wr-products-popover--above');
     11    }
     12
     13    function wrPositionPopover($btn, $popover) {
     14        var rect = $btn[0].getBoundingClientRect();
     15        var popW = $popover.outerWidth();
     16        var popH = $popover.outerHeight();
     17        var vpW  = window.innerWidth;
     18        var vpH  = window.innerHeight;
     19        var gap  = 8;
     20
     21        // Horizontal: center on the trigger, clamp to viewport
     22        var left = rect.left + rect.width / 2 - popW / 2;
     23        left = Math.max(8, Math.min(left, vpW - popW - 8));
     24
     25        // Arrow position relative to popover
     26        var arrowLeft = (rect.left + rect.width / 2 - left);
     27        arrowLeft = Math.max(16, Math.min(arrowLeft, popW - 16));
     28
     29        // Vertical: prefer below, flip above if not enough room
     30        var spaceBelow = vpH - rect.bottom - gap;
     31        var openAbove  = spaceBelow < popH && rect.top - gap > popH;
     32
     33        var top;
     34        if (openAbove) {
     35            top = rect.top - popH - gap;
     36            $popover.addClass('wr-products-popover--above');
     37        } else {
     38            top = rect.bottom + gap;
     39            $popover.removeClass('wr-products-popover--above');
     40        }
     41
     42        $popover.css({ top: top + 'px', left: left + 'px' });
     43        $popover[0].style.setProperty('--wr-popover-arrow', arrowLeft + 'px');
     44    }
     45
     46    $(document).on('click', '.wr-products-trigger', function (e) {
     47        e.stopPropagation();
     48        var $btn     = $(this);
     49        var $wrap    = $btn.closest('.wr-products-popover-wrap');
     50        var $popover = $wrap.find('.wr-products-popover');
     51        var isOpen   = $btn.attr('aria-expanded') === 'true';
     52
     53        wrCloseAllPopovers($btn);
     54
     55        if (!isOpen) {
     56            $btn.attr('aria-expanded', 'true');
     57            $popover.attr('aria-hidden', 'false');
     58            wrPositionPopover($btn, $popover);
     59        } else {
     60            $btn.attr('aria-expanded', 'false');
     61            $popover.attr('aria-hidden', 'true').removeClass('wr-products-popover--above');
     62        }
     63    });
     64
     65    $(document).on('click', '.wr-products-popover__close', function (e) {
     66        e.stopPropagation();
     67        var $wrap = $(this).closest('.wr-products-popover-wrap');
     68        $wrap.find('.wr-products-trigger').attr('aria-expanded', 'false');
     69        $wrap.find('.wr-products-popover').attr('aria-hidden', 'true').removeClass('wr-products-popover--above');
     70    });
     71
     72    $(document).on('click', function () {
     73        wrCloseAllPopovers();
     74    });
     75
     76    $(document).on('click', '.wr-products-popover', function (e) {
     77        e.stopPropagation();
     78    });
     79
     80    // Reposition open popover on scroll/resize
     81    $(window).on('scroll resize', function () {
     82        var $open = $('.wr-products-trigger[aria-expanded="true"]');
     83        if ($open.length) {
     84            var $popover = $open.closest('.wr-products-popover-wrap').find('.wr-products-popover');
     85            wrPositionPopover($open, $popover);
     86        }
     87    });
     88    $('.wr-report-card__body--table').on('scroll', function () {
     89        var $open = $(this).find('.wr-products-trigger[aria-expanded="true"]');
     90        if ($open.length) {
     91            var $popover = $open.closest('.wr-products-popover-wrap').find('.wr-products-popover');
     92            wrPositionPopover($open, $popover);
     93        }
     94    });
     95    //select2
     96    $(".wr-select2, .select2-filter").each(function() {
     97        var $el = $(this);
     98        $el.select2({
     99            placeholder: $el.data('placeholder') || '',
     100            allowClear: !!$el.attr('multiple')
     101        });
    8102    });
    9103
    10104    // settings page
    11     $('.wcrl-settings-container ul.tabs li').on('click',function(){
     105    $('.wr-settings-container ul.tabs li').on('click',function(){
    12106        var tab_id = $(this).attr('data-tab');
    13107        $('ul.tabs li').removeClass('current');
     
    18112    });
    19113
     114    // active email reporting
     115    if ($('#WR_active_email_reporting').is(':checked')) {
     116        $('.WR_email_form_settings').show();
     117    }
     118    $('#WR_active_email_reporting').on('change',function () {
     119        if ($('#WR_active_email_reporting').is(':checked')) {
     120            $('.WR_email_form_settings').show('200');
     121        }else{
     122            $('.WR_email_form_settings').hide('200');
     123        }
     124    });
     125
     126    //hidden screen-reader-text for export options(dataTable js)
     127    $(".wp-list-table .screen-reader-text").empty();
     128
     129    // Generic Summary panel handler for all report pages
     130    $(document).on('click', '.wr-summary-trigger', function() {
     131        var panelId = $(this).data('panel');
     132        var $panel = $('#' + panelId);
     133        if ($panel.length) {
     134            $panel.addClass('wr-insights-panel--open').attr('aria-hidden', 'false');
     135        }
     136    });
     137    $(document).on('click', '.wr-insights-panel__backdrop, .wr-insights-panel__close', function() {
     138        var $panel = $(this).closest('.wr-insights-panel');
     139        $panel.removeClass('wr-insights-panel--open').attr('aria-hidden', 'true');
     140    });
     141    $(document).on('click', '.wr-insights-panel__drawer', function(e) {
     142        e.stopPropagation();
     143    });
     144
     145    // Generic reset filters button for all report pages
     146    $(document).on('click', '.wr-report-reset-filters', function(e) {
     147        e.preventDefault();
     148        var page = $(this).data('page') || new URLSearchParams(window.location.search).get('page');
     149        if (page) {
     150            var url = new URL(window.location.href);
     151            url.search = '';
     152            url.searchParams.set('page', page);
     153            window.location = url.toString();
     154        }
     155    });
     156
    20157});
    21158})(jQuery);
  • wc-reports-lite/trunk/assets/js/persianDatepicker.js

    r2413794 r3493462  
    77 * Released under the MIT license.
    88 *
    9  * jalali Date Functions from NASA.gov
     9 * jalali Date Functions
    1010 *
    1111 * Date: Tue Jan 1 2013
     12 *
     13 * Last Update: Mon April 15 2019
     14 *
    1215 */
    13 
     16;
    1417(function ($) {
    1518    $.fn.persianDatepicker = function (options) {
    16         var 'wc-reports-lite' = 'persianDatepicker';
    17         var instance = this.data('wc-reports-lite');
     19        var pluginName = 'persianDatepicker';
     20        var instance = this.data(pluginName);
    1821        if (!instance) {
    1922            return this.each(function () {
    20                 return $(this).data('wc-reports-lite', new persianDatepicker(this, options));
     23                return $(this).data(pluginName, new persianDatepicker(this, options));
    2124            });
    2225        }
     
    5255                    y: 0,
    5356                },
    54                 onShow: function () {
    55                 },
    56                 onHide: function () {
    57                 },
    58                 onSelect: function () {
    59                 },
    60                 onRender: function () {
    61                 }
     57                onShow: function () { },
     58                onHide: function () { },
     59                onSelect: function () { },
     60                onRender: function () { }
    6261            };
    6362            var self = this;
     
    8786            }
    8887
    89             if (self.options.selectedDate == undefined) {
     88            if (self.options.selectedDate == undefined && !self.options.showGregorianDate) {
    9089                var patt1 = new RegExp('^([1-9][0-9][0-9][0-9])/([0]?[1-9]|[1][0-2])/([0]?[1-9]|[1-2][0-9]|[3][0-1])$');
    9190                if (el.is('input')) {
     
    138137            if (options.selectedBefore) {
    139138                if (self.options.selectedDate != undefined) {
    140                     jd = self.jDateFunctions.getJulianDayFromPersian(self.persianDate.parse(self.options.selectedDate));
    141                     self.showDate(el, self.persianDate.parse(self.options.selectedDate).toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(jd)), self.now().gDate, options.showGregorianDate);
     139                    //>jd = self.jDateFunctions.getJulianDayFromPersian(self.persianDate.parse(self.options.selectedDate));
     140                    self.showDate(el, self.persianDate.parse(self.options.selectedDate).toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(self.persianDate.parse(self.options.selectedDate)), self.now().gDate, options.showGregorianDate));
    142141                } else {
    143                     jd = self.jDateFunctions.getJulianDayFromPersian(self.now());
    144                     self.showDate(el, self.now().toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(jd)), self.now().gDate, options.showGregorianDate);
     142                    //>jd = self.jDateFunctions.getJulianDayFromPersian(self.now());
     143                    self.showDate(el, self.now().toString("YYYY/MM/DD/" + self.jDateFunctions.getWeekday(self.now())), self.now().gDate, options.showGregorianDate);
    145144                }
    146145            }
     
    168167            var onResize = function () {
    169168                var elPos = el.offset();
    170                 self.calendar.css(
    171                     {
    172                         top: (elPos.top + el.outerHeight() + options.calendarPosition.y) + 'px',
    173                         left: (elPos.left + options.calendarPosition.x) + 'px'
    174                     });
     169                self.calendar.css({
     170                    top: (elPos.top + el.outerHeight() + options.calendarPosition.y) + 'px',
     171                    left: (elPos.left + options.calendarPosition.x) + 'px'
     172                });
    175173            };
    176174            self.onresize = onResize;
     
    179177            self.render();
    180178            onResize();
    181         }
    182         ;
     179        };
    183180
    184181        // persianDatepicker methods
     
    243240                        return false;
    244241                    })
    245                     .on('click',function (e) {
     242                    .click(function (e) {
    246243                        e.stopPropagation();
    247                         _yearSelect.css({ display: 'none' });
    248                         _monthSelect.css({ display: 'inline-block' });
     244                        _yearSelect.css({
     245                            display: 'none'
     246                        });
     247                        _monthSelect.css({
     248                            display: 'inline-block'
     249                        });
    249250                    });
    250251                var _yearText = $('<span/>')
     
    253254                        return false;
    254255                    })
    255                     .on('click',function (e) {
     256                    .click(function (e) {
    256257                        e.stopPropagation();
    257                         _monthSelect.css({ display: 'none' });
    258                         _yearSelect.css({ display: 'inline-block' });
     258                        _monthSelect.css({
     259                            display: 'none'
     260                        });
     261                        _yearSelect.css({
     262                            display: 'inline-block'
     263                        });
    259264                        _yearSelect.scrollTop(70);
    260265                    });
     
    308313                        o.addClass('selected');
    309314                    }
    310                     o.data('month', { month: m, monthNum: i });
     315                    o.data('month', {
     316                        month: m,
     317                        monthNum: i
     318                    });
    311319                    if (!o.hasClass('disableMonth')) {
    312320                        o.bind("click", function () {
     
    382390                jd = self.persianDate;
    383391                jd.date = 1;
    384                 _start = self.jDateFunctions.getWeekday(self.jDateFunctions.getJulianDayFromPersian(jd));
    385                 _end = self.jDateFunctions.getLastDayOfPersianMonth(self.persianDate);
     392                _start = self.jDateFunctions.getWeekday(self.persianDate);
     393                _end = self.jDateFunctions.getLastDayOfMonth(self.persianDate);
    386394                for (var row = 0, cellIndex = 0; row < 5 + 1; row++) {
    387395                    _row = $('<div />');
     
    477485                this.options.onSelect();
    478486            },
    479             getDate: function (jd, d) {
    480                 jd.date = d;
    481                 jd.day = this.jDateFunctions.getWeekday(this.jDateFunctions.getJulianDayFromPersian(jd))
    482                 return jd;
     487            getDate: function (pd, d) {
     488                pd.date = d;
     489                pd.day = this.jDateFunctions.getWeekday(pd)
     490                return pd;
    483491            },
    484492            now: function () {
    485                 return this.jDateFunctions.getPCalendarDate(this.jDateFunctions.getJulianDay(new Date()));
     493                return this.jDateFunctions.gregorian_to_jalali(new Date());
    486494            },
    487495        };
     
    515523                    .replace("mm", this.getMinutes() == 0 ? new Date().getMinutes() : this.getMinutes())
    516524                    .replace("ss", this.getSeconds() == 0 ? new Date().getSeconds() : this.getSeconds())
     525                    .replace("0h", this.getHours() > 9 ? this.getHours() : "0" + this.getHours())
     526                    .replace("0m", this.getMinutes() > 9 ? this.getMinutes() : "0" + this.getMinutes())
     527                    .replace("0s", this.getSeconds() > 9 ? this.getSeconds() : "0" + this.getSeconds())
    517528                    .replace("ms", this.getMilliseconds() == 0 ? new Date().getMilliseconds() : this.getMilliseconds())
    518529                    .replace("tm", (this.getHours() >= 12 && this.getMinutes() > 0) ? "PM" : "AM")
     
    527538        };
    528539    })();
    529 })(jQuery);// end of persianDatepicker plugin
     540})(jQuery); // end of persianDatepicker plugin
    530541
    531542// persianDate object
     
    540551        self.day = 1;
    541552        self.gDate = new Date();
    542     }
    543     ;
     553    };
    544554    persianDate.prototype = {
    545555        now: function () {
    546556            var jdf = new jDateFunctions();
    547             return jdf.getPCalendarDate(jdf.getJulianDay(new Date()));
     557            return jdf.gregorian_to_jalali(new Date());
    548558        },
    549559        addDay: function (d) {
     
    555565                r.year = this.year;
    556566                r = r.addMonth(-1);
    557                 var lastDayOfMonth = d > 0 ? jdf.getLastDayOfPersianMonth(this) : jdf.getLastDayOfPersianMonth(r);
     567                var lastDayOfMonth = d > 0 ? jdf.getLastDayOfMonth(this) : jdf.getLastDayOfMonth(r);
    558568                d > 0 ? this.date += 1 : this.date -= 1;
    559569                if (d > 0) {
     
    611621            var r = new persianDate();
    612622            jdf = new jDateFunctions();
    613             r.year = parseInt(y), r.month = parseInt(m), r.date = parseInt(d)
    614                 , r.day = jdf.getWeekday(jdf.getJulianDayFromPersian(r)), r.gDate = jdf.getGCalendarDate(jdf.getJulianDayFromPersian(r), "jgmonth");
     623            r.year = parseInt(y), r.month = parseInt(m), r.date = parseInt(d), r.day = jdf.getWeekday(r), r.gDate = jdf.jalali_to_gregorian(r);
    615624            return r;
    616625        },
     
    628637                    .replace("mm", this.gDate.getMinutes())
    629638                    .replace("ss", this.gDate.getSeconds())
     639                    .replace("0h", this.gDate.getHours() > 9 ? this.gDate.getHours() : "0" + this.gDate.getHours())
     640                    .replace("0m", this.gDate.getMinutes() > 9 ? this.gDate.getMinutes() : "0" + this.gDate.getMinutes())
     641                    .replace("0s", this.gDate.getSeconds() > 9 ? this.gDate.getSeconds() : "0" + this.gDate.getSeconds())
    630642                    .replace("tm", (this.gDate.getHours() >= 12 && this.gDate.getMinutes() > 0) ? "ب.ظ" : "ق.ظ")
    631643                    .replace("ms", this.gDate.getMilliseconds())
     
    641653//  jalali Date Functions from NASA.gov
    642654var jDateFunctions = (function () {
    643     function jDateFunctions() {
    644     }
    645     ;
     655    function jDateFunctions() { };
    646656
    647657    jDateFunctions.prototype = {
     
    654664            return res;
    655665        },
     666
     667        gregorian_to_jalali: function (dt) {
     668            gy = dt.getFullYear();
     669            gm = dt.getMonth() + 1;
     670            gd = dt.getDate();
     671            g_d_m = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
     672            if (gy > 1600) {
     673                jy = 979;
     674                gy -= 1600;
     675            } else {
     676                jy = 0;
     677                gy -= 621;
     678            }
     679            gy2 = (gm > 2) ? (gy + 1) : gy;
     680            days = (365 * gy) + (parseInt((gy2 + 3) / 4)) - (parseInt((gy2 + 99) / 100)) + (parseInt((gy2 + 399) / 400)) - 80 + gd + g_d_m[gm - 1];
     681            jy += 33 * (parseInt(days / 12053));
     682            days %= 12053;
     683            jy += 4 * (parseInt(days / 1461));
     684            days %= 1461;
     685            if (days > 365) {
     686                jy += parseInt((days - 1) / 365);
     687                days = (days - 1) % 365;
     688            }
     689            jm = (days < 186) ? 1 + parseInt(days / 31) : 7 + parseInt((days - 186) / 30);
     690            jd = 1 + ((days < 186) ? (days % 31) : ((days - 186) % 30));
     691            dt = new Date();
     692            pd = new persianDate();
     693            pd.year = jy;
     694            pd.month = jm;
     695            pd.date = jd;
     696            pd.gDate = dt;
     697            return pd;
     698        },
     699
     700        jalali_to_gregorian: function (pd) {
     701            jy = pd.year;
     702            jm = pd.month;
     703            jd = pd.date;
     704            if (jy > 979) {
     705                gy = 1600;
     706                jy -= 979;
     707            } else {
     708                gy = 621;
     709            }
     710            days = (365 * jy) + ((parseInt(jy / 33)) * 8) + (parseInt(((jy % 33) + 3) / 4)) + 78 + jd + ((jm < 7) ? (jm - 1) * 31 : ((jm - 7) * 30) + 186);
     711            gy += 400 * (parseInt(days / 146097));
     712            days %= 146097;
     713            if (days > 36524) {
     714                gy += 100 * (parseInt(--days / 36524));
     715                days %= 36524;
     716                if (days >= 365) days++;
     717            }
     718            gy += 4 * (parseInt(days / 1461));
     719            days %= 1461;
     720            if (days > 365) {
     721                gy += parseInt((days - 1) / 365);
     722                days = (days - 1) % 365;
     723            }
     724            gd = days + 1;
     725            sal_a = [0, 31, ((gy % 4 == 0 && gy % 100 != 0) || (gy % 400 == 0)) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
     726            for (gm = 0; gm < 13; gm++) {
     727                v = sal_a[gm];
     728                if (gd <= v) break;
     729                gd -= v;
     730            }
     731            dt = new Date();
     732            return new Date(gy, gm - 1, gd, dt.getHours(), dt.getMinutes(), dt.getSeconds(), dt.getMilliseconds());
     733        },
    656734        getGDate: function (pd) {
    657             return this.getGCalendarDate(this.getJulianDayFromPersian(pd), "gmonth");
    658         },
    659         getPCalendarDate: function (jd) {
    660             var y = 0;
    661             var m = 0;
    662             var day = 0.0;
    663             if (jd > 0.0) {
    664                 var jdm = jd + 0.5;
    665                 var z = Math.floor(jdm);
    666                 var f = jdm - z;
    667                 var jdmp = Math.floor(jd) + 0.5;
    668                 var pd = new persianDate();
    669                 pd.year = 475;
    670                 pd.month = 1;
    671                 pd.date = 1;
    672                 var depoch = jdmp - this.getJulianDayFromPersian(pd);
    673                 var cycle = Math.floor(depoch / 1029983);
    674                 var cyear = depoch % 1029983;
    675                 var ycycle;
    676                 if (cyear == 1029982) {
    677                     ycycle = 2820;
    678                 }
    679                 else {
    680                     var a1 = Math.floor(cyear / 366);
    681                     var a2 = cyear % 366;
    682                     ycycle = Math.floor(((2134 * a1) + (2816 * a2) + 2815) / 1028522) + a1 + 1;
    683                 }
    684                 y = ycycle + (2820 * cycle) + 474;
    685                 if (y <= 0) {
    686                     y--;
    687                 }
    688                 pd.year = y;
    689                 pd.month = 1;
    690                 pd.date = 1;
    691                 var yday = (jdmp - this.getJulianDayFromPersian(pd)) + 1;
    692                 m = (yday <= 186) ? Math.ceil(yday / 31) : Math.ceil((yday - 6) / 30);
    693                 pd.year = y;
    694                 pd.month = m;
    695                 pd.date = 1;
    696                 day = (jdmp - this.getJulianDayFromPersian(pd)) + 1;
    697             }
    698 
    699             var r = new persianDate;
    700             r.year = y,
    701                 r.month = m,
    702                 r.date = day
    703                 , r.day = this.getWeekday(this.getJulianDayFromPersian(r)),
    704                 r.gDate = new Date();
    705             return r;
    706         },
    707         getGCalendarDate: function (jd, dateformat) {
    708             var y = 0;
    709             var m = 0;
    710             var day = 0.0;
    711             if (jd > 0.0) {
    712                 var jdm = jd + 0.5;
    713                 var z = Math.floor(jdm);
    714                 var f = jdm - z;
    715                 /* cases "jgmonth","gmonth","jmonth" */
    716                 var a;
    717                 if (dateformat == "jmonth" || (dateformat == "jgmonth" && z < 2299161)) {
    718                     a = z;
    719                 }
    720                 else if (dateformat == "gmonth" || (dateformat == "jgmonth" && z >= 2299161)) {
    721                     var alpha = Math.floor((z - 1867216.25) / 36524.25);
    722                     a = z + 1 + alpha - Math.floor(alpha / 4);
    723                 }
    724                 var b = a + 1524;
    725                 var c = Math.floor((b - 122.1) / 365.25);
    726                 var d = Math.floor(365.25 * c);
    727                 var e = Math.floor((b - d) / 30.6001);
    728                 day = b - d - Math.floor(30.6001 * e) + f;
    729                 if (e < 14) {
    730                     m = e - 1;
    731                 }
    732                 else if (e == 14 || e == 15) {
    733                     m = e - 13;
    734                 }
    735                 if (m > 2) {
    736                     y = c - 4716;
    737                 }
    738                 else if (m == 1 || m == 2) {
    739                     y = c - 4715;
    740                 }
    741             }
    742 
    743             r = new Date();
    744             return new Date(y, m - 1, day, r.getHours(), r.getMinutes(), r.getSeconds(), r.getMilliseconds());
    745         },
    746         /* function getJulianDay(originalY, originalM, originalD) */
    747         getJulianDay: function (d, jgGOrJ) {
    748             /* jgGOrJ: 0 = auto Julian/Gregorian; 1 = Gregorian; 2 = Julian */
    749             var jgGOrJ = (jgGOrJ === undefined) ? 0 : jgGOrJ;
    750             /* Given UT */
    751             var y0 = d.getFullYear();
    752             var m0 = d.getMonth() + 1;
    753             var d0 = d.getDate();
    754             var y = y0 + 0;
    755             var m = m0 + 0;
    756             var d = d0 + 0.0;
    757             /* y = -4712;
    758              m = 1;
    759              d = 1.5; */
    760             /* Determine JD */
    761             if (m <= 2) {
    762                 y = y - 1;
    763                 m = m + 12;
    764             }
    765             var b = 0;
    766             if (d0 < 1 || ((m0 == 1 || m0 == 3 || m0 == 5 || m0 == 7 || m0 == 8 || m0 == 10 || m0 == 12) && d0 > 31) || ((m0 == 4 || m0 == 6 || m0 == 9 || m0 == 11) && d0 > 30)) {
    767                 //try {
    768                 //    console.log("Id 646");
    769                 //} catch (e) { }
    770             }
    771             if (jgGOrJ == 2 || (jgGOrJ == 0 && (y0 < 1582 || (y0 == 1582 && m0 < 10) || (y0 == 1582 && m0 == 10 && d0 <= 4)))) {
    772                 /* Julian calendar */
    773                 b = 0;
    774                 if (y0 / 4.0 == Math.round(y0 / 4.0)) {
    775                     /* Leap year */
    776                     if (m0 == 2 && d0 > 29) {
    777                         //try {
    778                         //    console.log("Id 656");
    779                         //} catch (e) { }
    780                     }
    781                 }
    782             }
    783             else if (jgGOrJ == 1 || (jgGOrJ == 0 && (y0 > 1582 || (y0 == 1582 && m0 > 10) || (y0 == 1582 && m0 == 10 && d0 >= 15)))) {
    784                 /* Gregorian calendar */
    785                 var a = Math.floor(y / 100);
    786                 b = 2 - a + Math.floor(a / 4);
    787                 if (y0 / 4.0 == Math.round(y0 / 4.0)) {
    788                     if (y0 / 100.0 == Math.round(y0 / 100.0)) {
    789                         if (y0 / 400.0 == Math.round(y0 / 400.0)) {
    790                             /* Leap year */
    791                             if (m0 == 2 && d0 > 29) {
    792                                 //try {
    793                                 //    console.log("Id 671");
    794                                 //} catch (e) { }
    795                             }
    796                         }
    797                     }
    798                     else {
    799                         /* Leap year */
    800                         if (m0 == 2 && d0 > 29) {
    801                             //try {
    802                             //    console.log("Id 680");
    803                             //} catch (e) { }
    804                         }
    805                     }
    806                 }
    807             }
    808             //else {
    809             //    try {
    810             //        console.log("Id 687");
    811             //    } catch (e) { }
    812             //}
    813             var jd = Math.floor(365.25 * (y + 4716)) + Math.floor(30.6001 * (m + 1)) + d + b - 1524.5;
    814             return jd;
    815         },
    816         getJulianDayFromPersian: function (pd) {
    817             y0 = pd.year, m0 = pd.month, d0 = pd.date;
    818             var epbase = y0 - ((y0 >= 0) ? 474 : 473);
    819             var epyear = 474 + (epbase % 2820);
    820             return d0 + ((m0 <= 7) ? ((m0 - 1) * 31) : (((m0 - 1) * 30) + 6)) + Math.floor(((epyear * 682) - 110) / 2816) + (epyear - 1) * 365 + Math.floor(epbase / 2820) * 1029983 + (1948320.5 - 1);
    821         },
    822         getWeekday: function (jd) {
    823             wds = [1, 2, 3, 4, 5, 6, 0];
    824             wd = Math.floor((jd + 1.5) % 7.0);
    825             return wds[wd];
    826         },
    827         getLastDayOfPersianMonth: function (pd) {
     735            return this.jalali_to_gregorian(pd);
     736            //>return this.getGCalendarDate(this.getJulianDayFromPersian(pd), "gmonth");
     737        },
     738        getWeekday: function (pd) {
     739            var gds = [1, 2, 3, 4, 5, 6, 0];
     740            return gds[this.jalali_to_gregorian(pd).getDay()];
     741        },
     742        getLastDayOfMonth: function (pd) {
    828743            y = pd.year, m = pd.month;
    829744            if (m >= 1 && m <= 6) {
    830745                return 31;
    831             }
    832             else if (m >= 7 && m < 12) {
     746            } else if (m >= 7 && m < 12) {
    833747                return 30;
    834748            }
    835             else if (m != 12) {
    836                 //try {
    837                 //    console.log("Id 715");
    838                 //}catch (e){}
    839             }
    840749            /* Esfand */
    841             if (y%4==3) {
     750            else if (this.isLeapYear(y)) {
    842751                /* Leap year */
    843752                return 30;
     
    845754            return 29;
    846755        },
    847         isLeapYear(year) {
    848             ary = array(1, 5, 9, 13, 17, 22, 26, 30);
     756        // 1244 to 1472
     757        isLeapYear: function (year) {
     758            var ary = year > 1342 ? [1, 5, 9, 13, 17, 22, 26, 30] : [1, 5, 9, 13, 17, 21, 26, 30];
    849759            b = year % 33;
    850             if (in_array($b, $ary))
     760            if (ary._indexOf(b)>-1)
    851761                return true;
    852762            return false;
  • wc-reports-lite/trunk/includes/class-wr-autoloader.php

    r3493461 r3493462  
    55 * Autoloader class.
    66 */
    7 class WCRL_Autoloader {
     7class WR_Autoloader {
    88
    99    /**
     
    1818     */
    1919    public function __construct() {
    20         if ( function_exists( '__autoload' ) ) {
    21             spl_autoload_register( '__autoload' );
    22         }
    2320        spl_autoload_register( array( $this, 'autoload' ) );
    24         $this->include_path = untrailingslashit( plugin_dir_path( WCRL_PLUGIN_FILE) ) . '/includes/';
     21        $this->include_path = untrailingslashit( plugin_dir_path( WR_PLUGIN_FILE) ) . '/includes/';
    2522    }
    2623    /**
     
    4946
    5047    /**
    51      * Auto-load WCRL classes on demand to reduce memory consumption.
     48     * Auto-load WR classes on demand to reduce memory consumption.
    5249     *
    5350     * @param string $class Class name.
     
    5653        $class = strtolower( $class );
    5754
    58         if ( 0 !== strpos( $class, 'wcrl_' ) ) {
     55        if ( 0 !== strpos( $class, 'wr_' ) ) {
    5956            return;
    6057        }
     
    6966}
    7067
    71 new WCRL_Autoloader();
     68new WR_Autoloader();
  • wc-reports-lite/trunk/readme.txt

    r3321863 r3493462  
    1 === NikanWP WooCommerce Reporting ===
    2 Contributors: nikanwp,mahdikhaksar
    3 Tags: order report, report, sale report, stock report, tax report, woocommerce, woocommerce dashboard, woocommerce order pdf, woocommerce order report, woocommerce order summary, woocommerce report, woocommerce reporting, woocommerce sale
    4 Requires at least: 4.9 or higher
    5 Tested up to: 5.5.1
    6 Requires PHP: 7.0
    7 Stable tag: 1.0.0
     1=== WooReports Lite — Sales Reports for WooCommerce ===
     2Contributors: nikanwp
     3Tags: woocommerce, sales report, stock report, order report, revenue report
     4Requires at least: 6.0
     5Tested up to: 6.9
     6Stable tag: 3.0.0
     7Requires PHP: 7.4
     8WC requires at least: 7.0
     9WC tested up to: 10.5.3
    810License: GPLv2 or later
    911License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1012
     13Free sales reports for WooCommerce — 11 report modules including orders, products, stock, tax, coupons and payment gateways. No API key needed.
     14
    1115== Description ==
    12 WooCommerce Reporting is a complete reporting solution for your store. It helps you track sales, monitor order trends, analyze product performance, and make data-driven decisions — all from a beautiful and intuitive dashboard. 
    13 [View Live Demo](https://demo.nikanwp.com/woocommerce-reporting/ "WooCommerce Reporting Demo") | [Pro Version](https://nikanwp.com/product/woocommerce-reporting/ "WooCommerce Reporting Pro")
    1416
    15 **Features**
    16 * Summary Of Reports (FREE)
    17 * Orders Reports (FREE)
    18 * Products Reports (FREE)
    19 * Categories Reports (FREE)
    20 * Coupons Reports (FREE)
    21 * Payment Gateway Reports (FREE)
    22 * Orders Status Reports (FREE)
    23 * Locations Reports (FREE)
    24 * Shippings Reports (FREE)
    25 * Tax Reports (FREE)
    26 * Stock Reports (FREE)
    27 * RTL & Jalali date Support (FREE)
    28 * Export Reports (PRO)
    29 * Advance Search Filter (PRO)
    30 * Email Scheduler (PRO)
    31 * Visual Reports (PRO)
    32 * Profit Of Sales Reports (PRO)
    33 * Dokan Seller Reports (PRO)
    34 * Customer Reports (PRO)
     17WooReports Lite gives you a clear view of your store performance — directly inside your WordPress dashboard. Reports are generated fresh from your WooCommerce database each time you open a page. No external API, no monthly fee, no setup required.
    3518
     19**Free report modules:**
     20
     21* **Overview** — revenue KPIs, orders count, AOV, sales trend chart, top products, top categories, top payment gateways
     22* **Orders** — full order list with date, customer name, status, items, shipping, discount, tax and total
     23* **Products** — revenue and quantity sold per product
     24* **Categories** — sales broken down by product category
     25* **Coupons** — usage count and total discount amount per coupon code
     26* **Payment Gateway** — revenue and order count by payment method
     27* **Orders Status** — orders grouped and counted by status
     28* **Locations** — sales by country and state/province
     29* **Shippings** — shipping method usage, order count and revenue
     30* **Tax** — tax collected by rate and country
     31* **Stock** — inventory levels, stock status and value for all products
     32
     33**Upgrade to [WooReports — the advanced reporting plugin for WooCommerce](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=readme&utm_campaign=upgrade) to unlock:**
     34
     35* Advanced date range filter — filter every report by any custom date range and compare periods side by side
     36* Customer reports — lifetime value, total orders, average order value, purchase history, searchable by name, email or phone
     37* Profit reports — net profit per product using Cost of Goods (COG) tracking
     38* Profit by payment gateway and profit per order
     39* Export to Excel (XLSX), PDF & CSV — one click on every report
     40* Scheduled email reports — automatically delivered to any recipient on your schedule
     41* Admin bar quick stats — today's revenue and order count always visible
     42* Dokan vendor reports — full multi-vendor reporting
     43
     44== Installation ==
     45
     461. Upload the plugin folder to `/wp-content/plugins/`
     472. Activate through the **Plugins** menu in WordPress
     483. Go to **WooReports** in your WordPress admin sidebar
     494. The Overview dashboard loads instantly — no configuration needed
     50
     51== Frequently Asked Questions ==
     52
     53= Does this plugin require WooCommerce? =
     54Yes. WooReports Lite requires WooCommerce to be installed and active. It reads data directly from your WooCommerce orders.
     55
     56= Is it compatible with HPOS (High-Performance Order Storage)? =
     57Yes. WooReports Lite is fully compatible with WooCommerce HPOS (custom order tables). It uses the WooCommerce order API exclusively and does not query the posts table directly.
     58
     59= Does it work with the latest version of WordPress and WooCommerce? =
     60Yes. WooReports Lite is tested with WordPress 6.9 and WooCommerce 10.5. It is compatible with PHP 7.4 through 8.3.
     61
     62= How up to date is the data in the reports? =
     63Reports are generated directly from your WooCommerce database each time you open a report page — so you always see your latest orders and store data.
     64
     65= Can I filter reports by date range? =
     66The Overview dashboard includes a built-in date preset filter (today, yesterday, last 7 days, last 30 days, last 365 days). Custom date range filtering across all reports — including orders, products, categories and more — is available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade).
     67
     68= Can I see which products are most profitable? =
     69Profit tracking with Cost of Goods (COG) per product, payment gateway and order is a Pro feature. [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade) lets you enter a cost price per product and see real net profit across all reports.
     70
     71= Can I export reports to Excel or PDF? =
     72Export to Excel (XLSX), PDF and CSV is available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade). In Lite, reports are available as on-screen tables only.
     73
     74= Can I see customer purchase history and lifetime value? =
     75Customer reports — including lifetime spend, total orders, average order value, and searchable by name, email or phone — are available in [WooReports Pro](https://nikanwp.com/product/woocommerce-reporting/?utm_source=wp-org&utm_medium=faq&utm_campaign=upgrade).
     76
     77= What is the difference between Lite and Pro? =
     78Lite includes 11 free report modules with overview-level date filtering. Pro adds custom date ranges on all reports, customer lifetime value reports, profit tracking with Cost of Goods, export to Excel/PDF/CSV, scheduled email reports, admin bar quick stats and Dokan vendor reports.
     79
     80= Does it support multisite? =
     81WooReports Lite has not been tested on WordPress Multisite. It is designed for single-site WooCommerce stores.
     82
     83== Screenshots ==
     84
     851. Overview dashboard — KPI cards, sales trend chart and top segments
     862. Orders report — full order list with status, items, shipping, tax and total
     873. Products report — revenue and quantity sold per product
     884. Stock report — inventory levels and stock status for all products
     89
     90== Changelog ==
     91
     92= 3.0.0 =
     93* Full compatibility with WooCommerce HPOS (High-Performance Order Storage / custom order tables)
     94* Completely redesigned modern UI
     95* Tested with WordPress 6.9 and WooCommerce 10.5
     96* Compatible with PHP 7.4–8.3
     97
     98= 1.0.0 =
     99* Initial release
  • wc-reports-lite/trunk/wcrl.php

    r2413794 r3493462  
    11<?php
    22/**
    3  * Plugin Name: Reports for WooCommerce Lite
    4  * Plugin URI: https://nikanwp.com/woocommerce-reporting/
    5  * Description: WooCommerce reporting system
    6  * Version: 1.0.0
     3 * Plugin Name: WooReports Lite — WooCommerce Reporting
     4 * Plugin URI: https://nikanwp.com/product/woocommerce-reporting/
     5 * Description: Free WooCommerce reporting plugin with 11 report modules — sales, orders, products, stock, tax, coupons, payment gateways and more. No API key required. Upgrade to Pro for profit tracking, export to Excel/PDF, customer reports and scheduled emails.
     6 * Version: 3.0.0
    77 * Author: NikanWP
    88 * Author URI: https://nikanwp.com/
    9  * Text Domain: wc-reports-lite
     9 * Requires at least: 6.0
     10 * Tested up to: 6.7
     11 * Requires PHP: 7.4
     12 * Requires Plugins: woocommerce
     13 * Text Domain: wooreports
    1014 * Domain Path: /languages
     15 * License: GPLv2 or later
    1116 */
    1217
    13 if (!defined( 'ABSPATH' ) ) {
    14     exit;// Exit if accessed directly.
     18if ( ! defined( 'ABSPATH' ) ) { exit; }
     19if ( ! defined( 'WR_PLUGIN_FILE' ) ) { define( 'WR_PLUGIN_FILE', __FILE__ ); }
     20define( 'WR_LITE', true );
     21
     22add_action( 'before_woocommerce_init', function () {
     23    if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
     24        \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
     25    }
     26} );
     27
     28// Add "Upgrade to Pro" action link on the plugins list page.
     29add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), function ( $links ) {
     30    $upgrade_link = sprintf(
     31        '<a href="%s" target="_blank" rel="noopener" style="color:#7f77dd;font-weight:600;">%s</a>',
     32        esc_url( 'https://nikanwp.com/product/woocommerce-reporting/?utm_source=lite&utm_medium=plugin-list&utm_campaign=upgrade' ),
     33        esc_html__( 'Upgrade to Pro', 'wooreports' )
     34    );
     35    array_unshift( $links, $upgrade_link );
     36    return $links;
     37} );
     38
     39if ( ! class_exists( 'WooReports' ) ) {
     40    include_once dirname( __FILE__ ) . '/includes/class-wooreports.php';
    1541}
    16 
    17 // Define WCRL_PLUGIN_FILE.
    18 if (!defined('WCRL_PLUGIN_FILE') ) {
    19     define( 'WCRL_PLUGIN_FILE', __FILE__ );
    20 }
    21 
    22 // Include the main wcrl class.
    23 if(!class_exists('WCRL')) {
    24     include_once dirname(__FILE__).'/includes/class-wcrl.php';
    25 }
    26 
    27 /**
    28  * Plugin action links
    29  *
    30  * @param $links
    31  *
    32  * @return array
    33  */
    34 add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), 'wcrl_plugin_action_links');
    35 function wcrl_plugin_action_links( $links ) {
    36     $nurl = get_locale() === WCRL_FARSILANG ? 'https://nikanwp.ir/product/woocommerce-reporting/' : 'https://nikanwp.com/woocommerce-reporting/';
    37     $links[] = '<a href="'.$nurl.'" style="color: #389e38;font-weight: bold;" target="_blank">' . __( 'Get Pro', 'wc-reports-lite' ) . '</a>';
    38     return $links;
    39 }
    40 
    41 WCRL::getInstance();
     42WooReports::getInstance();
Note: See TracChangeset for help on using the changeset viewer.