/* ============================================================
   Yardly — shared design system ("Meridian")
   Linked by every app page; page-specific <style> blocks may still add
   layout rules but should reuse these tokens/classes.

   The product runs on the same identity as the public site: cool
   near-white surfaces, deep navy ink, one petrol-teal brand colour.
   Where the two differ is register — the marketing pages are
   expressive, this is an instrument. So: no coloured glows, no
   decorative gradients on controls, tabular figures everywhere a
   number can line up under another, and hairlines doing the work that
   shadows would otherwise do.

   IMPORTANT — the accent tokens are still named --blue*. Renaming them
   would mean touching 37 pages plus the component JS for no functional
   gain, so the names are treated as a stable interface and only the
   values move. --blue is the brand teal; read the name as "the accent".
   ============================================================ */

:root{
  /* ---------- surfaces ---------- */
  --bg:#FFFFFF;
  --surface:#FFFFFF;
  --surface-2:#F1F5F9;
  --surface-sunken:#F1F5F9;
  --line:#E2E8F0;
  /* --line is the hairline between things; --line-strong is the edge of a
     CONTROL (input, select, secondary button, drop zone). WCAG 1.4.11 asks 3:1
     for that edge against its ground, which #CBD5E1 missed at 1.5:1 — an
     unhelpfully faint field outline in a data-entry app. #8494A8 measures
     3.1:1 on white without making the forms look heavy. */
  --line-strong:#8494A8;

  /* ---------- text ----------
     --muted is the tightest of these: it has to clear AA on white AND on
     --surface-2 (table headers, sunken wells). #5B6B7F measures 5.45:1 and
     4.97:1 respectively; anything lighter fails the second one. */
  --ink:#0A1A2B;
  --ink-soft:#42546B;
  --muted:#5B6B7F;
  --on-accent:#FFFFFF;

  /* ---------- accent (see header note on the --blue* naming) ----------
     The teal is legible as both a fill and as text — 6.1:1 on white, 5.6:1 on
     --surface-2, 5.3:1 on its own tint — so one value serves buttons, active
     nav, links and icons without needing a separate "accent text" shade. */
  --blue:#0E6E66;
  --blue-deep:#0B554F;
  --blue-bright:#12857B;
  --blue-bg:#E4F2EF;
  --blue-border:#B9DED7;
  --cyan:#5FD4C4;       /* light teal — only for use ON the dark surfaces */
  --dark:#0A1A2B;
  /* Kept because ~15 page-level rules paint marks and progress fills with it.
     Deliberately shallow: a navy-to-teal shift, not a candy gradient. */
  --grad-brand:linear-gradient(135deg,#0E6E66 0%,#14837A 100%);
  --grad-brand-hover:linear-gradient(135deg,#0B554F 0%,#0E6E66 100%);
  --grad-mesh-1:#0E6E66;
  --grad-mesh-2:#123A5C;
  --grad-mesh-3:#5FD4C4;

  /* ---------- semantic ----------
     Outside the brand hue on purpose: a row that is "expiring" must not read
     as a row that is "branded". Text/background pairs all clear AA, and the
     solid values clear 3:1 on white for use as dots and bars. */
  --green:#067647;
  --green-bg:#ECFDF3;
  --green-border:#ABEFC6;
  --green-solid:#079455;
  --amber:#B54708;
  --amber-bg:#FFFAEB;
  --amber-border:#FEDF89;
  --amber-solid:#DC6803;
  --coral:#B42318;
  --coral-bg:#FEF3F2;
  --coral-border:#FECDCA;
  --coral-solid:#D92D20;

  /* ---------- radius ----------
     Controls (buttons, inputs, tabs, nav items) are square-ish; labels
     (badges, chips, progress tracks) stay pills. The split is the point: it
     tells you at a glance what you can press and what merely states a fact. */
  --radius-sm:8px;
  --radius-md:10px;
  --radius-lg:12px;
  --radius-xl:16px;
  --radius-pill:999px;

  /* Set by nav.js (measured, not fixed — the banner copy can wrap to two lines on a narrow
     viewport) only when a company is in its subscription grace period. Zero otherwise, so the
     calc() below is a no-op for the overwhelming majority of page loads. */
  --grace-banner-h:0px;

  /* ---------- shadow ----------
     Neutral navy only. The previous violet glow read as consumer software;
     depth here comes from hairlines first and shadow second. */
  --shadow-xs:0 1px 2px rgba(10,26,43,0.05);
  --shadow-sm:0 1px 2px rgba(10,26,43,0.06),0 1px 1px rgba(10,26,43,0.04);
  --shadow-md:0 8px 20px -8px rgba(10,26,43,0.14),0 2px 5px -2px rgba(10,26,43,0.07);
  --shadow-lg:0 24px 48px -16px rgba(10,26,43,0.24),0 6px 14px -6px rgba(10,26,43,0.12);
  /* Names kept for the two page-level rules that reference them. */
  --shadow-blue:0 1px 2px rgba(10,26,43,0.10);
  --shadow-blue-lg:0 6px 16px -6px rgba(10,26,43,0.20);

  --font-display:'Instrument Sans','Inter','Segoe UI',sans-serif;
  --font-body:'Instrument Sans','Inter','Segoe UI',sans-serif;
  --font-mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}

*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:var(--font-body);-webkit-font-smoothing:antialiased;background:var(--bg);color:var(--ink);}
a{color:inherit;text-decoration:none;}
ul{list-style:none;}
::selection{background:var(--blue-bg);color:var(--blue-deep);}

h1,h2,h3{font-family:var(--font-display);letter-spacing:-0.02em;color:var(--ink);}

/* Figures line up under one another wherever they are read as a column or
   compared across rows — the single biggest legibility win in a data tool. */
table,.mono,.stat-value,input,select,textarea{font-variant-numeric:tabular-nums;}

.text-gradient{background:var(--grad-brand);-webkit-background-clip:text;background-clip:text;color:transparent;}

/* ============================================================
   Buttons — 44px tall, square-cornered, weight 600. Controls are
   square throughout the app; only labels stay pills.
   ============================================================ */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:44px;padding:0 20px;border-radius:var(--radius-sm);
  font-size:14px;font-weight:600;font-family:var(--font-body);letter-spacing:-0.01em;
  cursor:pointer;border:1px solid transparent;white-space:nowrap;
  transition:background .5s var(--ease,cubic-bezier(.4,0,.2,1)),border-color .3s ease,box-shadow .18s ease,color .3s ease,transform .15s ease;
}
.btn:active{transform:translateY(1px) scale(0.99);}
.btn:disabled,.btn[disabled]{opacity:0.5;cursor:not-allowed;pointer-events:none;}

.btn-primary{background:var(--blue);color:#fff;border-color:transparent;box-shadow:var(--shadow-xs);}
.btn-primary:hover{background:var(--blue-deep);box-shadow:var(--shadow-sm);}

.btn-secondary{background:#fff;color:var(--ink);border-color:var(--line-strong);box-shadow:var(--shadow-xs);}
.btn-secondary:hover{border-color:var(--ink);background:var(--surface-2);}

.btn-ghost{background:transparent;color:var(--ink);border-color:var(--line-strong);}
.btn-ghost:hover{border-color:var(--blue);color:var(--blue);}

.btn-danger{background:var(--coral-bg);color:var(--coral);border-color:var(--coral-border);}
.btn-danger:hover{background:var(--coral);color:#fff;border-color:var(--coral);}

.btn-sm{height:36px;padding:0 14px;font-size:13px;}
.btn-block{width:100%;}

/* ============================================================
   Cards & sections — white, hairline border, minimal shadow. The
   border carries the separation; the shadow only lifts it off the
   sunken app background.
   ============================================================ */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);padding:24px;box-shadow:var(--shadow-sm);}
/* overflow-x:auto, not hidden: a table with enough columns (e.g. the equipment cost summary)
   is wider than the card even on a full desktop viewport, and `hidden` silently clipped the
   last columns with no way to reach them. `auto` still clips the rounded corners the same way,
   and shows no scrollbar at all when the table already fits. */
.card-table{padding:0;overflow-x:auto;overflow-y:hidden;}
.card-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px;}
.card-head h3{font-family:var(--font-display);font-weight:600;font-size:16px;letter-spacing:-0.02em;color:var(--ink);}

.section-title{font-family:var(--font-display);font-weight:600;font-size:20px;margin:40px 0 14px;letter-spacing:-0.02em;color:var(--ink);}

/* ============================================================
   Status pills / badges / stamps — one consistent tag system.
   ============================================================ */
.status-pill{font-size:11.5px;font-weight:700;padding:4px 11px;border-radius:var(--radius-pill);
  text-transform:uppercase;letter-spacing:0.03em;background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--line);}
.status-pill.active{background:var(--green-bg);color:var(--green);border-color:var(--green-border);}
.status-pill.warn{background:var(--amber-bg);color:var(--amber);border-color:var(--amber-border);}
.status-pill.expired{background:var(--coral-bg);color:var(--coral);border-color:var(--coral-border);}

/* Where a record came from when it was not typed in (e.g. DKV for a fuel card transaction). */
.source-tag{display:inline-block;font-size:10.5px;font-weight:800;letter-spacing:0.04em;padding:2px 7px;margin-right:6px;
  border-radius:var(--radius-pill);background:var(--blue-bg);color:var(--blue-deep);border:1px solid var(--blue-border);vertical-align:1px;}

.stamp{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-weight:700;letter-spacing:0.02em;
  text-transform:uppercase;padding:4px 10px;border-radius:var(--radius-pill);background:var(--surface-2);color:var(--ink-soft);border:1px solid var(--line);}
.stamp::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;}
.stamp.active{color:var(--green);background:var(--green-bg);border-color:var(--green-border);}
.stamp.warn{color:var(--amber);background:var(--amber-bg);border-color:var(--amber-border);}
.stamp.expired{color:var(--coral);background:var(--coral-bg);border-color:var(--coral-border);}

.plan-chip,.role-chip{font-size:11px;font-weight:700;padding:3px 10px;border-radius:var(--radius-pill);background:var(--surface-2);border:1px solid var(--line);color:var(--ink-soft);}
.role-chip{background:var(--blue-bg);border-color:var(--blue-border);color:var(--blue-deep);}

/* ============================================================
   Tabs — a page split into named sections the user switches between
   without a page load (e.g. Beállítások). Same pill visual language as
   the equipment-catalog modal's tab switcher, generalized for full-page use.
   ============================================================ */
.tabs{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:24px;border-bottom:1px solid var(--line);padding-bottom:14px;}
.tab-btn{padding:8px 14px;border-radius:var(--radius-sm);border:1px solid var(--line);background:#fff;
  font-size:13px;font-weight:600;color:var(--ink-soft);cursor:pointer;white-space:nowrap;
  transition:background .3s ease,border-color .3s ease,color .3s ease;}
.tab-btn:hover{background:var(--surface-2);color:var(--ink);border-color:var(--line-strong);}
.tab-btn.active{background:var(--blue);color:#fff;border-color:transparent;}
.tab-panel{display:none;}
.tab-panel.active{display:block;}

/* ============================================================
   Tables — dense, enterprise-dashboard-like precision.
   ============================================================ */
table{width:100%;border-collapse:collapse;font-size:13.5px;}
/* A long heading ("Hozzárendelt felhasználó") may take two lines rather than widen its column
   past the values under it. */
thead th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:0.06em;color:var(--muted);
  font-weight:700;padding:11px 14px;border-bottom:1px solid var(--line-strong);background:var(--surface-2);
  vertical-align:bottom;}
/* Sticky header: these lists run to hundreds of rows, and a column heading that
   scrolls away turns the table into unlabelled numbers halfway down. */
thead th{position:sticky;top:0;z-index:2;}
tbody td{padding:13px 14px;border-bottom:1px solid var(--line);vertical-align:middle;color:var(--ink);}
/* The outer columns keep the card's own 20px gutter; the ones between sit closer, so a wide
   list (eight or more columns) fits a laptop screen without scrolling. */
thead th:first-child,tbody td:first-child{padding-left:20px;}
thead th:last-child,tbody td:last-child{padding-right:20px;}
/* A short value (a plate, a date, an amount, a name) never breaks across lines: table-cards.js
   marks those cells, and the long texts beside them wrap instead. */
td.nowrap{white-space:nowrap;}
.page-header > div:last-child > a{white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:var(--blue-bg);}
.cell-main{font-weight:600;color:var(--ink);}
.cell-sub{font-size:12px;color:var(--muted);margin-top:2px;font-weight:500;}
.mono{font-family:var(--font-mono);font-size:12px;color:var(--ink-soft);letter-spacing:-0.01em;}
.empty-row td{text-align:center;color:var(--muted);padding:44px 20px;font-weight:500;}

/* ============================================================
   List toolbar (search) & pagination — shared across every list page so search
   input styling and prev/next paging look identical everywhere.
   ============================================================ */
.toolbar{display:flex;align-items:center;justify-content:space-between;gap:16px;margin-bottom:20px;flex-wrap:wrap;}
.search-box{position:relative;max-width:320px;flex:1;min-width:220px;}
.search-box svg{position:absolute;left:16px;top:50%;transform:translateY(-50%);color:var(--muted);pointer-events:none;}
/* input[type="text"], not bare input: the generic Forms rule below also matches
   input[type=text] with equal (0,1,1) specificity — without the type qualifier here this loses
   that tie via source order and the icon collides with the placeholder text. */
.search-box input[type="text"]{padding-left:42px;}

.pagination{display:flex;align-items:center;justify-content:center;gap:14px;padding:16px 20px;}
.pagination button{background:#fff;border:1px solid var(--line-strong);border-radius:var(--radius-sm);
  padding:7px 14px;font-size:12.5px;font-weight:600;color:var(--ink-soft);cursor:pointer;
  transition:background .3s ease,border-color .3s ease,color .3s ease;}
.pagination button:hover:not(:disabled){background:var(--surface-2);border-color:var(--blue);color:var(--ink);}
.pagination button:disabled{opacity:.45;cursor:default;}
.pagination .page-info{font-size:12.5px;font-weight:600;color:var(--muted);white-space:nowrap;}

/* ============================================================
   Forms — inputs and native <select>s share one shell. The select gets its
   own chevron (background-image) since appearance:none removes the native one.
   ============================================================ */
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:16px;}
.field label{font-size:12.5px;font-weight:600;color:var(--ink-soft);}
.field input,.field select,.field textarea,
input[type=text],input[type=email],input[type=password]{
  height:44px;border:1px solid var(--line-strong);border-radius:var(--radius-sm);padding:0 14px;
  font-family:var(--font-body);font-size:14px;background:#fff;color:var(--ink);width:100%;min-width:0;
  transition:border-color .15s ease,box-shadow .15s ease;
}
.field textarea{padding:12px 14px;}
.field input::placeholder,.field textarea::placeholder,input::placeholder{color:var(--muted);}

/* Native selects: strip the platform chrome and draw our own chevron so the
   control matches the input shell on every OS. */
.field select,select{
  -webkit-appearance:none;appearance:none;color-scheme:light;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%235B6B7F' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;padding-right:38px;cursor:pointer;
}
.field select:hover,select:hover{border-color:var(--ink-soft);}
.field select option,select option{background:#fff;color:var(--ink);}

.field input:focus,.field select:focus,.field textarea:focus,select:focus,input:focus,textarea:focus{
  outline:none;border-color:var(--blue);box-shadow:0 0 0 3px rgba(14,110,102,0.16);}
.field input:disabled,.field select:disabled{opacity:0.6;cursor:not-allowed;background:var(--surface-2);}

.form-error{display:none;background:var(--coral-bg);border:1px solid var(--coral-border);color:var(--coral);
  font-size:13px;font-weight:600;padding:11px 14px;border-radius:var(--radius-sm);margin-bottom:16px;}
.form-error.show{display:block;}
.form-success{background:var(--green-bg);border:1px solid var(--green-border);color:var(--green);
  font-size:13px;font-weight:600;padding:11px 14px;border-radius:var(--radius-sm);margin-bottom:16px;}

/* ============================================================
   Notice banners
   ============================================================ */
.notice{display:flex;align-items:flex-start;gap:12px;background:var(--amber-bg);border:1px solid var(--amber-border);
  border-radius:var(--radius-md);padding:14px 16px;margin-bottom:16px;}
.notice svg{flex-shrink:0;color:var(--amber);margin-top:1px;}
.notice .txt{font-size:13px;font-weight:500;color:var(--amber);line-height:1.5;}
.notice .txt b{font-weight:700;}

/* ============================================================
   Modal shell — used by every add/edit dialog (vehicles, drivers, …)
   ============================================================ */
.modal-overlay{position:fixed;inset:0;background:rgba(10,26,43,0.55);backdrop-filter:blur(3px);display:flex;align-items:center;justify-content:center;
  padding:24px;z-index:250;opacity:0;pointer-events:none;transition:opacity .18s ease;}
.modal-overlay.open{opacity:1;pointer-events:auto;}
.modal{background:var(--surface);border-radius:var(--radius-lg);width:100%;max-width:520px;max-height:88vh;overflow-y:auto;
  transform:translateY(10px) scale(0.98);transition:transform .2s cubic-bezier(.2,.8,.2,1);box-shadow:var(--shadow-lg);border:1px solid var(--line);}
.modal-overlay.open .modal{transform:translateY(0) scale(1);}
.modal-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:24px 24px 4px;}
.modal-head h2{font-family:var(--font-display);font-weight:600;font-size:20px;letter-spacing:-0.02em;color:var(--ink);}
.modal-head p{color:var(--ink-soft);font-size:13px;margin-top:6px;font-weight:500;line-height:1.5;}
.modal-close{width:30px;height:30px;border-radius:50%;border:none;background:var(--surface-2);
  display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--ink-soft);flex-shrink:0;
  transition:background .15s ease,color .15s ease;}
.modal-close:hover{background:var(--ink);color:#fff;}
.modal-body{padding:14px 24px 6px;color:var(--ink-soft);font-size:13.5px;line-height:1.6;}
.modal-body b{color:var(--ink);}
.modal-footer{display:flex;gap:10px;padding:20px 24px 24px;}
.modal-footer .btn{flex:1;}

/* ============================================================
   App shell — sidebar + main (dashboard.html)
   ============================================================ */
.app{display:flex;height:calc(100vh - var(--grace-banner-h));overflow:hidden;background:var(--surface-2);}
.sidebar{width:260px;flex-shrink:0;height:calc(100vh - var(--grace-banner-h));overflow:hidden;background:#fff;color:var(--ink);
  border-right:1px solid var(--line);display:flex;flex-direction:column;padding:22px 16px;}
.brand{display:flex;align-items:center;gap:10px;padding:0 8px 20px;border-bottom:1px solid var(--line);margin-bottom:16px;flex-shrink:0;}
/* The same logo as the yardly.hu website; companies cannot replace it. */
.brand-logo{display:block;height:26px;width:auto;}
/* Only the nav items scroll — brand and footer stay fixed. min-height:0 is required for a flex
   item to actually shrink and let its own overflow-y:auto take over instead of growing with
   content. Negative margin + matching padding lets the scrollbar sit flush with the sidebar
   edge instead of appearing inset from the nav items' own padding. */
.nav-scroll{flex:1;min-height:0;overflow-y:auto;margin:0 -16px;padding:0 16px;}
.nav-label{font-size:11px;text-transform:uppercase;letter-spacing:0.06em;color:var(--muted);padding:0 12px;margin:14px 0 6px;font-weight:700;}
.nav-label:first-child{margin-top:0;}
.nav-item{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:var(--radius-sm);font-size:13.5px;font-weight:500;
  color:var(--ink-soft);cursor:pointer;border:none;background:none;width:100%;text-align:left;font-family:var(--font-body);margin-bottom:1px;position:relative;
  transition:background .3s ease,color .3s ease;}
.nav-item .ico{width:18px;height:18px;flex-shrink:0;display:flex;align-items:center;justify-content:center;}
.nav-item:hover{background:var(--surface-2);color:var(--ink);}
/* Tinted rather than filled, with a brand rule on the leading edge: at a
   glance you read "you are here" without the item shouting over the list. */
.nav-item.active{background:var(--blue-bg);color:var(--blue-deep);font-weight:600;}
.nav-item.active .ico{color:var(--blue-deep);}
.nav-item.active::before{content:"";position:absolute;left:0;top:7px;bottom:7px;width:3px;
  border-radius:0 3px 3px 0;background:var(--blue);}
.nav-item.disabled{opacity:0.5;cursor:default;}
.nav-item .soon{margin-left:auto;font-size:9px;font-weight:700;text-transform:uppercase;letter-spacing:0.03em;color:var(--muted);}
.nav-count{margin-left:auto;min-width:20px;height:20px;padding:0 6px;border-radius:999px;background:var(--amber-bg);color:var(--amber);font-size:11px;font-weight:700;display:inline-flex;align-items:center;justify-content:center;}
.nav-count[hidden]{display:none;}

/* Collapsible parent nav item with sub-items (e.g. "Eszközpark" > Eszközök / Szervíz) —
   the only two-level nav group in the app, kept visually close to a plain .nav-item. */
.nav-group{margin-bottom:1px;}
.nav-group-toggle{margin-bottom:0;}
.nav-group-chevron{margin-left:auto;font-size:10px;color:var(--muted);transition:transform .15s ease;}
.nav-group.collapsed .nav-group-chevron{transform:rotate(-90deg);}
.nav-group-items{display:flex;flex-direction:column;margin:2px 0 2px 14px;padding-left:12px;border-left:1px solid var(--line);}
.nav-group.collapsed .nav-group-items{display:none;}
.nav-subitem{font-size:13px;padding:7px 10px;}

.company-switch{position:relative;}
.company-switch-btn{display:flex;align-items:center;gap:4px;background:none;border:0;padding:0;margin:0;
  font:inherit;color:inherit;cursor:pointer;text-align:left;}
.company-switch-btn svg{flex-shrink:0;opacity:.6;}
.company-switch-btn:hover{color:var(--ink);}
.company-menu{position:absolute;bottom:calc(100% + 8px);left:0;min-width:210px;z-index:40;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-sm);
  box-shadow:var(--shadow-md);padding:5px;display:none;}
.company-menu.open{display:block;}
.company-menu-item{display:block;width:100%;text-align:left;background:none;border:0;cursor:pointer;
  font:inherit;padding:8px 10px;border-radius:6px;color:var(--ink);}
.company-menu-item:hover{background:var(--surface-sunken);}
.company-menu-item[aria-current="true"]{background:var(--blue-bg);color:var(--blue);font-weight:700;}
.company-menu-item small{display:block;font-size:11px;color:var(--muted);font-weight:400;}

.sidebar-footer{flex-shrink:0;border-top:1px solid var(--line);padding-top:14px;display:flex;align-items:center;gap:10px;}
.avatar{width:34px;height:34px;border-radius:50%;background:var(--blue);color:#fff;display:flex;align-items:center;
  justify-content:center;font-weight:700;font-size:12.5px;flex-shrink:0;}
.sidebar-footer .who{font-size:13px;line-height:1.25;font-weight:600;color:var(--ink);}
.sidebar-footer .who small{display:block;font-size:11.5px;color:var(--muted);font-weight:500;}
.logout-link{margin-left:auto;color:var(--muted);}
.logout-link:hover{color:var(--ink);}
.sidebar-version{display:block;flex-shrink:0;text-align:center;font-size:11px;color:var(--muted);padding-top:8px;text-decoration:none;}
.sidebar-version:hover{color:var(--ink-soft);text-decoration:underline;}

.main{flex:1;min-width:0;height:calc(100vh - var(--grace-banner-h));overflow-y:auto;padding:32px 40px 56px;}

/* ---------- grace-period banner (nav.js) ----------
   Sits above .app in normal document flow (document.body.prepend, not part of nav.js's usual
   document.write markup — it has to render outside the app shell, not inside it), so on mobile
   (.app is height:auto there — no calc() needed) it just pushes content down naturally. */
.grace-period-banner{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:6px 16px;
  padding:10px 20px;background:#FEF2F2;border-bottom:1px solid #FECACA;color:#991B1B;
  font-size:13px;font-weight:600;text-align:center;}
.grace-period-banner a{font-weight:700;color:#991B1B;text-decoration:underline;white-space:nowrap;}
.grace-period-banner a:hover{color:#7F1D1D;}
.grace-period-banner-note{font-weight:600;opacity:0.85;}
/* A Yardly support session (nav.js): blue, not the warning red. */
.grace-period-banner.support-banner{background:#EFF6FF;border-bottom-color:#BFDBFE;color:#1E40AF;}
.grace-period-banner.support-banner a{color:#1E40AF;}

/* ============================================================
   Page header
   Was a title plus a paragraph explaining what the page is for. That
   paragraph is onboarding copy that every user reads once and then
   scrolls past forever, and it pushed the actual work below the fold.
   The header now orients (which section am I in) and reports (what is
   the state of this list) instead of explaining.
   ============================================================ */
.page-header{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin-bottom:22px;}
.page-eyebrow{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:0.09em;
  color:var(--muted);margin-bottom:5px;}
.page-header h1{font-family:var(--font-display);font-weight:600;font-size:27px;letter-spacing:-0.025em;color:var(--ink);}
.page-header p{color:var(--ink-soft);font-size:13.5px;margin-top:5px;font-weight:500;max-width:70ch;}

/* Live counts a page fills in once its data lands — "24 aktív · 3 szervizben".
   Hidden until it has something to say, so it never leaves an empty gap. */
.page-state{display:flex;flex-wrap:wrap;align-items:center;gap:7px 14px;margin-top:9px;
  font-size:13px;font-weight:600;color:var(--ink-soft);}
.page-state:empty{display:none;}
.page-state .s{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;}
.page-state .s::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--line-strong);}
.page-state .s.ok::before{background:var(--green-solid);}
.page-state .s.warn::before{background:var(--amber-solid);}
.page-state .s.crit::before{background:var(--coral-solid);}
.page-state .s b{font-variant-numeric:tabular-nums;color:var(--ink);}
.page-state .sep{color:var(--line-strong);}

/* ============================================================
   Command palette (palette.js)
   ============================================================ */
.nav-search{display:flex;align-items:center;gap:9px;width:100%;height:36px;padding:0 10px;
  margin-bottom:14px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--surface-2);
  color:var(--muted);font-family:var(--font-body);font-size:13px;cursor:pointer;flex-shrink:0;
  transition:border-color .15s ease,color .15s ease,background .15s ease;}
.nav-search:hover{border-color:var(--line-strong);color:var(--ink-soft);background:#fff;}
.nav-search span{flex:1;text-align:left;}
.nav-search kbd,.cp kbd{font-family:var(--font-mono);font-size:10px;line-height:1;padding:3px 5px;
  border:1px solid var(--line-strong);border-radius:4px;color:var(--muted);background:#fff;}

.cp-overlay{position:fixed;inset:0;z-index:500;background:rgba(10,26,43,0.45);backdrop-filter:blur(3px);
  display:flex;align-items:flex-start;justify-content:center;padding:12vh 20px 20px;
  opacity:0;pointer-events:none;transition:opacity .14s ease;}
.cp-overlay.open{opacity:1;pointer-events:auto;}
.cp{width:100%;max-width:540px;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);overflow:hidden;
  transform:translateY(-8px);transition:transform .14s ease;}
.cp-overlay.open .cp{transform:none;}
.cp-head{display:flex;align-items:center;gap:11px;padding:0 16px;height:52px;border-bottom:1px solid var(--line);
  color:var(--muted);}
.cp-head input{flex:1;height:100%;border:none;background:none;font-family:var(--font-body);font-size:15px;
  color:var(--ink);min-width:0;}
.cp-head input:focus{outline:none;box-shadow:none;}
.cp-list{max-height:min(52vh,420px);overflow-y:auto;padding:6px;}
.cp-item{display:flex;align-items:baseline;gap:12px;width:100%;padding:9px 11px;border:none;background:none;
  border-radius:var(--radius-sm);cursor:pointer;text-align:left;font-family:var(--font-body);}
.cp-item.on{background:var(--blue-bg);}
.cp-label{font-size:14px;font-weight:600;color:var(--ink);}
.cp-group{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--muted);text-transform:uppercase;
  letter-spacing:0.05em;white-space:nowrap;}
.cp-item.on .cp-group{color:var(--blue-deep);}
.cp-empty{padding:24px 14px;text-align:center;font-size:13.5px;color:var(--muted);}
.cp-foot{display:flex;gap:16px;padding:9px 16px;border-top:1px solid var(--line);
  font-size:11.5px;color:var(--muted);}
.cp-foot span{display:inline-flex;align-items:center;gap:5px;}

@media (max-width:768px){
  .cp-overlay{padding-top:8vh;}
  .cp-foot{display:none;}
}

/* Hamburger toggle for the mobile nav drawer — fixed top-left, only rendered/visible below the
   drawer breakpoint. Markup: a sibling of .sidebar inside .app, present on every app-shell page. */
.mobile-nav-toggle{display:none;position:fixed;top:14px;left:14px;z-index:210;width:40px;height:40px;
  border-radius:var(--radius-sm);border:1px solid var(--line);background:#fff;color:var(--ink);
  align-items:center;justify-content:center;box-shadow:var(--shadow-sm);cursor:pointer;}
.sidebar-backdrop{display:none;position:fixed;inset:0;background:rgba(10,26,43,0.55);z-index:190;opacity:0;
  pointer-events:none;transition:opacity .2s ease;}
.app.sidebar-open .sidebar-backdrop{opacity:1;pointer-events:auto;}

/* Bottom tab bar — the single biggest "this is a native app, not a squeezed desktop site" cue.
   Replaces the floating hamburger as the way into the full drawer (its last tab, "Több"), so
   there's one obvious way to navigate instead of two overlapping ones. Desktop-hidden here;
   the mobile breakpoint below turns it on. */
.mobile-tabbar{display:none;}
.mobile-tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
  padding:8px 2px calc(7px + env(safe-area-inset-bottom, 0px));border:none;background:none;color:var(--muted);
  font-family:var(--font-body);font-size:10px;font-weight:700;letter-spacing:0.01em;cursor:pointer;
  text-decoration:none;-webkit-tap-highlight-color:transparent;}
.mobile-tab svg{flex-shrink:0;}
.mobile-tab.active{color:var(--blue);}

/* ============================================================
   Mobile layout (<=768px) — sidebar becomes an off-canvas drawer toggled by
   .mobile-nav-toggle/.sidebar-backdrop above; main content goes full-width and
   single-column. Several rules here override page-specific inline <style>
   blocks (field-row-2/3 grids, stat-grid, etc.) that are declared unconditionally
   per page — !important is intentional and scoped to only this breakpoint.
   ============================================================ */
@media (max-width:768px){
  /* The tab bar's "Több" tab is the one way into the drawer now — no floating button
     doubling as a second entry point and sitting on top of page content. */
  .mobile-nav-toggle{display:none;}
  .sidebar-backdrop{display:block;}
  .mobile-tabbar{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:195;
    background:#fff;border-top:1px solid var(--line);box-shadow:0 -2px 10px -4px rgba(10,26,43,0.12);}
  .app.sidebar-open .mobile-tabbar{display:none;}

  .app{display:block;height:auto;min-height:100vh;overflow:visible;}
  /* 100dvh, not 100vh: iOS Safari sizes 100vh against the viewport with the address bar
     hidden, so a fixed-position drawer at 100vh extends past the real visible area whenever
     the bar is showing — clipping .sidebar-footer (profile/logout) below the fold with no
     way to scroll to it. dvh tracks the actual visible viewport instead. */
  .sidebar{position:fixed;top:0;left:0;height:100dvh;width:82vw;max-width:300px;z-index:200;
    transform:translateX(-100%);transition:transform .25s cubic-bezier(.2,.8,.2,1);box-shadow:var(--shadow-lg);}
  .app.sidebar-open .sidebar{transform:translateX(0);}

  /* Top padding no longer needs to clear a floating hamburger (gone — see .mobile-nav-toggle
     above); bottom padding clears the fixed tab bar plus its own safe-area inset instead. */
  .main{height:auto;min-height:100vh;overflow-y:visible;padding:20px 16px calc(76px + env(safe-area-inset-bottom, 0px));}

  .page-header{flex-direction:column;align-items:stretch;gap:12px;}
  .page-header h1{font-size:24px;}
  /* A page-header with one button (button as page-header's direct child) inherits
     align-items:stretch above and goes full-width automatically. A page-header with several
     buttons wraps them in an extra div (e.g. equipment.html) — that wrapper stretches to full
     width but its own row layout doesn't pass the stretch down to each button inside it, so
     they fell back to content width. Column + stretch here makes each button its own
     full-width row instead, matching the single-button pages. */
  .page-header > div:last-child{display:flex !important;flex-direction:column !important;align-items:stretch !important;gap:8px !important;}
  .page-header > div:last-child > a{align-self:center;}

  /* !important: several list pages restate .toolbar/.search-box in their own <style> block,
     which comes after this file and would otherwise keep the desktop row layout. */
  .toolbar{flex-direction:column !important;align-items:stretch !important;}
  .search-box{max-width:none !important;width:100%;}

  /* The settings tabs (12 of them) wrapped into seven rows: one scrolling strip instead. */
  #settings-tabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;margin-left:-16px;margin-right:-16px;padding-left:16px;padding-right:16px;}
  #settings-tabs::-webkit-scrollbar{display:none;}

  /* A horizontally-scrolling desktop table is still a desktop table, just squeezed — the
     opposite of "feels like an app". table-cards.js labels every <td> with its column header
     (read straight off each table's own <thead>, so no page's row-rendering code changes); this
     turns that into a stacked, native-feeling list of cards, one per row. overflow-x:auto stays
     as a safety net for the rare table this pass doesn't reach (e.g. one rendered before the
     script's MutationObserver attaches). */
  .card-table,.panel-table{overflow-x:auto;}
  :is(.card-table,.panel-table) table{min-width:0;width:100%;border-collapse:separate;border-spacing:0;}
  :is(.card-table,.panel-table) thead{display:none;}
  :is(.card-table,.panel-table) tbody{display:block;}
  :is(.card-table,.panel-table) tr{display:block;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-md);
    box-shadow:var(--shadow-sm);padding:4px 14px;margin-bottom:10px;}
  :is(.card-table,.panel-table) tbody tr:last-child{margin-bottom:0;}
  :is(.card-table,.panel-table) tr.empty-row{background:none;border:none;box-shadow:none;padding:0;}
  /* Label on the left, the value on the right. The label floats, so whatever the cell holds
     (a plate above its model, a date above its deadline, a pill, a row of buttons) stacks
     beside it right-aligned, the way it reads on the desktop row. */
  :is(.card-table,.panel-table) table tbody td{display:flow-root;border-bottom:1px solid var(--line);padding:10px 0;
    text-align:right;white-space:normal;}
  :is(.card-table,.panel-table) tbody td:last-child{border-bottom:none;}
  :is(.card-table,.panel-table) td[data-label]::before{content:attr(data-label);float:left;max-width:46%;margin:2px 14px 0 0;
    text-align:left;font-size:10.5px;font-weight:700;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);line-height:1.5;}
  :is(.card-table,.panel-table) td > :is(.plate-cell,.person-cell,.actor-cell,.veh-chip-row,.row-actions){justify-content:flex-end;margin-left:auto;}
  :is(.card-table,.panel-table) td > .changed-fields-list{align-items:flex-end;}
  :is(.card-table,.panel-table) td:empty{display:none;}
  :is(.card-table,.panel-table) :is(tr.empty-row td,td.span-cell){text-align:center;padding:28px 12px;}
  :is(.card-table,.panel-table) tr.empty-row td::before{content:none;}

  .modal-overlay{padding:0;align-items:flex-end;}
  .modal{max-width:none;width:100%;max-height:92vh;border-radius:var(--radius-lg) var(--radius-lg) 0 0;}

  /* min-width:0 is required here: grid items default to min-width:auto, which refuses to shrink
     below the content's intrinsic width — on iOS Safari, input[type=date] has a wide intrinsic
     size that then overflows its column and pokes out past the modal edge without this. */
  .field-row-2,.field-row-3{grid-template-columns:1fr !important;row-gap:0 !important;}
  .field-row-2 > *,.field-row-3 > *{min-width:0;}
  .stat-grid{grid-template-columns:1fr !important;}

  /* overflow:hidden alone wasn't enough: iOS Safari's native date-picker chrome doesn't just
     paint past the border-box, it computes the box itself wider than the CSS width — nothing
     is technically "overflowing" for overflow:hidden to clip. -webkit-appearance:none forces
     Safari to lay the input out with normal CSS sizing instead of its native widget algorithm.
     Tapping the field still opens the native date picker; only the inline chrome changes. */
  input[type="date"]{-webkit-appearance:none;appearance:none;overflow:hidden;}

  .split{grid-template-columns:1fr !important;}
}

/* ============================================================
   Role-based visibility — body gets is-admin/scope-own-vehicle from each
   page's own auth bootstrap script (backend is the real enforcement; this
   is just UI polish so no one sees a button that would 403 anyway).
   Generalized past the 3 built-in roles: is-admin covers any admin role,
   scope-own-vehicle covers Driver AND any custom own-vehicle-scoped role.
   ============================================================ */
body:not(.is-admin) .admin-only,
body.scope-own-vehicle .driver-hidden{display:none !important;}

/* Text-sized icons from the Lucide sprite (assets/icons/icons.svg) that replaced characters such as ✕ and →. */
svg.i{display:inline-block;vertical-align:-0.125em;flex-shrink:0;}

/* Plan locks and limits (nav.js PlanUi): a page the plan doesn't include stays in the menu with a
   lock; a slim amber notice when a limit is near. */
.plan-locked{opacity:.62;}
.plan-locked:hover{opacity:.85;}
.plan-lock-ico{margin-left:auto;flex-shrink:0;color:var(--muted);}
.nav-item .plan-lock-ico,.nav-subitem .plan-lock-ico{margin-left:auto;}
.tab-btn .plan-lock-ico{margin-left:6px;vertical-align:-1px;}
.limit-banner{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:6px 16px;
  padding:8px 44px 8px 20px;background:var(--amber-bg);border-bottom:1px solid var(--amber-border);color:var(--amber);
  font-size:12.5px;font-weight:600;text-align:center;position:relative;}
.limit-banner a{font-weight:700;color:inherit;text-decoration:underline;white-space:nowrap;}
/* The Master Admin's announcement bar: same shape as the limit notice, blue or amber. */
.announce-banner{display:flex;align-items:center;justify-content:center;gap:6px 16px;padding:8px 44px 8px 20px;font-size:12.5px;
  font-weight:600;text-align:center;position:relative;border-bottom:1px solid var(--blue-border);background:var(--blue-bg);color:var(--blue-bright);}
.announce-banner.warning{background:var(--amber-bg);border-bottom-color:var(--amber-border);color:var(--amber);}
.announce-banner button{position:absolute;right:12px;top:50%;transform:translateY(-50%);border:none;background:transparent;
  color:inherit;font-size:18px;line-height:1;cursor:pointer;padding:2px 6px;}
.limit-banner button{position:absolute;right:12px;top:50%;transform:translateY(-50%);border:none;background:transparent;
  color:inherit;font-size:18px;line-height:1;cursor:pointer;padding:2px 6px;}
.soon-tag{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:2px 8px;border-radius:var(--radius-pill);background:var(--blue-bg);color:var(--blue-bright);border:1px solid var(--blue-border);white-space:nowrap;}
.notify-btn{font-size:12px;font-weight:700;padding:5px 11px;border-radius:var(--radius-pill);border:1px solid var(--line-strong);
  background:var(--surface);color:var(--ink);cursor:pointer;white-space:nowrap;}
.notify-btn:hover{border-color:var(--blue);color:var(--blue-bright);}
.notify-btn[disabled]{cursor:default;opacity:.7;}
