.table-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  max-width: 100%;
  box-sizing: border-box;
  position: relative;   /* hammasratta ankur */

  /* Kerimine käib .table-wrapper'is mõlemal teljel, kui konteiner (leht) kõrguse ja laiuse piirab -- tabel ise
     kõrgust välja ei mõtle. scroll: false (Table attr) teeb konteineri ja wrapper'i sisu mõõtu, kerimist ei teki. */
  &.no-scroll { height: auto; overflow: visible; }
  &.no-scroll .table-wrapper { overflow: visible; }

  /* Rea kõrgus on fikseeritud ja virtuaalkerimine usub seda arvu: ta korrutab teda otse ridade
     arvuga, et arvutada täitepuhvrid ja see, mitmes rida on kerimispositsiooni all. table.js loeb
     need siit getComputedStyle-ga, nii et CSS ja JS ei saa lahku minna.

     --table-row-height on VÄLISKÕRGUS, mille sees on ka alumine äärejoon (box-sizing: border-box).
     Just see arv liitub: border-collapse: separate + border-spacing: 0 juures on N rida täpselt
     N x see arv, esimene ja viimane rida kaasa arvatud.

     ÄRA pane tabelile border-collapse: collapse. Collapse jagab äärejoone kahe naaberlahtri vahel:
     esimene rida jääb poole piksli võrra madalamaks ja tabeli välisserv annab ühe piksli juurde,
     ehk N x reakõrgus ei võrdu enam tabeli kõrgusega ja virtuaalkerimine nihkub sisust mööda.
     Mõõdetud: collapse'iga esimene rida 31,5 vs ülejäänud 32,0; mõlemapoolsete äärejoontega
     10 rida = 321 px, mitte 320.

     Sisu, mis on kõrgem kui reakõrgus miinus polsterdus ja äärejoon, kasvatab rea ja lõhub sama
     arvutuse. CSS seda ära keelata ei saa: `height` on tabelilahtril miinimum, mitte maksimum, ja
     `overflow: hidden`/`clip` piirab ainult joonistamist, mitte kõrgust (mõõdetud). Seega on see
     kokkulepe, mitte lukk -- lahtri sisu peab mahtuma reakõrgusesse. */
  --table-row-height: 32px;
  --table-header-height: 41px;
  --table-cell-pad-y: 4px;
  --table-cell-border: 1px;

  /* Hammasratas ei ole veerg, vaid hõljub konteineri paremas ülanurgas. Konteiner ise ei keri --
     kerimine käib .table-wrapper'i sees -- seega ratas jääb paigale ka siis, kui veerud lähevad
     üle serva. Päisest kõrgemal (th on 2, kinnitatud veerg 3), valge taust katab päiselahtri.
     Kõrgus on päiserida ilma alumise äärejooneta -- nii jääb päise enda border-bottom
     katkematuna ikooni alt läbi paistma. */
  > .settings-icon {
    position: absolute;
    top: 0;
    right: 0;
    height: calc(var(--table-header-height) - 1px);
    z-index: 4;
    padding: 0 6px 0 10px;
    background: white;
    cursor: pointer;
  }

  .table-wrapper {
    overflow-x: auto;
    overflow-y: auto;
    min-height: 0;
    max-width: 100%;
    width: 100%;

    /* Plan-lehel (palju ridu + kaardil sadu markereid, igaüks omaette GPU-kihina) tegi see
       tabel korra kogu lehe põhjatult aeglaseks: iga hõljutus/redraw kus tahes lehel (isegi
       kaardist eemal) võttis sadu millisekundeid, kuigi tabelis ise midagi ei muutunud.

       Põhjus: tabelis on iga lahtri peal `overflow: hidden` (teksti kärpimiseks), mis tähendab
       tuhandeid eraldi "clip-chunk'e". Kui tabel EI ole omaette kompositor-kihil, elavad need
       chunk'id brauseri jaoks samas "ruumis" kaardi markeri-kihtidega, ja iga kaadri peale
       kontrollib brauser (Chrome'i "Layerize" samm), kas mingi chunk kattub mingi kihiga --
       see on ristkorrutis (tuhanded chunk'id × sajad markerid), mis tuleb uuesti läbi käia
       IGA commit'i peale, olenemata sellest, mis tegelikult ekraanil muutus.

       `will-change: transform` annab sellele wrapper'ile omaette kompositor-kihi. See ei
       tähenda, et transform kunagi liiguks -- me ei animeeri midagi. See on lihtsalt Blinki
       olemasolev API, et öelda "käsitle see alampuu väljast vaadatuna ühe suletud üksusena".
       Kui tabel on väljast üks kiht, ei osale tema tuhanded sisemised chunk'id enam kaardi
       markeritega tehtavas ülekattetestis -- kontrollitakse vaid "kas tabel-kui-tervik kattub
       markeriga", mitte "kas iga üksik lahter kattub iga üksiku markeriga". See on põhjus,
       miks aitab just `transform` (ja mõni sarnane: `opacity`, `filter`, `backdrop-filter`) --
       ainult neid omadusi oskab brauser GPU peal iseseisvalt uuesti komponeerida, ilma et
       peaks sisu uuesti joonistama, ja ainult nende jaoks tasub eraldi kiht ette valmistada.
       `will-change: background-color` (mida kunagi siin proovitud oli) ei anna mitte kunagi
       eraldi kihti -- taustavärvi muutus nõuab ikka uue joonistuse, olgu kiht mis on, seega
       Blink ei loo selle jaoks kompositor-kihti üldse.

       Väikese tabeli/rea-arvu juures ei ole sellest midagi tunda (ristkorrutis on väike),
       seega ÄRA eemalda seda rida "kasutuseta näib" põhjendusel -- efekt ilmneb alles suurte
       andmemahtude ja paljude kaardielementide koosmõjus. Kõrvalmõju: see annab wrapper'ile
       uue containing block'i `position: fixed` järglaste jaoks -- fixed-positsioneeritud
       elemente (dropdown, tooltip) SEE wrapper'i SISSE panna ei tohi, nad hüppaksid siis
       wrapper'i, mitte ekraani suhtes.

       Loe pikemalt:
       https://web.dev/articles/stick-to-compositor-only-properties-and-manage-layer-count
       https://www.alibabacloud.com/blog/front-end-performance-optimization-with-accelerated-compositing-part-1_594194 */
    will-change: transform;

    /* Vertikaalne riba algab päise alt: päis on kinnitatud ja hammasratas istub tema paremas nurgas, mis muidu
       kataks riba ülemise otsa. Riba mõõt ja värv tulevad shell.css-ist; Firefoxis (standardsed omadused) jääb riba täispikaks. */
    &::-webkit-scrollbar-track { margin-top: calc(var(--table-header-height) + 4px); }   /* +4: pide ei puuduta päise alumist joont */
  }

  table {
    width: 100%;
    border-collapse: separate;
    border-spacing: 0;
    margin: 0;
    table-layout: auto;

    th, td {
      text-align: center;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      padding: var(--table-cell-pad-y) 6px;
      min-width: 0;
      box-sizing: border-box;
      vertical-align: middle;
    }

    /* Lahtri sisu keskele ka siis, kui ta on inline-element (ikoon, silt, sisendkast) -- muidu
       istub ta baasjoonel ja lükkab reakõrgust suuremaks kui reareegel lubab. */
    th > *, td > * { vertical-align: middle }

    /* Kärbitud lahter näitab hõljutamisel kogu sisu: kärpimine maha ja sisu jookseb järgmiste
       lahtrite peale. Laius jääb paigast liikumata, sest ::before ja transform ei mõjuta paigutust.
       Mõõdud arvutab table.js (`--spill-width` on ülejooksu laius, `--spill-shift` nihe vasakule,
       kui muidu jääks sisu wrapperist välja).
       `background: inherit` võtab rea värvi lahtrilt endalt, seega hover/valitud/keelatud olekud
       tulevad õigesti ilma neid siin teadmata. */
    td.spill, th.spill {
      /* Positsioneeritus on vaja ainult spilli ajal: ::before vajab containing block'i ja z-index
         ei mõju positsioneerimata elemendile. Kõigil lahtritel seda hoida ei ole vaja -- th on
         niikuinii sticky. */
      position: relative;
      overflow: visible;
      transform: translateX(calc(-1 * var(--spill-shift, 0px)));
      /* Keha-lahter on vaikimisi läbipaistev ja siis ei oleks ::before all midagi. Rea hover
         (0,3,3) ja valitud lahter (0,3,2) on spetsiifilisemad kui see (0,3,1) ja sõidavad üle. */
      background-color: white;
      /* Sisu ilmub kohe; reast päritud background-color üleminek jätaks tausta 200 ms hiljaks
         ja naabri tekst paistaks selle aja läbi. */
      transition: none;
    }

    td.spill { z-index: 1 }   /* tbody tr on stacking-kontekst, seega jääb rea sisse */
    th.spill { z-index: 3 }   /* päiselahtrid on ise 2, laienenu peab naabritest ette jääma */

    /* Kärpimine võib olla ka sisemisel elemendil (päises `.sortable .sort-label`, keha-lahtrites
       lehe enda css). Need on spetsiifilisemad kui see reegel ja peavad spilli ajal kõik taanduma,
       seega !important -- siin ongi mõte "midagi selle sees ei kärbi". */
    :is(td, th).spill * { overflow: visible !important }

    :is(td, th).spill::before {
      content: '';
      position: absolute;
      inset: 0 calc(-1 * var(--spill-width, 0px)) 0 0;
      background: inherit;
      z-index: -1;
      pointer-events: none;   /* taust katab naabreid, aga klikk kuulub neile */
    }

    /* line-height täidab kogu sisuala, seega rida on täpselt --table-row-height ja `height`
       deklaratsiooni ei ole vaja (ta oleks niikuinii ainult miinimum). */
    th {
      background: white;
      font-weight: 600;
      line-height: calc(var(--table-header-height) - 2 * var(--table-cell-pad-y) - var(--table-cell-border));
      border-bottom: var(--table-cell-border) solid #e0e0e0;
      position: sticky;
      top: 0;
      z-index: 2;
    }

    td {
      line-height: calc(var(--table-row-height) - 2 * var(--table-cell-pad-y) - var(--table-cell-border));
      border-bottom: var(--table-cell-border) solid #e0e0e0;

      /* tekstiväli lahtris on täpselt rea sisukõrgune: vertikaalne padding maha (td teeb paddingut ise) ja
         line-height sama mis lahtril miinus välja enda 1 px raam üleval ja all */
      input.pl {
        padding-top: 0;
        padding-bottom: 0;
        line-height: calc(var(--table-row-height) - 2 * var(--table-cell-pad-y) - var(--table-cell-border) - 2px);
      }
    }

    /* Sticky left column (selection) */
    .sticky-left {
      position: sticky;
      left: 0;
      z-index: 3;
      background: white;
      align-content: center;
    }

    .text-left {
      text-align: left;
    }

    .text-center {
      text-align: center;
    }

    .text-right {
      text-align: right;
    }

    /* Header select-all checkbox: always visible with gray borders (inverse of default white border).
       Checked-olek (taust + linnuke) tuleb base .check reeglist, seega override ainult valimata kastil. */
    thead .check:not(:checked) {
      border-color: #C2C2C2;
      background: rgba(255, 255, 255, 0.6);
    }
    thead .check:not(:checked):hover {
      border-color: #A8A8A8;
    }

    .check:checked {
      --check-border: var(--pl);
      --check-mark: var(--pl);
    }

    /* Sticky selected rows */
    tr.sticky-row {
      position: sticky;
      z-index: 5;
      background: white;
      
      td {
        background: white;
      }
      
      /* Maintain selection styling for sticky rows */
      &.selected td {
        background: var(--sel-color, #e3f2fd);
        cursor: grab;
      }
      
      /* Ensure sticky columns in sticky rows maintain their background */
      td.sticky-left {
        background: inherit;
      }
      
      &.selected td.sticky-left {
        background: var(--sel-color, #e3f2fd);
      }
      
      /* Only show shadow on the last sticky row */
      &.last-sticky {
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      }
    }

    /* Sortable header styles */
    .sortable {
      cursor: pointer;
      user-select: none;

      .sort-wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        min-width: 0;
      }

      .sort-label {
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .sort-arrow {
        flex-shrink: 0;
        font-size: 14px;
        color: #666;
        line-height: 1;
        margin: 0 0 0 4px;
        padding: 0;
        opacity: 0.5;
        transition: all 0.2s ease;
      }

      &.active .sort-arrow {
        color: #FFA600;
        opacity: 1;
      }

      &:hover .sort-arrow {
        color: #FFA600;
        opacity: 1;
      }

      /* Specific alignment overrides for sortable headers */
      &.text-left .sort-wrap {
        justify-content: flex-start;
      }

      &.text-right .sort-wrap {
        justify-content: flex-end;
      }

      &.text-center .sort-wrap {
        justify-content: center;
      }
    }

    tbody tr {
      position: relative;
      z-index: 0;

      > td {
        /* will-change: background-color; */
        transition: background-color 0.2s ease;
      }

      &:hover > td {
        background-color: #F5F5F5
      }

      > td.selected {
        background: #FFF1BF;
      }

      /* Prevent text selection on draggable rows (Safari fix) */
      &[draggable="true"] {
        user-select: none;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
      }

      /* Disabled row styling */
      &.disabled {
        user-select: none;

        &.faded {
          opacity: 0.4;
          filter: grayscale(100%);

          /* Disable interactions for most elements but allow ID column */
          input, button, a, label, select, textarea {
            pointer-events: none;
          }

          td {
            background: #fafafa;
          }
        }

        &:hover > td {
          background: inherit;
        }
      }
    }

    tfoot {
      background: white;
      position: relative;

      /* Ensure footer completely blocks interactions */
      &::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: transparent;
        pointer-events: auto;
        z-index: 3;
      }

      /* Footer overflow support */
      .footer-cell {
        &.footer-overflow {
          overflow: visible;
          position: relative;
        }

        /* Positioned overflow content that doesn't affect layout */
        .footer-overflow-content {
          position: absolute;
          left: 4px;
          top: 50%;
          transform: translateY(-50%);
          white-space: nowrap;
          z-index: 10;
          padding: 0 2px;
        }

        /* Hidden placeholder to maintain cell height */
        .footer-placeholder {
          visibility: hidden;
        }
      }

      &.ship-footer {
        .footer-row {
          font-weight: 600;
          height: 29px;
          line-height: 29px;

          .footer-cell {
            position: relative;
            z-index: 1;
            border-bottom: none;
            padding: 4px 6px;
            height: 29px;
            line-height: 29px;
          }

          /* Selected footer styling */
          &.selected-footer {
            position: relative;

            .footer-cell {
              z-index: 1;
              border-bottom: none;
              background-color: #FFF1BF;

              &.footer-overflow {
                z-index: 2;
              }
            }

            /* Selected footer sticky columns for non-scrollable tables */
            .sticky-left {
              background: white !important;
              position: relative;

              &::after {
                content: '';
                position: absolute;
                left: 50%;
                top: 0;
                bottom: 0;
                right: 0;
                background: #FFF1BF;
                border-top-left-radius: 8px;
                border-bottom-left-radius: 8px;
              }
            }

          }
        }
      }
    }

    /* Numeric column styles */
    .num {
      text-align: right;
      font-variant-numeric: tabular-nums;
    }

    /* Zero value styling */
    .zero {
      color: #8D92A5;
    }

    /* Price column styling */
    .price {
      text-align: right;
      font-variant-numeric: tabular-nums;

      .price-text {
        margin-right: 8px;
      }
    }

    /* Status icon styling */
    .status-icon {
      display: inline-block;
      width: 12px;
      height: 12px;
      margin-right: 3px;
      vertical-align: baseline;
      line-height: 1;

      &.completed svg {
        width: 10px;
        height: 11px;
      }

      &.partial svg {
        width: 10px;
        height: 11px;
      }

      &.error svg {
        width: 12px;
        height: 11px;
      }

      &.empty {
        visibility: hidden;
      }
    }

    /* Date with icon styling */
    .date-with-icon {
      display: inline-block;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      vertical-align: top;
      max-width: 100%;

      & > * {
        display: inline;
        white-space: nowrap;
      }

      /* Ikoon jääb oma 12px laiusesse kastisse ka siis, kui svg on väiksem või puudub hoopis --
         inline-elemendil laius ei kehtiks ja aadress algaks igas reas eri kohast. */
      & > .status-icon {
        display: inline-block;
      }

      .address-info {
        margin-left: 2px;
        display: inline ;
      }

      .company {
        color: #8D92A5;
        font-weight: 500;
        display: inline;
      }

      .msymbol {
        display: inline-block;
        vertical-align: middle;
      }

      time {
        display: inline;
        margin: 0 2px;
        font-weight: 500;
      }
    }

    /* Schedule icon styling */
    .msymbol.schedule {
      margin-left: 3px;
      color: #8D92A5;
      vertical-align: middle;
      font-size: 16px;
      line-height: 1;
    }

    /* Button styling for table actions */
    button {
      font-size: 86%;
      margin: 0 4px;
      padding: 0px 2px;
      color: #666;
      background-color: #f5f5f5;
      border: 1px solid #ccc;
      border-radius: 3px;
      cursor: pointer;

      &:hover {
        background-color: #e8e8e8;
      }
    }

    /* ID column styling */
    .nr {
      color: #E78F00;
      text-decoration: none;
      cursor: pointer;
    }

    /* Receipt icon styling */
    .receipt {
      font-size: 16px;
      color: #8D92A5;
      margin-right: 4px;
      vertical-align: middle;
      padding: 0;
    }

    /* Price with icon styling */
    .price-with-icon {
      display: flex;
      justify-content: space-between;
      align-items: center;
      width: 100%;
      gap: 8px; /* Add gap between icon and price */

      .receipt {
        margin-left: 4px;
        flex-shrink: 0;
      }

      .price-text {
        margin-left: auto;
        flex-shrink: 0;
      }
    }

    /* With note styling */
    .with-note {
      position: relative;

      &::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        display: block;
        border-left: 10px solid transparent;
        border-bottom: 10px solid transparent;
        border-top: 10px solid #FF6B35;
      }
    }
  }

  &.scrollable {
    position: relative;
    z-index: 1; /* Create stacking context so sticky elements don't overlap dropdowns */
    
    table {
      thead th {
        position: sticky;
        top: 0;
        background: white;
        z-index: 4;
      }

      thead th.sticky-left {
        z-index: 5;
      }

      tfoot.ship-footer {
        position: sticky;
        bottom: 0;
        background: white;
        z-index: 4;
        box-shadow: 0 -2px 8px rgba(0,0,0,0.1);
      }

      /* Ensure tfoot sticky columns work in scrollable mode */
      tfoot .sticky-left {
        position: sticky !important;
        left: 0 !important;
        z-index: 6 !important;
        background: white;
      }

      /* Selected footer sticky columns */
      tfoot .selected-footer .sticky-left {
        position: sticky !important;
        left: 0 !important;
        z-index: 6;
        background: white !important;
        position: relative;
      }

      tfoot .selected-footer .sticky-left::after {
        content: '';
        position: absolute;
        left: 50%;
        top: 0;
        bottom: 0;
        right: 0;
        background: #FFF1BF;
        border-top-left-radius: 8px;
        border-bottom-left-radius: 8px;
      }

    }
  }

  @media (max-width: 768px) {
    font-size: 12px;

    table {
      th, td {
        padding: 2px 4px;
      }
    }

    /* Responsive adjustments for sticky elements */
    &.scrollable {
      table {
        thead th {
          box-shadow: 0 1px 4px rgba(0,0,0,0.1);
        }

        tfoot.ship-footer {
          box-shadow: 0 -1px 4px rgba(0,0,0,0.1);
        }

        .selected-footer {
          box-shadow: 0 -1px 4px rgba(0,0,0,0.1);
        }
      }
    }
  }

  .settings-icon {
    font-size: 18px;
    color: #666;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease;

    &[menu-open] {
      color: #FFA600;
    }
  }

  .sort-wrap {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;

    &.justify-start {
      justify-content: flex-start;
    }

    &.justify-end {
      justify-content: flex-end;
    }

    &.justify-center {
      justify-content: center;
    }
  }

  .sort-arrow {
    font-size: 14px;
    color: #666;
    line-height: 1;
    margin: 0;
    padding: 0;
    transition: color 0.2s ease;

    &.active {
      color: #FFA600;
    }
  }

  .footer-row {
    height: 40px;
  }

  /* Virtual scrolling spacer rows */
  .virtual-spacer {
    pointer-events: none;
    
    td {
      padding: 0;
      border: none;
      background: transparent;
    }
  }

  .msymbol:hover {
    color: #FF8C00;
    cursor: pointer;
  }

  .msymbol.schedule:hover {
    color: #FF8C00;
  }

  .sort-arrow.msymbol:hover {
    color: #FF8C00;
  }

  .settings-icon.msymbol:hover {
    color: #FF8C00;
  }
}

/* Seadete menüü (table.js tableSettings). Kast on body all, mitte tabelis, seepärast tipptasemel.
   Silt vasakul, lüliti või ikoon paremal; klikk käib real, lüliti on ainult seisu näitaja. */
.menubox.table-settings li.item .label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.menubox.table-settings li.item .toggle { pointer-events: none; }
.menubox.table-settings li.item .msymbol { font-size: 18px; color: #9AA0A6; }
.menubox.table-settings li.item:hover .msymbol { color: #FFA600; }
