/* Παράχθηκε από το `templates/base.html` (03/09/2026).
 *
 * ⚠️ **Η ΣΕΙΡΑ ΕΧΕΙ ΣΗΜΑΣΙΑ.** Αυτό το αρχείο φορτώνεται ΜΕΤΑ από το
 * `{% block head %}` των σελίδων-παιδιών. Μετακινώντας το, αλλάζει ποιος
 * κανόνας νικά σε ισοβαθμία ειδικότητας — έχει ήδη κοστίσει μια φορά σε
 * αυτό το έργο (νεκρός κανόνας `.modal-backdrop` στο index.html).
 *
 * ⚠️ **Καμία σχετική `url()` εδώ μέσα.** Σε αρχείο CSS λύνεται ως προς το
 * ίδιο το αρχείο, όχι ως προς τη σελίδα — θα έσπαγε σιωπηλά.
 */

      /* ── Driver.js tour overrides ─────────────────────────── */
      .garage-tour-popover { font-family: 'Poppins', sans-serif; }
      .garage-tour-popover .driver-popover-title { font-weight: 700; font-size: 1.05rem; }
      .garage-tour-popover .driver-popover-description { font-size: .92rem; line-height: 1.55; white-space: pre-line; }
      .garage-tour-popover .driver-popover-footer button { font-size: .86rem; border-radius: .4rem; }
      /* Light mode (default) */
      .garage-tour-popover {
        background: #fff;
        color: #212529;
        border: 1px solid rgba(0,0,0,.1);
        box-shadow: 0 8px 28px rgba(0,0,0,.15);
      }
      .garage-tour-popover .driver-popover-title { color: var(--gary-primary); }
      .garage-tour-popover .driver-popover-description { color: #444; }
      .garage-tour-popover .driver-popover-arrow-side-left.driver-popover-arrow  { border-left-color:  #fff; }
      .garage-tour-popover .driver-popover-arrow-side-right.driver-popover-arrow { border-right-color: #fff; }
      .garage-tour-popover .driver-popover-arrow-side-top.driver-popover-arrow   { border-top-color:   #fff; }
      .garage-tour-popover .driver-popover-arrow-side-bottom.driver-popover-arrow{ border-bottom-color:#fff; }
      /* Dark mode */
      [data-bs-theme="dark"] .garage-tour-popover {
        background: var(--gary-dk-surface);
        color: var(--gary-dk-bright);
        border: 1px solid rgba(240,246,252,.12);
        box-shadow: 0 8px 28px rgba(0,0,0,.45);
      }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-title { color: var(--gary-accent-dark); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-description { color: var(--gary-dk-text); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-progress-text { color: var(--gary-dk-subtle); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-prev-btn { color: var(--gary-dk-subtle); border-color: var(--gary-dk-border); background: transparent; }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-prev-btn:hover { color: var(--gary-dk-bright); border-color: var(--gary-dk-subtle); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-next-btn,
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-done-btn { background: var(--gary-primary); border-color: var(--gary-primary); color: #fff; }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-next-btn:hover,
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-footer button.driver-popover-done-btn:hover { background: var(--gary-primary-hover); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-close-btn { color: var(--gary-dk-subtle); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-close-btn:hover { color: var(--gary-dk-bright); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-arrow-side-left.driver-popover-arrow  { border-left-color:  var(--gary-dk-surface); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-arrow-side-right.driver-popover-arrow { border-right-color: var(--gary-dk-surface); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-arrow-side-top.driver-popover-arrow   { border-top-color:   var(--gary-dk-surface); }
      [data-bs-theme="dark"] .garage-tour-popover .driver-popover-arrow-side-bottom.driver-popover-arrow{ border-bottom-color:var(--gary-dk-surface); }
      /* ── Driver.js popover: mobile responsive ── */
      @media (max-width: 767px) {
        .driver-popover {
          max-width: calc(100vw - 24px) !important;
          min-width: 260px !important;
        }
        .garage-tour-popover .driver-popover-title { font-size: .98rem !important; }
        .garage-tour-popover .driver-popover-description { font-size: .88rem !important; line-height: 1.5; }
        .garage-tour-popover .driver-popover-footer button {
          font-size: .83rem !important; padding: .35rem .65rem !important;
          min-height: 36px;
        }
      }
      /* Toast container */
      #tourToastContainer {
        position: fixed; bottom: 1.2rem; right: 1.2rem; z-index: 9999;
        display: flex; flex-direction: column; align-items: flex-end;
      }
      /* ⚠️ Και αυτό το δοχείο πρέπει να καθαρίζει τη μπάρα πλοήγησης.
         Μέχρι τις 29/08/2026 ανέβαινε **μόνο** όταν φαινόταν το κουμπί
         «πάνω» (`body.has-back-to-top`), δηλαδή σε κάθε άλλη περίπτωση τα
         μηνύματα της ξενάγησης κάθονταν πάνω στη μπάρα — ίδιο σφάλμα με τα
         κανονικά toast, στο μοναδικό δοχείο που είχε ξεχαστεί. */
      @media (max-width: 767px) {
        /* ⚠️ **Ο ίδιος κανόνας, και για το δεύτερο δοχείο.** Το 29/08 αυτό
           εδώ ήταν το «μοναδικό που είχε ξεχαστεί»· δεν το ξαναφήνουμε πίσω.
           Βλ. `--gary-bottom-inset` στο `base.html`. */
        #tourToastContainer {
          bottom: calc(var(--gary-bottom-inset, calc(var(--gary-bottomnav-h, 76px) + env(safe-area-inset-bottom, 0px))) + 1.2rem);
        }
      }
      #tourToastContainer .toast { min-width: 280px; max-width: 340px; }
      /* ─────────────────────────────────────────────────────────────
         PAGE LAYOUT
         Χρήση: <div class="page-card"> … </div>
         Τύπος Α Λίστα:    page-card (default, max-w 960px)
         Τύπος Β Φόρμα:    page-card page-card--form (max-w 680px)
         Τύπος Γ Dashboard: page-card page-card--wide (max-w 1200px, no border)
      ──────────────────────────────────────────────────────────────── */
      /* Εικονίδιο τίτλου σελίδας: το ίδιο Bootstrap Icon με την πλευρική μπάρα
         (αίτημα ιδιοκτήτη 16/09/2026 — ήταν emoji διαφορετικά από του μενού). */
      .page-title-icon { color: var(--gary-primary); margin-right: .15em; }
      [data-bs-theme="dark"] .page-title-icon { color: var(--gary-accent-dark); }

      /* Μονόχρωμο πράσινο εικονίδιο σε τίτλους ενοτήτων, ετικέτες και επιλογές
         (αίτημα ιδιοκτήτη 17/09/2026: «δεν μου αρέσουν τα έγχρωμα icons»).
         ⚠️ **Όχι μέσα σε κουμπί**: εκεί το εικονίδιο κληρονομεί το χρώμα του
         κουμπιού — πράσινο πάνω σε γεμάτο πράσινο κουμπί εξαφανίζεται. */
      .gary-ico { color: var(--gary-primary); }
      [data-bs-theme="dark"] .gary-ico { color: var(--gary-accent-dark); }
      /* ⚠️ Μέσα σε κουμπί, σήμα ή μήνυμα το εικονίδιο παίρνει **το χρώμα του
         πλαισίου του**: πράσινο πάνω σε γεμάτο πράσινο κουμπί εξαφανίζεται, και
         σε κόκκινο μήνυμα σφάλματος θα έλεγε άλλα από το κείμενο δίπλα του. */
      .btn .gary-ico, .badge .gary-ico, .alert .gary-ico,
      .btn-close .gary-ico, .nav-link.active .gary-ico { color: inherit; }

      /* Το μενού του κινητού (κάτω μπάρα + φύλλο «Περισσότερα») φορά τα ίδια
         εικονίδια με την πλευρική μπάρα, στο ίδιο πράσινο. Το χρώμα μένει ίδιο
         και στην ενεργή καρτέλα: εκείνη ξεχωρίζει από το φόντο και το έντονο
         κείμενο. Το υπόλοιπο CSS του μενού είναι inline στο base.html. */
      .mob-tab__icon, .mob-sheet__item .si { color: var(--gary-primary); }
      [data-bs-theme="dark"] .mob-tab__icon,
      [data-bs-theme="dark"] .mob-sheet__item .si { color: var(--gary-accent-dark); }

      .page-card {
        background: var(--bs-body-bg);
        border: 1px solid var(--bs-border-color);
        border-radius: .75rem;
        box-shadow: 0 1px 6px rgba(0,0,0,.07);
        padding: 1.75rem;
        max-width: 960px;
        margin: 1.75rem auto;
      }
      .page-card--form { max-width: 680px; }

      /* ── Κολλητή γραμμή εργαλείων + κεφαλίδα πίνακα (static/js/sticky_table.js) ──
         Κινήσεις & Ιστορικό, Απόθεμα, Ομάδα, Προμηθευτές (αίτημα 16/09/2026).
         Μόνο υπολογιστής: στο κινητό οι πίνακες είναι κάρτες χωρίς κεφαλίδα. */
      @media (min-width: 769px) {
        [data-sticky-bar] {
          position: sticky; top: 0; z-index: 40;
          background: var(--bs-body-bg);
          padding-top: .5rem; padding-bottom: .5rem;
          transition: box-shadow .2s ease;
        }
        /* Το `bg-transparent` του Bootstrap είναι !important — σε κολλητή γραμμή
           θα άφηνε τις γραμμές του πίνακα να φαίνονται από κάτω της. */
        [data-sticky-bar].bg-transparent { background-color: var(--bs-body-bg) !important; }
        /* Κάρτα ως γραμμή (Ιστορικό → Αντικείμενα): το `.card` έχει ημιδιαφανές
           φόντο με blur, και δικό της εσωτερικό περιθώριο. */
        [data-sticky-bar].card { background: var(--bs-body-bg); backdrop-filter: none; padding-top: 0; padding-bottom: 0; }
        [data-sticky-bar].is-stuck { box-shadow: 0 3px 10px rgba(0,0,0,.08); }
        [data-bs-theme="dark"] [data-sticky-bar].is-stuck { box-shadow: 0 3px 10px rgba(0,0,0,.35); }
        table[data-sticky-head] > thead { position: sticky; top: var(--sticky-bar-h, 0px); z-index: 20; }
        /* Αδιαφανές φόντο: η γραμμή φίλτρων ήταν διάφανη, και οι γραμμές του
           πίνακα θα φαίνονταν από κάτω της. */
        table[data-sticky-head] > thead > tr > th { background-color: var(--bs-tertiary-bg); }
        table[data-sticky-head] > thead > tr.col-filters > th { background-color: var(--bs-body-bg) !important; }
        /* Χωρίς scroll container ανάμεσα σε κεφαλίδα και σελίδα. `clip`, όχι
           hidden/auto: μόνο το clip δεν φτιάχνει νέο scroll container. */
        .table-responsive:has(table[data-sticky-head]) { overflow-x: clip; overflow-y: visible; }
        .table-responsive.is-hscroll:has(table[data-sticky-head]) { overflow-x: auto; }
        .table-responsive.is-hscroll table[data-sticky-head] > thead { position: static; }
      }
      /* Σελίδες φόρμας με `.card` αντί για `.page-card` (Προσθήκη, Επεξεργασία):
         ίδιο κάθετο περιθώριο με όλες τις άλλες. Ξεκινούσαν 28px ψηλότερα
         (αναφορά ιδιοκτήτη 16/09/2026). */
      .page-frame { margin-top: 1.75rem; margin-bottom: 1.75rem; }
      .page-card--wide { max-width: 1200px; }
      /* ⚠️ Ήταν inline `style="padding:1.75rem;max-width:none"` σε πέντε
         σελίδες. Το inline style νικά **κάθε** κανόνα φύλλου, οπότε η μείωση
         padding του κινητού πιο κάτω ήταν νεκρή εκεί — και το `padding`
         ήταν ούτως ή άλλως ίδιο με το default, δηλαδή δεν πρόσθετε τίποτα
         και μόνο έσπαγε το responsive. Ίδια παγίδα με το
         `#garyToastContainer` (βλ. CLAUDE.md). Ό,τι πρέπει να προσαρμόζεται
         ανά οθόνη ζει σε CSS, ποτέ σε attribute. */
      .page-card--full { max-width: none; }

      /* ─────────────────────────────────────────────────────────────
         ΠΙΝΑΚΑΣ → ΚΑΡΤΕΣ σε στενή οθόνη  (`class="gary-stack"`)
         Ετικέτες από τα <th>, μέσω static/js/table_stack.js.
      ──────────────────────────────────────────────────────────────── */
      @media (max-width: 767px) {
        /* ⚠️ Το `min-width` του πίνακα πρέπει να ακυρωθεί, αλλιώς ο πίνακας
           εξακολουθεί να ξεχειλίζει και η στοίβαξη δεν κερδίζει τίποτα. */
        table.gary-stack { min-width: 0 !important; width: 100% !important; }
        table.gary-stack, table.gary-stack tbody { display: block; }
        table.gary-stack thead, table.gary-stack tfoot { display: none; }
        table.gary-stack tr {
          display: flex; flex-direction: column;
          border: 1px solid var(--bs-border-color);
          border-radius: .5rem;
          padding: .55rem .7rem;
          margin-bottom: .5rem;
          background: var(--bs-body-bg);
        }
        table.gary-stack td {
          display: flex; gap: .5rem; align-items: baseline;
          border: 0 !important;
          padding: .12rem 0 !important;
          width: auto !important;
          white-space: normal;
        }
        /* Η ετικέτα μπαίνει μόνο όταν η στήλη έχει όνομα — μια στήλη κουμπιών
           δεν χρειάζεται «:» από πάνω της. */
        table.gary-stack td[data-label]::before {
          content: attr(data-label);
          flex: 0 0 8.5em;
          font-size: .74rem;
          font-weight: 600;
          color: var(--bs-secondary-color);
          text-transform: none;
        }
        /* Κενό κελί σε κάρτα είναι μια γραμμή που λέει «τίποτα». */
        table.gary-stack td:empty { display: none; }
      }
      [data-bs-theme="dark"] .page-card {
        box-shadow: 0 1px 8px rgba(0,0,0,.35);
      }

      /* ─────────────────────────────────────────────────────────────
         PAGE TITLE
         Χρήση: <h2 class="page-title">Τίτλος</h2>
      ──────────────────────────────────────────────────────────────── */
      .page-title {
        font-weight: 600;
        text-align: center;
        margin-bottom: 1.5rem;
        color: var(--bs-body-color);
        letter-spacing: -.01em;
      }

      /* ── Κεφαλίδα σελίδας με κουμπιά ── (αίτημα 17/09/2026)
         Τίτλος στο κέντρο και όταν έχει δίπλα του «Πίσω» ή ενέργειες.
         Μετρημένο πριν, απόσταση του τίτλου από το κέντρο στα 1280px:
         Εργαλεία −455, Απογραφή −442, Ανακλήσεις −350, Ειδοποιήσεις −330,
         Προσθήκη +34 (το «Πίσω» τον έσπρωχνε).
           <div class="page-head">
             <div class="page-head-start">«Πίσω»</div>          (προαιρετικό)
             <h2 class="page-title">Τίτλος</h2>
             <div class="page-head-end">ενέργειες</div>        (προαιρετικό)
           </div>
         Το grid μόνο του **δεν** κρατά ίσες δύο πλευρές με διαφορετικό
         περιεχόμενο: το `static/js/page_head.js` μετρά την πιο φαρδιά και τη
         δίνει ως ελάχιστο και στις δύο (`--ph-side`), ή κάνει την κεφαλίδα δύο
         σειρών (`is-stacked`) όταν ο τίτλος δεν χωρά ανάμεσα.
         ⚠️ Χωρίς το script η προεπιλογή είναι `auto`, **όχι** `0`: με μηδενικό
         ελάχιστο ένα φαρδύ κουμπί πέφτει πάνω στον τίτλο. */
      .page-head {
        display: grid;
        grid-template-columns: minmax(var(--ph-side, auto), 1fr) auto minmax(var(--ph-side, auto), 1fr);
        align-items: center;
        column-gap: .75rem; row-gap: .5rem;
        margin-bottom: 1rem;
      }
      .page-head > .page-title { grid-column: 2; grid-row: 1; margin: 0; }
      .page-head-start, .page-head-end {
        grid-row: 1; display: flex; align-items: center; flex-wrap: wrap; gap: .5rem;
      }
      .page-head-start { grid-column: 1; justify-self: start; }
      .page-head-end { grid-column: 3; justify-self: end; justify-content: flex-end; }
      /* Η στήλη του τίτλου (`auto`) παίρνει πρώτα όλο το πλάτος του. Μετρημένο
         στη βάση barcode σε 1000px: τίτλος 650px και το «Εξαγωγή» στριμωγμένο
         σε 97px, **τέσσερις γραμμές**. Κουμπί που δεν σπάει → σπάει ο τίτλος. */
      @media (min-width: 576px) {
        .page-head-start .btn, .page-head-end .btn { white-space: nowrap; }
      }
      /* Δύο σειρές: από το script όταν δεν χωρά, και πάντα στο κινητό (και
         χωρίς JavaScript). Οι ίδιοι κανόνες δύο φορές — ένα media query δεν
         ενώνεται με κλάση σε έναν επιλογέα. */
      .page-head.is-stacked { grid-template-columns: auto 1fr auto; }
      .page-head.is-stacked > .page-title { grid-column: 1 / -1; }
      .page-head.is-stacked > .page-head-start { grid-row: 2; grid-column: 1; }
      .page-head.is-stacked > .page-head-end { grid-row: 2; grid-column: 3; }
      .page-head.is-stacked:not(:has(> .page-head-start)) > .page-head-end { grid-column: 1 / -1; justify-self: center; justify-content: center; }
      @media (max-width: 575.98px) {
        .page-head { grid-template-columns: auto 1fr auto; }
        .page-head > .page-title { grid-column: 1 / -1; }
        .page-head-start { grid-row: 2; grid-column: 1; }
        .page-head-end { grid-row: 2; grid-column: 3; }
        /* Μόνο ενέργειες, χωρίς «Πίσω»: στο κέντρο, κάτω από τον τίτλο. */
        .page-head:not(:has(> .page-head-start)) > .page-head-end { grid-column: 1 / -1; justify-self: center; justify-content: center; }
      }

      /* Πιο έντονο εικονίδιο (αίτημα 17/09/2026: το `bi-plus-lg` είναι λεπτό).
         Περίγραμμα στο ίδιο χρώμα αντί για άλλο εικονίδιο: ο τίτλος φορά το
         **ίδιο** εικονίδιο με τη μπάρα (tests/test_sidebar_nav.py). */
      .bi-bold::before { -webkit-text-stroke: .07em currentColor; }

      /* ─────────────────────────────────────────────────────────────
         NAV TABS — ανενεργά: κανονικό χρώμα body, χωρίς μπλε
         ενεργό: bold, χωρίς έξτρα χρώμα
      ──────────────────────────────────────────────────────────────── */
      .nav-tabs .nav-link {
        color: var(--bs-body-color);
        opacity: .6;
        font-weight: 400;
      }
      .nav-tabs .nav-link:hover,
      .nav-tabs .nav-link:focus {
        color: var(--bs-body-color);
        opacity: .85;
      }
      .nav-tabs .nav-link.active {
        color: var(--bs-body-color);
        font-weight: 700;
        opacity: 1;
      }

      /* ─────────────────────────────────────────────────────────────
         PAGE TOOLBAR
         Χρήση:
         <div class="page-toolbar">
           <div class="page-toolbar__left">…</div>
           <div class="page-toolbar__right">…</div>
         </div>
      ──────────────────────────────────────────────────────────────── */
      .page-toolbar {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: .75rem;
        margin-bottom: 1rem;
        flex-wrap: wrap;
      }
      .page-toolbar__left  { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }
      .page-toolbar__right { display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; }

      /* ─────────────────────────────────────────────────────────────
         SEARCH INPUT  (μέσα στο toolbar)
         Χρήση: <input class="page-search" placeholder="Αναζήτηση…">
         Ο φακός έρχεται από το `.gary-search` παρακάτω — **όχι** από το
         placeholder: ένα 🔍 μέσα σε msgid ταξιδεύει σε έξι καταλόγους.
      ──────────────────────────────────────────────────────────────── */
      .page-search {
        min-width: 200px;
        max-width: 280px;
        font-size: .875rem;
      }

      /* ─────────────────────────────────────────────────────────────
         BUTTON CONVENTIONS
         Primary action:   btn btn-primary   btn-sm
         Secondary action: btn btn-outline-secondary btn-sm
         Danger action:    btn btn-outline-danger    btn-sm
      ──────────────────────────────────────────────────────────────── */

      /* ─────────────────────────────────────────────────────────────
         PAGE SECTION HEADER  (εντός card, πριν από υποενότητα)
         Χρήση: <div class="page-section-header">Τίτλος ενότητας</div>
      ──────────────────────────────────────────────────────────────── */
      .page-section-header {
        font-size: .7rem;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: .07em;
        color: var(--bs-secondary-color);
        margin-bottom: .5rem;
      }

      /* ─────────────────────────────────────────────────────────────
         RESPONSIVE — mobile
      ──────────────────────────────────────────────────────────────── */
      @media (max-width: 576px) {
        .page-card { padding: 1rem; margin: .75rem; border-radius: .5rem; }
        .page-frame { margin-top: .75rem; margin-bottom: .75rem; }
        .page-title { font-size: 1.4rem; margin-bottom: 1rem; }
        .page-search { min-width: 140px; max-width: 100%; }
        .page-toolbar { flex-direction: column; align-items: stretch; }
        .page-toolbar__right { justify-content: flex-end; }
      }
        /* ── Global ───────────────────────────────────────────────── */
        /* Κρατά δεσμευμένο χώρο για scrollbar ώστε το toggle του modal-open
           να μην προκαλεί layout shift (flash) κατά το άνοιγμα/κλείσιμο modals */
        html {
            scrollbar-gutter: stable;
            background-color: #e8eef6; /* ενιαίο χρώμα — χωρίς gradient για consistent scroll */
            overflow-x: hidden; /* αποτρέπει τυχόν στοιχείο που ξεχειλίζει οριζόντια από το να
                                    πλατύνει το viewport (π.χ. έσπρωχνε το fixed bottom nav εκτός θέας) */
        }

        /* scrollbar-gutter:stable δεσμεύει ήδη τον χώρο — ακυρώνουμε το Bootstrap padding-right
           που προκαλεί layout shift (flash/reflow) κατά το άνοιγμα modal */
        body.modal-open { padding-right: 0 !important; }

        /* ── Κολλητά στοιχεία πίσω από ανοιχτό modal ──
           Αναφορά ιδιοκτήτη 16/09/2026: κυλισμένη Λίστα, ανοίγει modal, και η
           γραμμή εργαλείων/κεφαλίδα «εξαφανίζονται από το φόντο». Μετρημένο: η
           γραμμή από top 0 πήγαινε στο **−1349** όσο ήταν ανοιχτό το modal.
           Το Bootstrap κλειδώνει την κύλιση με `overflow: hidden` στο **body**.
           Επειδή το <html> δεν έχει `overflow: visible` (βλ. παραπάνω), το
           overflow του body ΔΕΝ περνά στο viewport: το body γίνεται δικό του,
           μη κυλισμένο πλαίσιο κύλισης, και κάθε `sticky` μέσα του πέφτει στη
           φυσική του θέση. Ίδια ρίζα με την πάνω μπάρα του κινητού (έγινε fixed).
           Το κλείδωμα γίνεται στο <html> — το ίδιο το viewport, που μένει στην
           ίδια θέση κύλισης — και το body μένει `visible`. */
        body.modal-open { overflow: visible !important; }
        html:has(> body.modal-open) { overflow-y: hidden !important; }

        body {
            background-color: #ffffff;
            font-family: 'Poppins', sans-serif;
            min-height: 100vh;
            margin: 0;
            display: flex;
        }

        /* ── Sidebar ──────────────────────────────────────────────── */
        /* Πλάτος μπάρας ως μεταβλητή: το διαβάζουν το `.main-wrapper` και η
           κολλητή μπάρα εργαλείων της λίστας. Η ράγα και η κρυφή μορφή το
           αλλάζουν παρακάτω, μόνο στον υπολογιστή. */
        :root { --gary-sidebar-w: 220px; }

        .sidebar {
            width: 220px;
            min-height: 100vh;
            /* Συμπαγές (σχέδιο 1b). Το gradient από κρεμ υπήρχε για το τεντωμένο
               λογότυπο, που έφυγε. ⚠️ Και **χωρίς `backdrop-filter`**: κάνει την
               μπάρα containing block για κάθε `position: fixed` μέσα της, οπότε
               τα αναδυόμενα πάνελ της ράγας θα κόβονταν στα 68px της. */
            background: #1e3a28;
            position: fixed;
            left: 0;
            top: 0;
            bottom: 0;
            z-index: 1050;
            display: flex;
            flex-direction: column;
            transition: transform 0.28s ease, width 0.28s ease;
            overflow-y: auto;
            overflow-x: hidden;
            scrollbar-width: thin;
            scrollbar-color: rgba(255,255,255,.22) transparent;
        }

        /* ── Κεφαλίδα (σχέδιο 1b, μικρή εκδοχή) ── */
        .sb-head {
            padding: 10px 8px 13px;
            display: flex; flex-direction: column; gap: 7px;
            border-bottom: 1px solid rgba(255,255,255,.09);
        }
        .sb-brand-row { display: flex; align-items: center; gap: 6px; }
        .sb-brand { display: flex; align-items: center; gap: 6px; text-decoration: none; min-width: 0; }
        .sb-tile {
            width: 44px; height: 44px; border-radius: 12px; background: #faf8f4;
            display: flex; align-items: center; justify-content: center; flex-shrink: 0;
        }
        .sb-tile img { width: 33px; height: auto; display: block; }
        .sb-wordmark { height: 35px; width: auto; display: block; }
        .sb-tagline { width: 146px; height: auto; opacity: .85; align-self: flex-start; display: block; }
        #sidebarCollapseBtn { margin-left: auto; }

        /* ── Κορυφή που δεν κυλά ──
           `sticky` μέσα στη μπάρα (που είναι το scroll container). Τα
           καρφιτσωμένα κολλούν κάτω από την κορυφή· το ύψος της το μετρά η JS
           (`--sb-top-h`), με προεπιλογή το μετρημένο της ανοιχτής μορφής. */
        .sb-top { position: sticky; top: 0; z-index: 6; background: #1e3a28; flex-shrink: 0; }
        #sbPins {
            position: sticky; top: var(--sb-top-h, 131px); z-index: 5;
            background: #1e3a28; padding-bottom: 6px;
            box-shadow: 0 1px 0 rgba(255,255,255,.09);
        }

        /* ── Αναζήτηση σελίδας ── */
        .sb-search {
            margin: 10px 10px 2px; height: 32px; padding: 0 9px;
            display: flex; align-items: center; gap: 7px; flex-shrink: 0;
            background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.14); border-radius: 9px;
        }
        .sb-search:focus-within { border-color: rgba(255,255,255,.4); }
        .sb-search > .bi { font-size: 11px; color: rgba(255,255,255,.55); }
        .sb-search input {
            flex: 1; min-width: 0; height: 100%; padding: 0;
            background: transparent; border: 0; outline: none; color: #fff; font-size: 12px;
        }
        .sb-search input::placeholder { color: rgba(255,255,255,.55); }
        .sb-search input::-webkit-search-cancel-button { filter: invert(1); opacity: .6; }
        .sb-kbd {
            font-family: inherit; font-size: 9.5px; line-height: 1.2; white-space: nowrap;
            color: rgba(255,255,255,.6); background: transparent;
            border: 1px solid rgba(255,255,255,.2); border-radius: 4px; padding: 1px 4px;
        }

        .sidebar-nav {
            /* 1 0 auto, όχι σκέτο «1»: το `flex: 1` σημαίνει flex-basis:0 με
               flex-shrink:1, οπότε σε κοντή οθόνη το nav συρρικνωνόταν κάτω από
               το ύψος του περιεχομένου του. Το περιεχόμενο ξεχείλιζε έξω από το
               κουτί του, το scrollHeight του sidebar δεν το κάλυπτε, και το
               .sidebar-footer έπεφτε εκτός κυλιόμενης έκτασης: σε ύψος 620px η
               μέγιστη κύλιση ήταν 314 ενώ το κουμπί θέματος ήθελε ~540 —
               «Φωτεινό/Σκοτεινό» και «Αποσύνδεση» ήταν απλησίαστα. */
            flex: 1 0 auto;
            padding: 0.6rem 0;
        }

        .sidebar-section {
            padding: 0.9rem 1.2rem 0.3rem;
            font-size: 0.65rem;
            text-transform: uppercase;
            letter-spacing: 0.1em;
            color: rgba(255,255,255,0.65);
            font-weight: 600;
        }

        .sidebar-link {
            display: flex;
            align-items: center;
            gap: 0.7rem;
            padding: 0.6rem 1.2rem;
            color: rgba(255,255,255,0.92);
            text-decoration: none;
            font-size: 0.875rem;
            position: relative;
            transition: background 0.15s, color 0.15s;
            border-left: 3px solid transparent;
        }
        .sidebar-link:hover {
            background: rgba(255,255,255,0.07);
            color: #fff;
        }
        /* Πορτοκαλί από το ίδιο το λογότυπο. Το προηγούμενο #4a9eff ήταν ένα
           μπλε που δεν υπάρχει πουθενά αλλού στο brand. */
        .sidebar-link.active {
            /* Διακριτικό: η αριστερή γραμμή κάνει τη δουλειά της ένδειξης, το
               φόντο απλώς τη συνοδεύει. Στο 16% διάβαζε ως πλακάκι. */
            background: rgba(224,122,47,0.09);
            color: #fff;
            border-left-color: #e07a2f;
            font-weight: 600;
        }
        .sidebar-link .badge-notify {
            margin-left: auto;
            background: var(--bs-danger);
            color: #fff;
            font-size: 0.7rem;
            padding: 0.2em 0.5em;
            border-radius: 1rem;
            font-weight: 700;
            line-height: 1;
        }
        /* Τα εικονίδια είναι Bootstrap Icons (γραμματοσειρά), όχι emoji: ένα
           οικογενειακό σχέδιο, βάφονται με το currentColor και ευθυγραμμίζονται
           μεταξύ τους. Το line-height:1 τα κρατά κεντραρισμένα στη γραμμή. */
        .sidebar-icon {
            width: 1.25em;
            text-align: center;
            flex-shrink: 0;
            font-size: 1.05rem;
            line-height: 1;
        }


        .sidebar-divider {
            border-top: 1px solid rgba(255,255,255,0.08);
            margin: 0.4rem 0;
        }

        /* ── Ανοιχτή μπάρα: σελίδες ως πλακίδια (σχέδιο 3a) ──
           Οι κανόνες αφορούν **μόνο** το `.sidebar-nav`· το υποσέλιδο κρατά την
           αριστερή γραμμή του. */
        .sidebar-nav { padding: 4px 0 8px; }
        .sidebar-nav .sb-items { padding: 0 8px; display: flex; flex-direction: column; gap: 3px; }
        .sidebar-nav .sidebar-section { padding: 12px 4px 5px; font-size: 10px; }
        .sb-rail-btn, .sb-rail-only { display: none; }
        .sb-row { position: relative; }
        .sidebar-nav .sidebar-link {
            padding: 8px 10px; border-radius: 9px; border-left: 0;
            gap: 10px; font-size: 13px; min-height: 32px;
        }
        .sidebar-nav .sidebar-link .sidebar-icon { font-size: 14px; }
        .sidebar-nav .sidebar-link:hover { background: rgba(255,255,255,.08); color: #fff; }
        .sidebar-nav .sidebar-link.active { background: #e07a2f; color: #fff; font-weight: 600; }
        .sidebar-nav .sidebar-link.active .badge-notify { background: rgba(0,0,0,.25); }

        /* Καρφίτσα: δεξιά στη σειρά, σε hover/εστίαση (απόφαση ιδιοκτήτη
           16/09/2026). Όσο φαίνεται, ο αριθμός της σειράς κρύβεται από κάτω της. */
        .sb-pin {
            position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
            width: 26px; height: 26px; padding: 0; border: 0; border-radius: 7px;
            display: flex; align-items: center; justify-content: center;
            background: transparent; color: rgba(255,255,255,.75); font-size: 12px;
            opacity: 0; transition: opacity .15s, background .15s;
        }
        .sb-row:hover .sb-pin, .sb-pin:focus-visible { opacity: 1; }
        /* Αδιαφανές φόντο, ίδιο με τη σειρά σε hover: η καρφίτσα σκεπάζει το
           τέλος ενός μακριού ονόματος αντί να του κρατά μόνιμα 34px — με αυτά
           το «Προσθήκη αντικειμένου» έσπαγε σε δύο γραμμές. */
        .sb-row:hover .sb-pin, .sb-pin:focus-visible { background: color-mix(in srgb, #1e3a28 92%, #fff); }
        .sb-row:hover .sidebar-link.active + .sb-pin { background: #e07a2f; color: #fff; }
        .sb-pin:hover, .sb-row:hover .sb-pin:hover { background: color-mix(in srgb, #1e3a28 80%, #fff); color: #fff; }
        .sb-row:hover .sidebar-link.active + .sb-pin:hover { background: color-mix(in srgb, #e07a2f 80%, #000); }
        .sb-pin:focus-visible { outline: 2px solid #e07a2f; outline-offset: 1px; }
        .sb-row:hover .badge-notify, .sb-row:focus-within .badge-notify { visibility: hidden; }
        /* Χωρίς ποντίκι (αφή) δεν υπάρχει hover: η καρφίτσα μένει ορατή, αχνή. */
        @media (hover: none) {
            .sb-pin { opacity: .6; }
            .sb-row .badge-notify { visibility: visible !important; margin-right: 22px; }
        }

        /* `.sb-group` μπροστά: το `is-pinned` κρύβει τη σελίδα από την ενότητά
           της, ποτέ από τη λίστα Καρφιτσωμένα. */
        .sb-group.is-empty, .sb-group.sb-beyond, .sb-group .sb-row.is-pinned { display: none; }
        /* «Περισσότερα» ανοιχτό: κλάση στο <html> από το <head>, πριν το paint. */
        html.sb-more-expanded .sb-group.sb-beyond:not(.is-empty) { display: block; }
        .sb-more-lbl-open { display: none; }
        html.sb-more-expanded .sb-more .sb-more-lbl-closed { display: none; }
        html.sb-more-expanded .sb-more .sb-more-lbl-open { display: inline; }
        .sidebar.is-searching #sbPins,
        .sidebar.is-searching .sb-group,
        .sidebar.is-searching #sbMore { display: none !important; }

        /* Σειρά καρφιτσωμένων με σύρσιμο (sidebar_nav.js). */
        #sbPinList .sidebar-link { -webkit-user-drag: none; user-select: none; }
        #sbPinList .sidebar-icon { touch-action: none; }
        /* Κέρσορας πάνω-κάτω σε ΟΛΗ τη σελίδα όσο σέρνεται: ο δείκτης βγαίνει
           εύκολα από τη λίστα, και ένα χεράκι-σύνδεσμος εκεί λέει «κλικ». */
        html.sb-sorting, html.sb-sorting * { cursor: ns-resize !important; user-select: none !important; }
        #sbPinList.is-sorting .sb-pin { opacity: 0 !important; }
        /* Η θέση από την οποία σηκώθηκε: αχνή, όχι κενή — φαίνεται από πού ξεκίνησε. */
        #sbPinList .sb-row.is-drag-source { opacity: .35; }
        /* Το αιωρούμενο αντίγραφο. */
        /* Ημιδιαφανές (αίτημα ιδιοκτήτη): αδιαφανές έκρυβε ό,τι είχε από κάτω —
           και τη γραμμή απόθεσης. */
        .sb-drag-ghost {
            position: fixed; z-index: 1080; margin: 0; pointer-events: none;
            transform: scale(1.03); transform-origin: left center;
            opacity: .6;
        }
        .sb-drag-ghost .sidebar-link {
            background: color-mix(in srgb, #1e3a28 80%, #fff);
            color: #fff;
            box-shadow: 0 10px 24px rgba(0,0,0,.45), 0 0 0 1px rgba(255,255,255,.18);
        }
        .sb-drag-ghost .sidebar-link.active { background: #e07a2f; }
        .sb-drag-ghost .sb-pin { display: none; }
        .sb-drag-ghost .badge-notify { visibility: visible !important; }
        /* Γραμμή απόθεσης, με κουκκίδα στην αρχή. */
        /* Πάνω από το αιωρούμενο: η γραμμή είναι αυτό που λέει πού θα πέσει,
           και δεν πρέπει να κρύβεται ποτέ από κάτω του. */
        .sb-drop-line {
            position: fixed; z-index: 1081; height: 2px; border-radius: 2px;
            background: #e07a2f; pointer-events: none;
        }
        .sb-drop-line::before {
            content: ''; position: absolute; left: -4px; top: -3px;
            width: 8px; height: 8px; border-radius: 50%; background: #e07a2f;
        }
        .sb-drop-line[hidden] { display: none; }
        @media (prefers-reduced-motion: reduce) { .sb-drag-ghost { transform: none; } }

        .sb-more {
            margin: 12px 8px 0; padding: 7px 10px; width: calc(100% - 16px);
            display: flex; align-items: center; gap: 10px;
            background: transparent; border: 0; border-radius: 9px; text-align: left;
            color: rgba(255,255,255,.6); font-size: 12.5px;
        }
        .sb-more:hover { background: rgba(255,255,255,.08); color: #fff; }

        /* Αποτελέσματα: σελίδα και από κάτω η ενότητα — ποτέ στην ίδια γραμμή,
           τρώει το πλάτος και κόβει τα μεγάλα ονόματα. */
        .sb-result {
            display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: 9px;
            color: rgba(255,255,255,.9); text-decoration: none;
        }
        .sb-result .sidebar-icon { font-size: 14px; }
        .sb-result:hover, .sb-result.is-selected { background: rgba(255,255,255,.1); color: #fff; }
        .sb-result.active { background: #e07a2f; color: #fff; }
        .sb-result.active.is-selected { box-shadow: inset 0 0 0 2px rgba(255,255,255,.55); }
        .sb-r-text { flex: 1; min-width: 0; display: flex; flex-direction: column; }
        .sb-r-title, .sb-r-sec { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .sb-r-title { font-size: 12.5px; line-height: 1.3; }
        .sb-r-sec { font-size: 9.5px; color: rgba(255,255,255,.55); }
        .sb-result.active .sb-r-sec { color: rgba(255,255,255,.8); }
        .sb-no-results { padding: 6px 12px; font-size: 12px; color: rgba(255,255,255,.6); }

        .sidebar :focus-visible { outline: 2px solid #e07a2f; outline-offset: 2px; }

        /* ── Ράγα 68px και κρυφή μορφή: ΜΟΝΟ στον υπολογιστή ──
           Το κριτήριο είναι το **ακριβές αντίστροφο** του κινητού παρακάτω
           («στενή οθόνη ή κινητό γυρισμένο πλάγια»). Με σκέτο `min-width` ένα
           κινητό σε landscape (~844×390) θα έπαιρνε ράγα μέσα στο off-canvas. */
        @media (min-width: 769px) and (orientation: portrait),
               (min-width: 769px) and (min-height: 501px) {
            html[data-sb="rail"] { --gary-sidebar-w: 68px; }
            html[data-sb="hidden"] { --gary-sidebar-w: 0px; }

            html[data-sb="hidden"] .sidebar { transform: translateX(-100%); }
            html[data-sb="hidden"] .sidebar-show-pill { display: block; }

            html[data-sb="rail"] .sidebar {
                width: 68px; align-items: center; padding: 0 0 12px;
            }
            html[data-sb="rail"] .sb-top {
                width: 100%; padding-top: 10px;
                display: flex; flex-direction: column; align-items: center;
            }
            html[data-sb="rail"] .sb-open-only,
            html[data-sb="rail"] .sb-wordmark,
            html[data-sb="rail"] .sb-tagline,
            html[data-sb="rail"] #sbPins,
            html[data-sb="rail"] #sbResults,
            html[data-sb="rail"] #sbMore { display: none !important; }
            html[data-sb="rail"] .sb-head { padding: 0; border: 0; margin-bottom: 6px; }
            html[data-sb="rail"] .sb-rail-only { display: flex; }

            .sb-rail-expand {
                width: 40px; height: 28px; margin-bottom: 6px; flex-shrink: 0;
                align-items: center; justify-content: center;
                background: rgba(255,255,255,.08); border: 1px solid rgba(255,255,255,.16);
                border-radius: 8px; color: rgba(255,255,255,.85); font-size: 13px;
                transition: background .15s, color .15s;
            }
            .sb-rail-expand:hover { background: rgba(255,255,255,.2); color: #fff; }

            html[data-sb="rail"] .sidebar-nav {
                padding: 0; display: flex; flex-direction: column; align-items: center; gap: 4px;
            }
            html[data-sb="rail"] .sb-rail-btn {
                display: flex; align-items: center; justify-content: center; position: relative;
                width: 40px; height: 40px; flex-shrink: 0; padding: 0;
                border: 0; border-radius: 11px; background: transparent;
                color: rgba(255,255,255,.7); font-size: 17px;
                transition: background .15s, color .15s;
            }
            html[data-sb="rail"] .sb-rail-btn:hover,
            html[data-sb="rail"] .sb-rail-btn[aria-expanded="true"] { background: rgba(255,255,255,.14); color: #fff; }
            html[data-sb="rail"] .sb-rail-btn.is-current { background: rgba(224,122,47,.16); color: #fff; }
            html[data-sb="rail"] .sb-rail-btn.is-current::before {
                content: ''; position: absolute; left: -10px; top: 11px;
                width: 3px; height: 18px; border-radius: 2px; background: #e07a2f;
            }
            /* Στη ράγα δεν χωρά αριθμός — μόνο τελεία· ο αριθμός είναι στο πάνελ. */
            .sb-dot {
                position: absolute; top: 5px; right: 5px; width: 7px; height: 7px; border-radius: 50%;
                background: var(--bs-danger); border: 1.5px solid #1e3a28; pointer-events: none;
            }
            .sb-dot[hidden] { display: none; }

            /* Στη ράγα οι ενότητες είναι απλώς κοντέινερ: καμία δεν κρύβεται
               λόγω καρφιτσώματος ή «Περισσότερα». */
            html[data-sb="rail"] .sb-group,
            html[data-sb="rail"] .sb-group.is-empty,
            html[data-sb="rail"] .sb-group.sb-beyond { display: block; }
            html[data-sb="rail"] .sb-row.is-pinned { display: block; }
            html[data-sb="rail"] .sb-pin { display: none; }

            /* Αναδυόμενο πάνελ: το ίδιο `.sb-items` της ανοιχτής μπάρας. `fixed`,
               γιατί η μπάρα κυλά (`overflow-y: auto`) και θα το έκοβε. Το `top`
               το βάζει η JS από τη θέση του εικονιδίου — όχι σταθερός τύπος. */
            html[data-sb="rail"] .sb-group > .sb-items {
                display: none; position: fixed; left: 68px; width: 210px; z-index: 1070;
                padding: 11px 0; gap: 0;
                /* Ένα σκαλί πιο βαθύ από τη μπάρα, χωρίς νέο καρφωτό χρώμα. */
                background: color-mix(in srgb, #1e3a28 78%, #000);
                border: 1px solid rgba(255,255,255,.12); border-left: 0;
                border-radius: 0 12px 12px 0;
                box-shadow: 12px 10px 30px rgba(10,20,14,.35);
            }
            html[data-sb="rail"] .sb-group.is-open > .sb-items { display: flex; animation: sbFlyIn 120ms ease-out; }
            html[data-sb="rail"] .sb-items .sidebar-section { padding: 4px 14px 8px; font-size: 10px; }
            html[data-sb="rail"] .sb-items .sidebar-link {
                padding: 8px 14px 8px 11px; min-height: 0; border-radius: 0; gap: 9px;
                border-left: 3px solid transparent; color: rgba(255,255,255,.9); font-weight: 400;
            }
            html[data-sb="rail"] .sb-items .sidebar-link .sidebar-icon { font-size: 13px; opacity: .8; }
            html[data-sb="rail"] .sb-items .sidebar-link:hover { background: rgba(255,255,255,.07); }
            html[data-sb="rail"] .sb-items .sidebar-link.active {
                background: rgba(224,122,47,.14); border-left-color: #e07a2f; color: #fff; font-weight: 600;
            }
            html[data-sb="rail"] .sb-items .sidebar-link.active .badge-notify { background: var(--bs-danger); }
            html[data-sb="rail"] .sb-row:hover .badge-notify { visibility: visible; }
            @keyframes sbFlyIn { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }

            /* Στη ράγα κολλά πάντα κάτω (αίτημα 17/09/2026): το ελάχιστο
               περιεχόμενό της (~486px) χωρά σε κάθε ύψος αυτής της μορφής. */
            html[data-sb="rail"] .sb-rail-foot {
                margin-top: auto; padding-top: 8px; flex-direction: column; align-items: center; gap: 6px;
                position: sticky; bottom: 0; z-index: 6; width: 100%; background: #1e3a28;
            }
            html[data-sb="rail"] .sb-rail-foot .sb-rail-btn { font-size: 16px; }
            html[data-sb="rail"] .sb-rail-foot .sb-rail-btn:hover { background: rgba(255,255,255,.1); }
            html[data-sb="rail"] .sb-rail-foot .sb-rail-small { height: 28px; font-size: 13px; }
            .sidebar .sb-rail-foot .gary-net-chip { margin: 0; padding: .15rem .35rem; }
            .sb-avatar-btn {
                width: 40px; height: 40px; padding: 0; border: 0; border-radius: 11px; background: transparent;
                display: flex; align-items: center; justify-content: center; position: relative;
            }
            .sb-avatar-btn:hover, .sb-avatar-btn[aria-expanded="true"] { background: rgba(255,255,255,.1); }
            .sb-avatar {
                width: 28px; height: 28px; border-radius: 50%; overflow: hidden;
                background: var(--gary-primary); color: #fff; font-size: 12px; font-weight: 700;
                display: flex; align-items: center; justify-content: center;
            }
            .sb-avatar img { width: 100%; height: 100%; object-fit: cover; }
            .sb-avatar-btn .sb-dot { top: 4px; right: 4px; }

            /* Το υποσέλιδο γίνεται πάνελ πάνω από το αρχικό. Χωρίς `overflow`:
               η λίστα γλωσσών είναι dropdown και θα κοβόταν. */
            html[data-sb="rail"] .sidebar-footer {
                display: none; position: fixed; left: 68px; bottom: 12px; width: 230px; z-index: 1070;
                background: color-mix(in srgb, #1e3a28 78%, #000);
                border: 1px solid rgba(255,255,255,.12); border-left: 0; border-radius: 0 12px 12px 0;
                box-shadow: 12px 10px 30px rgba(10,20,14,.35);
            }
            html[data-sb="rail"] .sidebar-footer.is-open { display: block; animation: sbFlyIn 120ms ease-out; }
        }
        @media (prefers-reduced-motion: reduce) {
            .sidebar, .main-wrapper { transition: none !important; }
            .sb-items, .sidebar-footer { animation: none !important; }
        }

        .sidebar-footer {
            border-top: 1px solid rgba(255,255,255,0.08);
            padding: 0.4rem 0 0.6rem;
        }
        /* ── Κάτω μέρος που δεν κυλά ── (αίτημα 17/09/2026)
           Αντίστοιχο του `.sb-top`. Την κλάση τη βάζει το `sidebar_nav.js`
           μόνο όταν μένει χώρος για τις σελίδες. ⚠️ Ειδικότητα (0,2,0),
           **κάτω** από το `html[data-sb="rail"] .sidebar-footer` (0,2,1): στη
           ράγα το υποσέλιδο είναι αναδυόμενο πάνελ και πρέπει να κερδίζει εκείνο. */
        .sb-foot-stick > .sidebar-footer {
            position: sticky; bottom: 0; z-index: 6;
            background: #1e3a28;
            box-shadow: 0 -1px 0 rgba(255,255,255,.09);
        }
        /* Η αναζήτηση κάνει `scrollIntoView` — ένα αποτέλεσμα να μην κρύβεται από κάτω του. */
        .sb-foot-stick { scroll-padding-bottom: var(--sb-foot-h, 0px); }
        .sidebar-footer .sidebar-link.logout-link {
            color: rgba(255,100,100,0.8);
        }
        .sidebar-footer .sidebar-link.logout-link:hover {
            color: #ff6b6b;
            background: rgba(var(--bs-danger-rgb), 0.1);
        }

        /* ── Sidebar toggle button (κλείσιμο — μέσα στο sidebar) ──── */
        .sidebar-toggle-btn {
            display: flex; align-items: center; justify-content: center;
            width: 28px; height: 28px;
            background: rgba(255,255,255,.12);
            border: 1px solid rgba(255,255,255,.18);
            border-radius: .4rem;
            color: rgba(255,255,255,.85);
            cursor: pointer;
            font-size: .85rem;
            line-height: 1;
            flex-shrink: 0;
            transition: background .15s;
        }
        .sidebar-toggle-btn:hover { background: rgba(255,255,255,.22); color:#fff; }

        /* ── "Άνοιξε το sidebar" floating pill όταν είναι κρυφό ──── */
        .sidebar-show-pill {
            position: fixed;
            left: 0; top: 50%;
            transform: translateY(-50%);
            z-index: 1055;
            background: var(--bs-body-bg);
            border: 1px solid var(--bs-border-color);
            border-left: none;
            border-radius: 0 .5rem .5rem 0;
            padding: .55rem .45rem;
            cursor: pointer;
            font-size: .85rem;
            line-height: 1;
            box-shadow: 2px 0 8px rgba(0,0,0,.12);
            color: var(--bs-body-color);
            display: none;
        }
        .sidebar-show-pill:hover { background: var(--bs-tertiary-bg); }

        /* ── Κρυφή μορφή ──────────────────────────────────────────────
           Ήταν `body.sidebar-hidden`, μπαίνοντας από JS **μετά** τη φόρτωση —
           δηλαδή η μπάρα φαινόταν για ένα καρέ σε κάθε πλοήγηση. Πλέον
           `html[data-sb="hidden"]` από το <head>, στο μπλοκ υπολογιστή πιο πάνω. */
        /* Κρύψε pill σε mobile: εκεί η πλοήγηση γίνεται από την
           κάτω μπάρα, και η πλευρική ανοίγει ως συρτάρι. */
        /* ⚠️ **Και σε landscape κινητού, όχι μόνο σε στενή οθόνη.**
           Ένα κινητό γυρισμένο πλάγια γίνεται ~844px πλατύ — ξεπερνά το
           όριο των 768 — και επέστρεφε η διάταξη υπολογιστή: εμφανιζόταν η
           πλευρική μπάρα και εξαφανιζόταν η πάνω μπάρα, μέσα στην ίδια
           συσκευή, με μια περιστροφή (αναφορά χρήστη 03/09/2026).

           Το `max-height` είναι το κριτήριο που ξεχωρίζει «κινητό πλάγια»
           από «μικρό παράθυρο υπολογιστή»: ένα κινητό σε landscape έχει ύψος
           ~390–430px, ένα tablet ~820, ένας φορητός 700+. Το πλάτος μόνο του
           δεν μπορεί να τα ξεχωρίσει. */
        @media (max-width: 768px),
               (orientation: landscape) and (max-height: 500px) {
            .sidebar-show-pill { display: none !important; }
        }

        /* ── Main wrapper ─────────────────────────────────────────── */
        .main-wrapper {
            margin-left: var(--gary-sidebar-w);
            flex: 1;
            min-width: 0; /* flex items default σε min-width:auto — χωρίς αυτό, ένα φαρδύ
                              στοιχείο μέσα στο content-area αρνείται να μικρύνει και πλατύνει
                              όλο το body, σπρώχνοντας το fixed bottom nav εκτός οθόνης σε mobile */
            display: flex;
            flex-direction: column;
            min-height: 100vh;
            transition: margin-left .28s ease;
        }
        .main-wrapper.no-sidebar {
            margin-left: 0;
        }

        /* ── Μπάρα «εκτός σύνδεσης» ── (αίτημα 17/09/2026)
           `fixed` με `left: 0` και z-index 9998 πάνω από την πλευρική μπάρα
           (1050): μετρημένο, σκέπαζε τα πρώτα 68px της ράγας — το λογότυπο
           και το κουμπί ανοίγματος — ή όλα τα 220 της ανοιχτής μπάρας.
           Ξεκινά εκεί που ξεκινά το περιεχόμενο, με την ίδια μεταβλητή και
           την ίδια μετάβαση με το `.main-wrapper`.
           ⚠️ Μόνο όταν **υπάρχει** μπάρα: η μεταβλητή είναι 220px και στη
           σελίδα σύνδεσης, που δεν έχει. */
        #garyOfflineBanner { left: 0; transition: left .28s ease; }
        body:has(#sidebar) #garyOfflineBanner { left: var(--gary-sidebar-w); }
        @media (prefers-reduced-motion: reduce) { #garyOfflineBanner { transition: none; } }

        /* ── Μηνύματα (flash): αιωρούνται στον κενό χώρο, δεν σπρώχνουν ──
           Μέσα στη ροή, ένα μήνυμα 90px κατέβαζε τη σελίδα και, κλείνοντας,
           την ανέβαζε ξανά (αναφορά ιδιοκτήτη 14/09/2026). Σε desktop ο κενός
           χώρος πάνω από την κάρτα είναι 60px (padding του .content-area +
           margin της κάρτας)· ένα μήνυμα μίας γραμμής με τη μικρότερη
           εσωτερική απόσταση χωράει ολόκληρο εκεί.
           ⚠️ Η άγκυρα έχει **μηδενικό ύψος** και μένει στη θέση της μέσα στο
           flex του .main-wrapper: με `position: absolute` στο ίδιο το
           wrapper, το μήνυμα θα κάθονταν πάνω στη μπάρα των όρων χρήσης που
           προηγείται. Η σκιά λέει ότι αιωρείται όταν, σε στενή οθόνη ή με
           μεγάλο κείμενο, πέφτει πάνω στον τίτλο. */
        .gary-flash-anchor {
            position: relative;
            height: 0;
            z-index: 1020;
        }
        .gary-flash-stack {
            position: absolute;
            top: .5rem;
            left: 0;
            right: 0;
        }
        .gary-flash-stack .alert {
            padding-top: .55rem;
            padding-bottom: .55rem;
            margin-bottom: .5rem;
            box-shadow: 0 4px 14px rgba(0,0,0,.12);
        }
        .gary-flash-stack .alert-dismissible .btn-close {
            padding: .8rem 1rem;
        }

        .content-area {
            flex: 1;
            min-width: 0; /* βλ. σχόλιο στο .main-wrapper */
            padding: 2rem 1.5rem;
        }

        /* ── Ένδειξη δικτύου ──────────────────────────────────────
           Μόνιμη και μικρή: η μπάρα εξηγεί, αλλά κλείνει και φεύγει με το
           scroll· αυτό μένει. Σε αποθήκη με σήμα που πάει κι έρχεται, το «σε
           ουρά: N» είναι η μόνη απόδειξη ότι η δουλειά δεν χάθηκε. */
        .gary-net-chip {
            display: none; align-items: center; gap: .3rem;
            background: rgba(var(--bs-warning-rgb), .18); color: var(--bs-warning);
            border: 1px solid rgba(var(--bs-warning-rgb), .45);
            border-radius: 999px; padding: .15rem .5rem;
            font-size: .7rem; font-weight: 600; text-decoration: none;
            white-space: nowrap; flex-shrink: 0;
        }
        .gary-net-chip.is-visible { display: inline-flex; }
        .gary-net-chip .queue-count {
            background: var(--bs-warning); color: #1a1a2e;
            border-radius: 999px; padding: 0 .35rem; font-size: .65rem;
        }
        .sidebar .gary-net-chip { margin: .35rem 1rem; }

        /* ── Overlay (mobile) ─────────────────────────────────────── */
        .sidebar-overlay {
            display: none;
            position: fixed;
            inset: 0;
            background: rgba(0,0,0,0.45);
            z-index: 1040;
        }

        /* ── Responsive ───────────────────────────────────────────── */
        /* ⚠️ **Και σε landscape κινητού, όχι μόνο σε στενή οθόνη.**
           Ένα κινητό γυρισμένο πλάγια γίνεται ~844px πλατύ — ξεπερνά το
           όριο των 768 — και επέστρεφε η διάταξη υπολογιστή: εμφανιζόταν η
           πλευρική μπάρα και εξαφανιζόταν η πάνω μπάρα, μέσα στην ίδια
           συσκευή, με μια περιστροφή (αναφορά χρήστη 03/09/2026).

           Το `max-height` είναι το κριτήριο που ξεχωρίζει «κινητό πλάγια»
           από «μικρό παράθυρο υπολογιστή»: ένα κινητό σε landscape έχει ύψος
           ~390–430px, ένα tablet ~820, ένας φορητός 700+. Το πλάτος μόνο του
           δεν μπορεί να τα ξεχωρίσει. */
        @media (max-width: 768px),
               (orientation: landscape) and (max-height: 500px) {
            .sidebar {
                transform: translateX(-100%);
            }
            .sidebar.sidebar-open {
                transform: translateX(0);
            }
            .sidebar-overlay.sidebar-open {
                display: block;
            }
            :root { --gary-sidebar-w: 0px; }
            .main-wrapper {
                margin-left: 0;
            }
            /* Εδώ ισχύει πάντα η ανοιχτή μορφή, ό,τι κι αν λέει το data-sb. */
            .sb-search input { font-size: 16px; }
            .content-area {
                padding: 1.25rem 1rem;
            }
        }

        /* ── Cards & components ───────────────────────────────────── */
        .card {
            border: none;
            border-radius: 1rem;
            box-shadow: 0 6px 16px rgba(0,0,0,0.1);
            transition: transform 0.2s ease, box-shadow 0.2s ease;
            background: rgba(255, 255, 255, 0.88);
            backdrop-filter: blur(5px);
        }
        .card:hover {
            transform: translateY(-3px);
            box-shadow: 0 12px 24px rgba(0,0,0,0.13);
        }
        .no-card-hover .card:hover {
            transform: none;
            box-shadow: 0 6px 16px rgba(0,0,0,0.1);
        }

        h2 { font-weight: 600; color: #2d3436; }
        label { font-weight: 500; }

        footer {
            background: rgba(255,255,255,0.6);
            text-align: center;
            padding: 0.9rem;
            font-size: 0.82rem;
            color: #888;
            border-top: 1px solid rgba(0,0,0,0.05);
        }
        /* ─────────────────────────────────────────────────────────────
           BACK TO TOP — with a ring showing how far down the page you are.
           Gary's green rather than the usual accent: it sits over content all
           day, so it should read as part of the chrome, not as an action.
           ───────────────────────────────────────────────────────────── */
        .back-to-top {
            position: fixed;
            right: 1.5rem;
            bottom: 1.5rem;
            width: 52px;
            height: 52px;
            padding: 0;
            border: 0;
            border-radius: 1rem;          /* rounded square, like the cards */
            background: #1e3a28;
            color: #fff;
            cursor: pointer;
            display: grid;
            place-items: center;
            box-shadow: 0 4px 14px rgba(0,0,0,.22);
            /* Hidden until you have scrolled enough for it to be worth offering */
            opacity: 0;
            visibility: hidden;
            transform: translateY(8px);
            transition: opacity .2s, transform .2s, visibility .2s;
            z-index: 1035;                /* under the toasts, over the content */
        }
        .back-to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
        .back-to-top:hover { background: #27503a; }
        .back-to-top:focus-visible { outline: 3px solid #7fb894; outline-offset: 2px; }

        /* Both SVGs share the cell created by `place-items: center`, so the
           arrow sits inside the ring without absolute positioning. */
        .back-to-top > * { grid-area: 1 / 1; }
        /* Geometry lives in the SVG attributes, not in CSS: `r`/`cx`/`cy` as CSS
           properties are not universally supported, and the viewBox scales the
           whole thing anyway — the mobile rule below only changes the box. */
        .btt-ring { width: 44px; height: 44px; transform: rotate(-90deg); }
        .btt-ring circle {
            fill: none;
            stroke-width: 3;
            stroke-linecap: round;
        }
        .btt-track { stroke: rgba(255,255,255,.28); }
        .btt-progress {
            stroke: #fff;
            /* 2πr for r=19. Set here so the ring is correct before any script
               runs; JS only moves the offset. */
            stroke-dasharray: 119.38;
            stroke-dashoffset: 119.38;
        }
        .btt-arrow { width: 20px; height: 20px; stroke: #fff; stroke-width: 2.5;
                     fill: none; stroke-linecap: round; stroke-linejoin: round; }

        /* The toast stacks live in the same corner. Lift them clear only while
           the button is actually showing, so nothing moves on short pages. */
        body.has-back-to-top #tourToastContainer { bottom: calc(1.2rem + 60px); }
        /* Σε κινητό ανεβαίνουν **και τα δύο**: το ύψος της μπάρας συν το
           κουμπί. Χωρίς αυτό, το `has-back-to-top` παραπάνω αντικαθιστά τον
           κανόνα της μπάρας και το toast ξαναπέφτει πάνω της. */
        @media (max-width: 767px) {
          body.has-back-to-top #tourToastContainer {
            bottom: calc(var(--gary-bottomnav-h, 76px) + 1.2rem + 60px + env(safe-area-inset-bottom, 0px));
          }
        }

        /* ⚠️ 767px, όχι 576px. Η μπάρα εμφανίζεται ως τα 767 — ανάμεσα στα
           577 και 767 το κουμπί καθόταν **πάνω** της. Ίδιο σφάλμα με τα
           μηνύματα, σε άλλο στοιχείο: βρέθηκε ψάχνοντας για εκείνο. */
        @media (max-width: 767px) {
            .back-to-top {
                right: 1rem;
                bottom: calc(var(--gary-bottomnav-h, 76px) + .75rem + env(safe-area-inset-bottom, 0px));
                width: 46px; height: 46px; border-radius: .85rem;
            }
            .btt-ring { width: 38px; height: 38px; }
            .btt-arrow { width: 17px; height: 17px; }
        }
        @media (prefers-reduced-motion: reduce) {
            .back-to-top { transition: none; }
        }

        footer a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
        footer a:hover { color: var(--bs-body-color); }
        /* The separator is a pseudo-element so it can disappear when the links
           drop onto their own line — a line starting with "·" reads as a typo. */
        .footer-legal::before { content: " · "; }
        @media (max-width: 480px) {
            .footer-legal { display: block; margin-top: .25rem; }
            .footer-legal::before { content: none; }
        }

        .list-group-item {
            border: none !important;
            border-bottom: 1px solid rgba(0,0,0,0.05) !important;
        }
        .list-group-item:hover { background-color: #f8f9fa; }

        /* Θέση κρατημένη για τη φωτογραφία του modal πληροφοριών.

           Το JSON του αντικειμένου έρχεται ολόκληρο πριν ανοίξει το modal· αυτό που
           αργεί είναι τα **bytes** της εικόνας. Ένα <img> χωρίς διαστάσεις πιάνει
           μηδέν ύψος μέχρι να φορτώσει, και μόλις φτάσει σπρώχνει το περιεχόμενο —
           σε κεντραρισμένο modal αυτό φαίνεται ως αναπήδηση ολόκληρου του παραθύρου
           (αναφορά χρήστη 20/08/2026, ~μισό δευτερόλεπτο).

           Το να περιμέναμε την εικόνα πριν δείξουμε το modal θα άλλαζε το πρόβλημα
           με χειρότερο: μισό δευτερόλεπτο όπου το πάτημα δεν κάνει τίποτα. Κρατάμε
           λοιπόν τον χώρο από την αρχή, όσο το ανώτατο ύψος που μπορεί να πιάσει.
           Το γκρι φόντο λέει «έρχεται εικόνα» και φεύγει μόλις φτάσει. */
        .gary-photo-slot {
          height: 300px;
          display: flex;
          align-items: center;
          justify-content: center;
          border-radius: .5rem;
          background: var(--bs-secondary-bg);
          transition: background-color .2s;
        }
        .gary-photo-slot.is-loaded { background: transparent; }
        .gary-photo-slot img {
          max-height: 100%;
          max-width: 100%;
          object-fit: contain;
          opacity: 0;
          transition: opacity .2s;
        }
        .gary-photo-slot.is-loaded img { opacity: 1; }

        /* ── z-index stack ────────────────────────────────────────── */
        /* ⚠️ Η τιμή έρχεται από **custom property**, που τη γράφει το
           `static/js/modal_stack.js` τη στιγμή του ανοίγματος: το νεότερο
           modal πάει πάντα πάνω από όσα είναι ήδη ανοιχτά. Μη βάζεις
           `style="z-index:…"` σε modal — το `!important` εδώ το σκοτώνει, και
           **έντεκα** τέτοια στο `index.html` ήταν νεκρά επί μήνες ενώ
           διάβαζαν σαν να δουλεύουν. Βάλε τιμή στο `--gary-z-modal` αν
           χρειαστεί ποτέ χειροκίνητη παρέκκλιση. */
        .modal         { z-index: var(--gary-z-modal, 6000) !important; }

        /* Το πλαίσιο των modal: πιο χοντρό και πιο σκούρο από το default.
           Το Bootstrap βάζει 1px σε πολύ χαμηλή αντίθεση, που πάνω από το
           ημιδιάφανο backdrop σχεδόν εξαφανίζεται — το παράθυρο δεν φαίνεται
           να έχει άκρη (αναφορά χρήστη 31/08/2026).

           ⚠️ Τα χρώματα βγαίνουν από **μεταβλητές θέματος**, όχι σκληρές τιμές:
           ένα σκέτο #ccc είναι αόρατο στο σκοτεινό θέμα και βαρύ στο φωτεινό.
           Το `--bs-border-color-translucent` ακολουθεί και τα δύο. */
        .modal-content {
          border-width: 2px;
          /* ⚠️ ΟΧΙ `--bs-border-color`: είναι #dee2e6, δηλαδή **ανοιχτότερο**
             από το default του Bootstrap για modal (rgba(0,0,0,.175)) — θα
             έκανε το πλαίσιο πιο αχνό ενώ ο σκοπός ήταν το αντίθετο.
             Μετρημένη αντίθεση προς το λευκό φόντο: #dee2e6 → 1.30,
             rgba(0,0,0,.32) → 2.30. */
          border-color: rgba(0, 0, 0, .32);
          /* Η σκιά κάνει τη δουλειά που δεν μπορεί να κάνει το πάχος μόνο του:
             ξεχωρίζει το παράθυρο από το περιεχόμενο πίσω του χωρίς να
             βαραίνει οπτικά. */
          box-shadow: 0 .75rem 2rem rgba(0, 0, 0, .28);
        }

        /* Το ίδιο πλαίσιο και στη μεγέθυνση φωτογραφίας (αίτημα 01/09/2026).

           ⚠️ Μπαίνει στην **εικόνα**, όχι στο `.modal-content`: εκείνο είναι
           επίτηδες `bg-transparent border-0 shadow-none`, ώστε να μη φαίνεται
           κουτί γύρω από μια φωτογραφία που έχει το δικό της σχήμα. Πλαίσιο
           στο διάφανο δοχείο θα ζωγράφιζε ορθογώνιο στον αέρα — γύρω από τον
           **χώρο** του modal, όχι γύρω από την εικόνα.

           ⚠️ Και `display: block`: μια `<img>` είναι inline, οπότε κληρονομεί
           το `line-height` και αφήνει λωρίδα κάτω από το πλαίσιο. */
        .gary-photo-frame {
          display: block;
          border: 2px solid rgba(0, 0, 0, .32);
          box-shadow: 0 .75rem 2rem rgba(0, 0, 0, .28);
        }
        [data-bs-theme="dark"] .gary-photo-frame {
          border-color: rgba(255, 255, 255, .28);
        }
        {# Εδώ ζούσε το `.gary-lightbox-close`. Έφυγε μαζί με το κουμπί του
           (02/09/2026): ο προβολέας κλείνει με πάτημα οπουδήποτε, οπότε το ×
           δεν πρόσθετε δρόμο — μόνο έκρυβε μέρος της φωτογραφίας. Νεκρό CSS
           δεν μένει «για παν ενδεχόμενο»: την επόμενη φορά διαβάζεται ως
           ενεργό και κάποιος χτίζει πάνω του. #}
        /* Οι εσωτερικοί διαχωριστές ακολουθούν, αλλιώς η κεφαλίδα και το
           υποσέλιδο μοιάζουν να επιπλέουν μέσα σε πιο έντονο πλαίσιο. */
        .modal-header, .modal-footer { border-color: var(--bs-border-color); }
        [data-bs-theme="dark"] .modal-content {
          /* Στο σκοτεινό η ίδια λογική αντίστροφα: μαύρο πάνω σε σκούρο είναι
             αόρατο, οπότε το πλαίσιο γίνεται φωτεινό. */
          border-color: rgba(255, 255, 255, .28);
          box-shadow: 0 .75rem 2rem rgba(0, 0, 0, .55);
        }

        /* Footer των δύο φορμών επεξεργασίας σε στενή οθόνη.
           Με την προεπιλογή του Bootstrap τα τρία κουμπιά τυλίγονταν μόνα τους
           και η «Αποθήκευση» έπεφτε στη δεύτερη γραμμή, στοιχισμένη αριστερά, 8px
           κάτω από το «Κλείσιμο» — γειτονιά που δεν την επέλεξε κανείς, με ύψος
           38px αντί για τα 48 των υπόλοιπων mobile μπαρών της εφαρμογής. */
        @media (max-width: 575.98px) {
          #editItemModal .modal-footer,
          #gItemFullEditModal .modal-footer {
            flex-direction: column;
            align-items: stretch;
            /* Κάθετο κενό μόνο — η οριζόντια απόσταση του ζεύγους μένει στο
               `gap-2` του markup. Μεγαλύτερο εδώ επίτηδες: από πάνω κάθεται το
               «Επαναφορά» και από κάτω η «Αποθήκευση». */
            gap: .75rem;
          }
          #editItemModal .modal-footer > *,
          #gItemFullEditModal .modal-footer > * { margin: 0; width: 100%; }
          /* 44px: ο χρήστης τα ήθελε λίγο χαμηλότερα από τα 48, και είναι
             ακόμα πάνω από το συνιστώμενο μέγεθος στόχου αφής. Ίδιο με τη
             σταθερή μπάρα του `/add`, ώστε οι δύο οθόνες να μοιάζουν. */
          #editItemModal .modal-footer .btn,
          #gItemFullEditModal .modal-footer .btn { min-height: 44px; }
          /* «Κλείσιμο» και «Επαναφορά» μοιράζονται τη δική τους γραμμή· η
             «Αποθήκευση» μένει τελευταία στο DOM, άρα κάτω-κάτω και ολόπλατη —
             εκεί που φτάνει ο αντίχειρας. */
          #editItemModal .modal-footer > div .btn,
          #gItemFullEditModal .modal-footer > div .btn { flex: 1 1 0; }
        }
        /* Η σκίαση ΠΟΛΛΑΠΛΑΣΙΑΖΕΤΑΙ: το `.modal-backdrop.show` του Bootstrap
           βάζει `opacity: var(--bs-backdrop-opacity)` = **0.5**, οπότε το άλφα
           εδώ δεν είναι το τελικό. 0.6 x 0.5 = **0,30 πραγματικό** — που είναι
           η προεπιλογή του Bootstrap. Ήταν 0.3, δηλαδή 0,15: μισή σκίαση, και
           διαβαζόταν ως «δεν υπάρχει καθόλου». Αν χρειαστεί ξανά ρύθμιση,
           γράψε τον στόχο και διαίρεσε δια 0,5 — μην αλλάξεις το `opacity`,
           γιατί εκείνο ελέγχει και τη μετάβαση εμφάνισης. */
        .modal-backdrop { z-index: 5500 !important; background-color: rgba(0,0,0,0.6) !important; transition: none !important; }
        .modal.fade .modal-dialog { transition: none !important; }

        /* Κάρτα email template: το σώμα κοβόταν με `max-height` στη μέση μιας
           γραμμής. Κόβεται πλέον σε ακέραιες γραμμές, και στο κινητό σε τρεις. */
        .tmpl-actions .btn { min-height: 34px; }
        .tmpl-body {
            white-space: pre-line; overflow: hidden;
            display: -webkit-box; -webkit-box-orient: vertical;
            -webkit-line-clamp: 4; line-clamp: 4;
        }
        @media (max-width: 767px) {
            /* Ονομασία και κουμπιά σε χωριστές γραμμές: το όνομα στριμωχνόταν σε
               τρεις λέξεις δίπλα σε τρία κουμπιά των 24px (αίτημα 16/09/2026). */
            .tmpl-head { flex-direction: column; align-items: stretch !important; gap: .5rem; }
            .tmpl-actions { display: grid !important; grid-template-columns: repeat(3, 1fr); gap: .4rem !important; }
            .tmpl-actions .btn { min-height: 40px; font-size: 1rem !important; padding: 0 !important; }
            .tmpl-body { -webkit-line-clamp: 3; line-clamp: 3; }
        }

        /* ── Καρτέλες σε πλέγμα δύο στηλών στο κινητό (`gary-tabs-grid`) ──
           Η διάταξη του Προφίλ, που άρεσε στον ιδιοκτήτη (15/09/2026) και ζητήθηκε
           για Απόθεμα, Κινήσεις & Ιστορικό, Στατιστικά και Ομάδα. Ζούσε μέσα στο
           profile.html· ένας ορισμός εδώ, αλλιώς πέντε αντίγραφα που αποκλίνουν.
           Κουμπιά 44px με περίγραμμα, η ενεργή γεμάτη· μονός αριθμός καρτελών
           αφήνει την τελευταία σε όλο το πλάτος.
           ⚠️ `!important` επίτηδες: κάθε σελίδα έχει ήδη δικό της στυλ καρτελών
           (υπογράμμιση στα Στατιστικά, οριζόντια κύλιση στο Απόθεμα). */
        @media (max-width: 767px) {
            ul.gary-tabs-grid {
                flex-wrap: wrap !important; overflow-x: visible !important;
                border-bottom: none !important; gap: .35rem;
                margin-bottom: .75rem !important; padding-bottom: 0 !important;
            }
            ul.gary-tabs-grid > .nav-item { flex: 1 1 calc(50% - .2rem); min-width: 0; }
            /* Μακρύ όνομα («Έχω μοιραστεί 1», «Χρόνος & Συντήρηση») σε δεύτερη
               γραμμή μέσα στο κουμπί, όχι αποσιωπητικά: στην Ομάδα κόβονταν και
               οι δύο καρτέλες. Τα σύντομα μένουν σε μία γραμμή, όπως στο Προφίλ. */
            ul.gary-tabs-grid .nav-link {
                width: 100%; height: 100%; min-height: 44px; margin: 0 !important;
                display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 .3rem;
                text-align: center; font-size: .85rem !important; padding: .45rem .4rem !important;
                line-height: 1.2; white-space: normal;
                border-radius: .4rem !important; border: 1px solid var(--bs-border-color) !important;
                /* Φωτεινό θέμα: το `--bs-secondary-color` (75% αδιαφάνεια) ήταν πολύ
                   αχνό — «δεν είναι εμφανές το Αντικείμενα όταν η Κοινή χρήση είναι
                   ενεργή» (15/09/2026). Στο σκοτεινό μένει ως είχε. */
                color: var(--bs-gray-700); background: transparent;
                /* Το γενικό `.nav-tabs .nav-link { opacity: .6 }` ξέβαφε και το
                   σκούρο γκρι — αυτό ήταν το μισό του «δεν είναι εμφανές». */
                opacity: 1;
            }
            ul.gary-tabs-grid .nav-link:hover, ul.gary-tabs-grid .nav-link:focus { opacity: 1; color: var(--bs-body-color); }
            [data-bs-theme="dark"] ul.gary-tabs-grid .nav-link:not(.active) { color: var(--bs-secondary-color); opacity: .6; }
            ul.gary-tabs-grid .nav-link.active {
                background: var(--bs-primary) !important; color: #fff !important;
                border-color: var(--bs-primary) !important; font-weight: 600;
            }
            /* Ο αριθμός μέσα στην ενεργή καρτέλα: primary πάνω σε primary χανόταν. */
            ul.gary-tabs-grid .nav-link.active .badge { background: #fff !important; color: var(--bs-primary) !important; }
        }

        /* ── Γεφύρι σκίασης (static/js/backdrop_bridge.js) ──
           **Ίδιος τόνος** με το backdrop από πάνω (0.6 × 0.5), ώστε η αλλαγή από
           το ένα στο άλλο να μη φαίνεται. Κάτω από τα modal, και χωρίς να πιάνει
           κλικ: όσο σβήνει, η σελίδα δουλεύει ήδη. */
        .gary-backdrop-bridge {
            position: fixed;
            inset: 0;
            z-index: 5500;
            background-color: rgba(0,0,0,0.6);
            opacity: 0;
            visibility: hidden;
            pointer-events: none;
        }
        .gary-backdrop-bridge.is-on { opacity: .5; visibility: visible; }
        .gary-backdrop-bridge.is-on.is-fading { opacity: 0; transition: opacity .16s ease; }

        /* ── Modal που σέρνεται από τον τίτλο (static/js/modal_drag.js) ── */
        @media (pointer: fine) and (min-width: 768px) {
            .modal-header { cursor: move; }
            .modal-header :is(button, a, input, select, textarea, label) { cursor: pointer; }
        }
        html.gary-modal-dragging, html.gary-modal-dragging * { user-select: none !important; cursor: move !important; }
        .card, .table-responsive { position: static !important; z-index: auto !important; }
        /* Εξαίρεση: κάρτα που είναι κολλητή γραμμή εργαλείων (Ιστορικό → Αντικείμενα).
           Ο κανόνας από πάνω την έκανε static και το sticky αγνοούνταν σιωπηλά.
           Δεν περιέχει modal, άρα η στοίβαξή τους δεν επηρεάζεται. */
        @media (min-width: 769px) {
            .card[data-sticky-bar] { position: sticky !important; z-index: 40 !important; }
        }

        #deleteCategoryModal .modal-body { min-height: 80px; max-height: 65vh; }

    /* ⚠️ **Το `modal-dialog-centered` κεντράρει μόνο ΚΑΤΑΚΟΡΥΦΑ.**
       Κάτω από 576px το Bootstrap δίνει στο `.modal-dialog` `margin: .5rem`
       — όχι `auto`. Όσο το παράθυρο γεμίζει την οθόνη δεν φαίνεται· με
       σταθερό `max-width` μικρότερο από αυτήν, κολλάει **αριστερά**.
       Μετρημένο σε 375px με το QR των Χώρων (`max-width: 320px`): αριστερό
       περιθώριο 8px, δεξί 47px (αναφορά ιδιοκτήτη 21/09/2026, με
       στιγμιότυπο). Καθολικός κανόνας, όχι `mx-auto` ανά modal: η παγίδα
       αφορά κάθε παράθυρο που είναι στενότερο από την οθόνη. */
    @media (max-width: 575.98px) {
        .modal-dialog { margin-left: auto; margin-right: auto; }
    }

    /* ⚠️ **Το ανοιχτό πράσινο είναι χρώμα ΓΡΑΜΜΑΤΩΝ, όχι γεμίσματος.**
       Στο σκοτεινό θέμα το `--bs-primary-rgb` γίνεται το ανοιχτό accent, ώστε
       οι σύνδεσμοι να διαβάζονται πάνω στο σκούρο. Παρασύρεται όμως και το
       `.badge.bg-primary`, που έχει **λευκά** γράμματα: μετρημένο λευκό πάνω
       σε #74c493 = **2.09**, δηλαδή μισό από το όριο AA (αναφορά ιδιοκτήτη
       21/09/2026, με στιγμιότυπο της ετικέτας «Επεξεργασία»).
       Το γεμισμένο σήμα κρατά το χρώμα της μάρκας, όπως ακριβώς τα γεμισμένα
       κουμπιά: λευκό πάνω σε #2f6b47 = **6.33**. */
    [data-bs-theme="dark"] .badge.bg-primary {
        background-color: var(--gary-primary) !important;
        color: #fff;
    }

    /* ── Dark mode ────────────────────────────────────────────── */
    [data-bs-theme="dark"] body {
        background: linear-gradient(160deg, #0d1117 0%, var(--gary-dk-bg) 100%);
    }
    [data-bs-theme="dark"] .card {
        background: rgba(22, 27, 34, 0.98);
        border: 1px solid rgba(240, 246, 252, 0.08) !important;
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
    }
    [data-bs-theme="dark"] .card:hover {
        box-shadow: 0 8px 28px rgba(var(--gary-accent-rgb), 0.12), 0 4px 16px rgba(0, 0, 0, 0.45);
        border-color: rgba(var(--gary-accent-rgb), 0.2) !important;
    }
    [data-bs-theme="dark"] .no-card-hover .card:hover {
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
        border-color: rgba(240, 246, 252, 0.08) !important;
    }
    [data-bs-theme="dark"] h2 { color: var(--gary-dk-text); }
    [data-bs-theme="dark"] h4, [data-bs-theme="dark"] h5 { color: var(--gary-dk-text); }
    [data-bs-theme="dark"] label { font-weight: 500; color: var(--gary-dk-subtle); }
    [data-bs-theme="dark"] footer {
        background: rgba(1, 4, 9, 0.95);
        border-top: 1px solid rgba(240, 246, 252, 0.08);
        color: var(--gary-dk-subtle);
    }
    [data-bs-theme="dark"] .list-group-item:hover {
        background-color: rgba(177, 186, 196, 0.06);
    }
    /* Keep table cells transparent but give table-light thead a distinct stripe */
    [data-bs-theme="dark"] .table > :not(caption) > * > * {
        background-color: transparent;
        border-color: rgba(240, 246, 252, 0.07);
    }
    [data-bs-theme="dark"] thead.table-light > tr > th,
    [data-bs-theme="dark"] thead.table-light > tr > td {
        background-color: rgba(33, 38, 45, 0.98) !important;
        color: var(--gary-dk-subtle) !important;
        border-bottom: 1px solid rgba(240, 246, 252, 0.12) !important;
    }
    [data-bs-theme="dark"] .table-hover > tbody > tr:hover > * {
        background-color: rgba(177, 186, 196, 0.05) !important;
    }

/* ── Μπάρα ενεργειών αντικειμένου, σε κινητό ─────────────────────────────
   Την ίδια διάταξη έχουν το **modal πληροφοριών** (`#itemModalActions`) και η
   **σελίδα** `/item/<id>/view`. Γραμμένη σε κλάση και όχι σε id ακριβώς γι'
   αυτό: αντιγραμμένη σε δύο σημεία, η επόμενη διόρθωση θα έπιανε το ένα.

   ⚠️ **Δεν είναι αισθητική επιλογή.** Μετρημένο στα 375×812, στην παλιά
   διάταξη: η **Επεξεργασία** — η πιο συχνή ενέργεια, 108 καταγεγραμμένες —
   ήταν η **πιο μακρινή** από τον αντίχειρα (350px) και η **Διαγραφή** η **πιο
   κοντινή** (238px). Το ευκολότερο κουμπί να πατηθεί κατά λάθος ήταν αυτό που
   σβήνει.

   Δύο σειρές: ο πρωταγωνιστής πιάνει το πλάτος (δεν χρειάζεται στόχευση) με το
   «⋮» δίπλα του, και η ακίνδυνη ενέργεια (Κλείσιμο / Πίσω) από κάτω σε όλο το
   πλάτος — δικαιούται τη θέση που πέφτει ευκολότερα στον αντίχειρα. Οι
   δευτερεύουσες θέλουν δύο πατήματα· η **Διαγραφή** είναι η τελευταία στο
   μενού, μετά από διαχωριστικό. */
@media (max-width: 767px) {
  .gary-item-actions {
    /* ⚠️ Το `!important` **χρειάζεται**: η σελίδα κρατά το `d-flex` του
       Bootstrap για τη διάταξη σε υπολογιστή, και τα utility του είναι
       δηλωμένα `!important` — νικούσαν σιωπηλά, και η μπάρα έμενε flex
       (μετρημένο: `display: flex`, επιστροφή 181px αντί για ολόπλατη).
       Ίδιο μοτίβο με το `display: contents` του modal πληροφοριών. */
    display: grid !important;
    grid-template-columns: 1fr auto;
    gap: .5rem;
  }
  .gary-item-actions .btn { min-height: 44px; margin: 0; }
  /* ⚠️ Ρητό `grid-area` και στα τρία: η σειρά του DOM δεν είναι πάντα η σειρά
     της οθόνης, και με μόνο `grid-column` η αυτόματη τοποθέτηση δεν γυρίζει
     πίσω σε κελί που προσπέρασε. */
  .gary-item-actions .gary-item-primary { grid-area: 1 / 1 / 2 / 2;
                                          min-height: 48px; font-weight: 600; }
  .gary-item-actions .dropup            { grid-area: 1 / 2 / 2 / 3; }
  .gary-item-actions .gary-item-more    { min-width: 52px; height: 100%; }
  /* Η ακίνδυνη ενέργεια: **ρητή** θέση, ώστε να μη μετακινηθεί αν προστεθεί
     κάτι ανάμεσα. */
  .gary-item-actions > .btn-secondary   { grid-area: 2 / 1 / 3 / 3; }

  /* Τα στοιχεία του μενού είναι στόχοι αφής, όχι γραμμές λίστας. */
  .gary-item-actions .dropdown-item { padding-top: .6rem; padding-bottom: .6rem; }
}

/* ── Στόχος αφής 44px που κεντράρει και κατακόρυφα ────────────────────────
   ⚠️ Ένα `<a class="btn">` **δεν** κεντράρει κατακόρυφα το κείμενό του όταν
   του επιβάλλεις ύψος· ένα `<button>` το κάνει από μόνο του. Μετρημένο σε
   browser 06/09/2026, ίδιο ύψος 44px, ίδια κλάση:

       <button>  11px πάνω / 11px κάτω   ✓
       <a>        6px πάνω / 19px κάτω   ✗

   Το κείμενο κάθεται ψηλά και το κουμπί φαίνεται μισοάδειο — αναφορά
   ιδιοκτήτη, δύο φορές, για τα «Καταχώριση» και «Καταχωρήθηκε» της απογραφής.
   Και τα **44px είναι ο λόγος** που μπαίνει ύψος: είναι το ελάχιστο μέγεθος
   στόχου αφής. Ένας κανόνας, ένας συγγραφέας — αντί για inline `min-height`
   που ξαναγεννά το σφάλμα με το επόμενο κουμπί. */
.btn-touch {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* ── Σήματα μέσα στο μενού «Περισσότερα» (κινητό) ─────────────────────────
   Κάθε αριθμός στο «Περισσότερα» υπάρχει και ως σήμα στο εικονίδιο του
   μενού που ανοίγει (αναφορά ιδιοκτήτη 13/09/2026: «1» που δεν οδηγούσε
   πουθενά). Το σήμα ζει ήδη ως `.mob-tab__badge`· εδώ μόνο το εικονίδιο του
   μενού γίνεται βάση για απόλυτη θέση.

   ⚠️ **Διπλή κλάση στο πορτοκαλί.** Το στυλ της μπάρας είναι inline στο
   `base.html` και έρχεται **μετά** από αυτό το φύλλο: σε ισοβαθμία
   ειδικότητας το δικό του `.mob-tab__badge { right: -8px; background: … }`
   θα κέρδιζε, και το πορτοκαλί θα ξανακαθόταν πάνω στο κόκκινο — κόκκινο.
   Μπαίνει **αριστερά**: στην ίδια θέση με το κόκκινο το σκέπαζε. */
.mob-sheet__item .si { position: relative; }
.mob-tab__badge.mob-tab__badge--pending {
  right: auto;
  left: -8px;
  background: var(--bs-orange);
}

/* ── «🔔 Ειδοποίηση [ N ] ημέρες πριν» ──────────────────────────────────────
   Αναφορά ιδιοκτήτη 13/09/2026, με στιγμιότυπο: στη φόρμα επεξεργασίας το
   πεδίο ημερών είχε **18px** — ούτε διψήφιος αριθμός δεν φαινόταν. Μέσα σε
   `.input-group` το πεδίο είναι το μόνο στοιχείο που συρρικνώνεται, και οι
   δύο ετικέτες δεξιά κι αριστερά του έπαιρναν όλο το πλάτος της στήλης.

   ⚠️ Επιλογέας στο **όνομα**, όχι σε ids: το ίδιο πεδίο υπάρχει για λήξη,
   εγγύηση και απόθεμα, σε τρεις φόρμες — εννέα εμφανίσεις. Με ids θα
   διορθωνόταν όποιο φάνηκε σε στιγμιότυπο.

   ⚠️ **3.75rem, όχι περισσότερο.** Μετρημένο σε browser: το 365 (το μέγιστο)
   χωράει από τα 60px και πάνω. Με 72px, στη στήλη της λήξης (273px) το
   «ημέρες πριν» έπεφτε σε δεύτερη γραμμή — 113 + 72 + 93 = 278.
   ⚠️ **Και ίδιο εσωτερικό περιθώριο.** Το πεδίο του αποθέματος δεν είναι
   `form-control-sm` (12px αντί για 8) και στα 60px το 365 δεν χωρούσε·
   μεγαλύτερο πλάτος θα ξανάσπρωχνε την ετικέτα της λήξης. */
.input-group > input[type="number"][name$="_notify_days"] {
  flex: 0 0 3.75rem;
  min-width: 3.75rem;
  padding-left: .5rem;
  padding-right: .25rem;
}

/* ── Μπάρα πλοήγησης κινητού & φύλλο «Περισσότερα» ──────────────────
   Ήταν inline στο base.html, **μετά** το περιεχόμενο: η μπάρα δεν είχε στυλ
   μέχρι να διαβαστεί όλη η σελίδα, και σε κάθε πλοήγηση εμφανιζόταν με
   καθυστέρηση (αναφορά ιδιοκτήτη 20/09/2026). Εδώ φορτώνεται από την
   κεφαλίδα, μία φορά, και μένει στην cache. */
/* Το ύψος της μπάρας ήταν γραμμένο **τρεις φορές** ως σκέτο 76: εδώ, στο
   κουμπί «πάνω», και πουθενά για τα μηνύματα — γι' αυτό τα μηνύματα την
   έκρυβαν (αναφορά με screenshot, 26/08/2026). Μία σταθερά, τρεις χρήσεις.

   ⚠️ Και η σταθερά ήταν **λάθος**: μετρημένο σε browser 375px, η μπάρα είναι
   60px, όχι 76. Το 76 δεν αντιστοιχούσε σε τίποτα — ούτε στο ύψος χωρίς
   safe-area (60) ούτε με αυτήν (60 + inset, που ποικίλλει ανά συσκευή).
   Γι' αυτό η τιμή εδώ είναι πλέον απλώς **εφεδρεία**: το ύψος μετριέται στην
   εκκίνηση και σε κάθε αλλαγή προσανατολισμού (βλ. script πιο κάτω).
   ⚠️ Η μετρημένη τιμή γράφεται **χωρίς** το `padding-bottom` της safe-area,
   γιατί κάθε καταναλωτής προσθέτει ήδη μόνος του `env(safe-area-inset-bottom)`
   — αλλιώς το inset μετριόταν δύο φορές. */
:root { --gary-bottomnav-h: 76px; }

/* ── Εμφανίζεται μόνο σε phone (≤ 767px) ──────────────────── */
/* ⚠️ **Ίδια συνθήκη με την πλευρική μπάρα**, αλλιώς υπάρχει οθόνη χωρίς
   καμία πλοήγηση: κινητό γυρισμένο πλάγια (~844×390) είναι «φαρδύ» για
   την κάτω μπάρα και «κινητό» για την πλευρική, οπότε έφευγαν **και οι
   δύο**. Το ίδιο στα ακριβώς 768px, από το κενό 767/768.
   Αναφορά ιδιοκτήτη 21/09/2026. Ίδια παγίδα με την 03/09 για την πάνω
   μπάρα — τότε διορθώθηκε η πλευρική και η πάνω, όχι αυτή. */
@media (max-width: 768px),
       (orientation: landscape) and (max-height: 500px) {

  /* Τα μηνύματα πάνω από τη μπάρα, όχι πάνω της. Ο κανόνας ζει **μέσα** σε
     αυτό το μπλοκ, που αποδίδεται μόνο όταν υπάρχει η μπάρα: σε σελίδα χωρίς
     αυτήν, το μήνυμα δεν έχει λόγο να ανέβει. */
  /* ⚠️ Το `--gary-bottom-inset` είναι **ολόκληρη** η απόσταση από τον πάτο
     της οθόνης, όταν κάποια σελίδα έχει δικό της σταθερό περιεχόμενο εκεί
     κάτω (π.χ. η στοίβα κουμπιών της απογραφής, που κάθεται **πάνω** από τη
     μπάρα). Χωρίς αυτό, τα μηνύματα ήξεραν μόνο για τη μπάρα και έβγαιναν
     πάνω στα κουμπιά (αναφορά ιδιοκτήτη 09/09/2026).
     Η προεπιλογή είναι ακριβώς η παλιά συμπεριφορά: μπάρα + safe area. */
  #garyToastContainer {
    bottom: calc(var(--gary-bottom-inset, calc(var(--gary-bottomnav-h, 76px) + env(safe-area-inset-bottom, 0px))) + .75rem);
    left: .75rem;
    right: .75rem;
    max-width: none;
  }

  /* Sidebar: hidden — πλοηγούμαστε από bottom nav + mobile topbar */
  .sidebar          { display: none !important; }
  /* ⚠️ Η απόσταση από τη μπάρα ανήκει στο **τελευταίο** στοιχείο της σελίδας,
     και αυτό ΔΕΝ είναι το `.content-area`: ο footer είναι αδερφός του, μετά
     από αυτό. Με την απόσταση μόνο στο `.content-area`, ο footer έπεφτε από
     κάτω και η σταθερή μπάρα σκέπαζε **59 από τα 73px του** — δηλαδή τους
     συνδέσμους «Όροι Χρήσης / Πολιτική Απορρήτου / Ευχαριστίες», που είναι ο
     **μοναδικός** δρόμος προς τις νομικές σελίδες μετά τη σύνδεση (αναφορά
     χρήστη 29/08/2026: «δε βλέπω δυνατότητα πρόσβασης από το κινητό»).
     Μετρημένο: έγγραφο 943, οθόνη 812, footer 870–943, μπάρα 753–812.
     Πηγαίνει στο `.main-wrapper`, που περιέχει **και τα δύο** — άρα ισχύει
     είτε υπάρχει footer είτε όχι (σε `embed` δεν υπάρχει). */
  .main-wrapper     { margin-left: 0 !important; width: 100% !important;
                      padding-bottom: calc(var(--gary-bottomnav-h, 76px) + env(safe-area-inset-bottom, 0px)) !important; }
  .content-area     { padding-top: 1rem !important; }

  /* ── Bottom Nav bar ──────────────────────────────────────── */
  .mob-nav {
    display: flex;
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1080;
    background: var(--bs-body-bg);
    border-top: 1px solid var(--bs-border-color);
    padding-bottom: env(safe-area-inset-bottom, 0px);
    box-shadow: 0 -2px 12px rgba(0,0,0,.08);
  }

  .mob-tab {
    flex: 1; display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 3px; padding: 8px 4px;
    color: var(--bs-secondary-color);
    text-decoration: none; font-size: 10px; font-weight: 500;
    transition: color .15s; border: none; background: none; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    min-height: 58px;
  }
  .mob-tab:hover, .mob-tab:focus { color: var(--bs-primary); text-decoration: none; }
  .mob-tab--active { color: var(--bs-primary); font-weight: 600; }
  .mob-tab--active .mob-tab__icon {
    background: rgba(var(--gary-primary-rgb), .13);
    border-radius: 14px;
    padding: 4px 14px;
    margin: 0 -14px;
  }
  [data-bs-theme="dark"] .mob-tab--active .mob-tab__icon {
    background: rgba(var(--gary-accent-rgb), .15);
  }

  /* Το χρώμα των εικονιδίων ζει στο gary-main.css — εδώ το inline CSS έχει
     ταβάνι (tests/test_css_extraction.py). */
  .mob-tab__icon {
    font-size: 22px; line-height: 1;
    display: flex; align-items: center; justify-content: center;
    position: relative;
  }
  .mob-tab__badge {
    position: absolute; top: -4px; right: -8px;
    background: var(--bs-danger); color: #fff;
    font-size: 9px; font-weight: 700; line-height: 1;
    padding: 2px 4px; border-radius: 8px; min-width: 14px;
    text-align: center;
  }
  .mob-tab__label { font-size: 10px; line-height: 1; }

  /* ── More Bottom Sheet ───────────────────────────────────── */
  .mob-sheet-backdrop {
    display: none;
    position: fixed; inset: 0; z-index: 1090;
    background: rgba(0,0,0,.4);
    opacity: 0; transition: opacity .25s;
  }
  .mob-sheet-backdrop.open { display: block; opacity: 1; }

  .mob-sheet {
    position: fixed; bottom: 0; left: 0; right: 0; z-index: 1091;
    background: var(--bs-body-bg);
    border-radius: 16px 16px 0 0;
    padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    transform: translateY(100%);
    transition: transform .3s cubic-bezier(.32,1,.23,1);
    max-height: 75vh; overflow-y: auto;
  }
  .mob-sheet.open { transform: translateY(0); }

  .mob-sheet__handle {
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--bs-border-color);
    margin: 10px auto 6px;
  }

  /* Το όνομα, εκεί όπου έφυγε η πάνω μπάρα (21/09/2026). Λευκό πλαίσιο
     γιατί το ίδιο το αρχείο έχει λευκό φόντο — σε σκοτεινό θέμα χωρίς αυτό
     το wordmark χάνεται μέσα στο φόντο του. */
  .mob-sheet__brand { display: flex; justify-content: center; padding: .1rem 0 .55rem; }
  .mob-sheet__brand img {
    height: 34px; width: auto; max-width: 190px; object-fit: contain;
    background: #fff; border-radius: 8px; padding: 4px 12px;
  }

  .mob-sheet__grid {
    display: grid; grid-template-columns: 1fr 1fr 1fr;
    gap: 4px; padding: 8px 12px 12px;
  }
  .mob-sheet__item {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 5px; padding: 14px 8px;
    border-radius: 12px; text-decoration: none;
    color: var(--bs-body-color); font-size: 11px;
    font-weight: 500; text-align: center;
    background: var(--bs-tertiary-bg);
    -webkit-tap-highlight-color: transparent;
    transition: background .12s;
  }
  .mob-sheet__item:hover { background: var(--bs-secondary-bg); text-decoration: none; color: var(--bs-body-color); }
  .mob-sheet__item--active { background: rgba(var(--gary-primary-rgb), .12); color: var(--bs-primary); }
  .mob-sheet__item .si { font-size: 24px; line-height: 1; }
  /* Το κουμπί αποσύνδεσης μπαίνει στο ίδιο πλέγμα με τους συνδέσμους, οπότε
     χρειάζεται να ακυρώσει τα defaults του <button>. */
  button.mob-sheet__item { border: 0; width: 100%; font-family: inherit; cursor: pointer; }
  /* Δευτερεύουσες, όχι πλοήγηση: μικρές και διακριτικές, κάτω από το πλέγμα. */
  .mob-sheet__legal {
    padding: 0 12px 14px; text-align: center;
    font-size: 11px; color: var(--bs-secondary-color);
  }
  .mob-sheet__legal a { color: var(--bs-secondary-color); text-decoration: underline; }
}

/* Desktop: κρύψε το bottom nav.
   ⚠️ **Το ακριβές συμπλήρωμα** της συνθήκης από πάνω, γραμμένο με τον
   ίδιο τρόπο που το γράφει ήδη το αρχείο (γρ. ~671): «φαρδύ ΚΑΙ ψηλό» ή
   «φαρδύ ΚΑΙ κατακόρυφο». Ένα σκέτο `min-width` πιάνει και το κινητό
   σε οριζόντια θέση — και επειδή εδώ υπάρχει `!important`, κέρδιζε. */
@media (min-width: 769px) and (min-height: 501px),
       (min-width: 769px) and (orientation: portrait) {
  .mob-nav, .mob-sheet, .mob-sheet-backdrop { display: none !important; }
}
/* Print: κρύψε όλα τα mobile elements */
@media print {
  .mob-nav, .mob-sheet, .mob-sheet-backdrop,
  .mob-stk-counter, #garyOfflineBanner { display: none !important; }
}

/* Το × που μαζεύει μια ενότητα της φόρμας.

   Το προεπιλεγμένο `.btn-close` του Bootstrap είναι φτιαγμένο για
   επικεφαλίδα modal· δίπλα στο μικρό κείμενο τίτλου μιας ενότητας δείχνει
   υπερβολικά μεγάλο (αναφορά ιδιοκτήτη 16/10/2026).

   ⚠️ Μικραίνει το **σύμβολο**, όχι το κουτί: το `.btn-close` ορίζει
   `width/height: 1em` και `padding: .25em`, οπότε σκέτο μικρότερο
   `font-size` θα συρρίκνωνε και τον στόχο αφής. Το padding ανεβαίνει όσο
   χρειάζεται ώστε το κουτί να μείνει ~24px στο κινητό. */
.btn-close-xs {
  font-size: .7rem;
  padding: .4rem;
  opacity: .5;
}
.btn-close-xs:hover { opacity: .9; }

/* ─────────────────────────────────────────────────────────────
   ΑΝΑΖΗΤΗΣΗ — ο φακός ΜΕΣΑ στο πεδίο, αριστερά

   <div class="gary-search"><i class="bi bi-search"></i><input …></div>

   Ίδιο σχήμα με το `.sb-search` της πλαϊνής μπάρας· αίτημα ιδιοκτήτη
   16/10/2026, «όπως στην sidebar». Ένας ορισμός για τα επτά πεδία
   αναζήτησης της εφαρμογής, αντί για επτά αντίγραφα.

   ⚠️ Εικονίδιο **γραμματοσειράς**, όχι `data:` URI σε background-image:
   ακολουθεί μόνο του το χρώμα του θέματος. Ένα SVG μέσα στο CSS θα ήθελε
   δεύτερο ορισμό για το σκοτεινό, που αποκλίνει σιωπηλά.

   ⚠️ `pointer-events: none` — αλλιώς το κλικ πάνω στον φακό δεν εστιάζει το
   πεδίο: στόχος που φαίνεται πατήσιμος και δεν κάνει τίποτα.

   ⚠️ Όπου το πεδίο ζει σε `.input-group`, ο φακός μπαίνει σε περιτύλιγμα
   **γύρω** από το group, ποτέ μέσα του: το Bootstrap στρογγυλεύει με
   `> :not(:first-child)`, οπότε ένα `<i>` ως πρώτο παιδί θα έκοβε την
   αριστερή καμπύλη του πεδίου.
──────────────────────────────────────────────────────────────── */
.gary-search { position: relative; }
.gary-search > .bi-search {
  position: absolute;
  left: .6rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;                 /* το .form-control σηκώνεται σε 5 στο focus */
  pointer-events: none;
  color: var(--bs-secondary-color);
}
/* ⚠️ Δύο επιλογείς, όχι ένας: μέσα σε `.input-group-sm` το Bootstrap γράφει
   `.input-group-sm > .form-control { padding: .25rem .5rem }` — ίδια
   ειδικότητα με έναν σκέτο `.gary-search input`, οπότε το αποτέλεσμα θα
   κρεμόταν από τη σειρά των φύλλων. Μετρημένο: ο φακός καθόταν πάνω στο
   κείμενο του placeholder. */
.gary-search input,
.gary-search input.form-control { padding-left: 2rem; }
