:root{
  --avocado:#5a7f22; --avocado-dark:#3e5c14; --avocado-light:#eef4e2;
  --yellow:#f5c518; --ink:#14210a; --muted:#5c6b52; --line:#dde5d2;
  --bg:#ffffff; --card:#f7faf2; --danger:#b42318;
}
*{box-sizing:border-box}
/* Hidden must actually mean hidden: without this, author display
   rules (.row flex, .grid grid, .add-btn block, .badge
   inline-block) override the browser's built-in hidden behaviour,
   and admin-only rows/buttons could still show when logged out. */
[hidden]{display:none !important}
body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,Arial,sans-serif;color:var(--ink);background:var(--bg);line-height:1.45}
.top{display:flex;justify-content:space-between;align-items:center;gap:.75rem;padding:.9rem 1rem;max-width:960px;margin:0 auto;position:sticky;top:0;background:rgba(255,255,255,.96);z-index:5;border-bottom:1px solid var(--line)}
.brand{display:flex;align-items:center;gap:.7rem;min-width:0}
.brand img{width:auto;height:56px;max-width:220px;object-fit:contain;flex:0 0 auto}
.logo-btn{background:none;border:0;padding:0;cursor:pointer;line-height:0;flex:0 0 auto}
.logo-btn:focus-visible{outline:2px solid var(--avocado);outline-offset:3px;border-radius:8px}
.brand h1{margin:0;font-size:1.35rem;line-height:1.1}
.brand .sub{color:var(--muted);margin:.15rem 0 0;font-size:.9rem}
/* Header is one short row on phone and desktop: logo on the
   left, blue bin + ☰ Menu on the right, no wrapping. Every
   other action (Admin / Log out, Manage categories, What's
   out, Refresh, Share / Export) lives stacked on top of each
   other inside the Menu dropdown, which overlays the page
   instead of pushing the header taller or covering content. */
.top-actions-always{display:flex;gap:.5rem;flex-wrap:nowrap;justify-content:flex-end;align-items:center}
#pullCartBtn{white-space:nowrap;padding:.45rem .6rem}
/* Admin / Log out sit grouped with the Menu button on the right,
   not spaced out in the middle between the logo and the menu. */
.top-right{display:flex;gap:.5rem;align-items:center;margin-left:auto;flex-wrap:nowrap;justify-content:flex-end}
.top{display:flex;justify-content:space-between;align-items:center;gap:.5rem;padding:.6rem 1rem}
.brand img{height:48px;max-width:180px}
#menuBtn{white-space:nowrap}
#menuBtn{display:inline-block}
.top-actions{display:none}
.top-actions.open{display:flex;flex-direction:column;position:absolute;top:100%;right:1rem;background:#fff;border:1px solid var(--line);border-radius:16px;padding:.6rem;box-shadow:0 16px 40px rgba(0,0,0,.16);z-index:10;min-width:260px}
.top-actions.open .icon-btn{width:100%;text-align:left;justify-content:flex-start}
h1{margin:0} h2{font-size:1.3rem;margin:.5rem 0} h3{margin:1.25rem 0 .5rem}
main{max-width:960px;margin:0 auto;padding:0 1rem 2.5rem}
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.85rem;margin:1rem 0}
.tile,.card{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:1.05rem;text-align:left;cursor:pointer;font:inherit;min-height:88px}
.tile:hover,.card:hover{border-color:var(--avocado);box-shadow:0 4px 14px rgba(90,127,34,.12)}
.tile b{display:block;font-size:1.02rem}
.tile span,.path,.hint{color:var(--muted);font-size:.9rem}
.search{display:flex;gap:.5rem;align-items:center;border:1.5px solid var(--line);border-radius:999px;padding:.7rem 1rem;margin:1.1rem 0;background:#fff}
.search:focus-within{border-color:var(--avocado);box-shadow:0 0 0 3px var(--avocado-light)}
.search input{border:0;outline:0;flex:1;font-size:1rem;min-width:0}
.add-btn{display:block;width:100%;min-height:52px;padding:.9rem;background:var(--avocado);color:#fff;border:0;border-radius:14px;font-size:1.05rem;font-weight:700;cursor:pointer}
.add-btn:hover{background:var(--avocado-dark)}
/* Home Add, 2026-11-03: large full-width button replaced by a
   small green + beside the search bar, same id (addBtn) so the
   admin-only show/hide and the Add dialog open unchanged. */
.home-search-row{display:flex;gap:.5rem;align-items:stretch;margin:1.1rem 0}
.home-search-row .search{flex:1 1 auto;margin:0;min-width:0}
.home-add-btn{flex:0 0 auto;width:52px;background:var(--avocado);color:#fff;border:0;border-radius:999px;font-size:1.6rem;font-weight:700;line-height:1;padding:0;cursor:pointer}
.home-add-btn:hover{background:var(--avocado-dark)}
button{cursor:pointer;min-height:44px}
.icon-btn,.back{background:#fff;border:1px solid var(--line);border-radius:999px;padding:.55rem .95rem;font:inherit}
.primary{background:var(--avocado);color:#fff;border:0;border-radius:12px;padding:.75rem 1.1rem;font-weight:700}
.danger{background:var(--danger);color:#fff;border:0;border-radius:12px;padding:.75rem 1.1rem;font-weight:700}
.card img{width:100%;height:130px;object-fit:cover;border-radius:10px;background:#eef4e2}
.badge{display:inline-block;background:#e6f2d8;border:1px solid #bcd69a;color:#2f5210;border-radius:999px;padding:.2rem .65rem;font-size:.8rem;font-weight:600}
.badge.out{background:#fdeeee;border-color:#f0c9c9;color:#7a1f1a}
.row{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:1rem;align-items:center}
.row button{flex:1 1 auto}
dialog{border:1px solid var(--line);border-radius:18px;padding:1.35rem;max-width:540px;width:calc(100% - 2rem);box-shadow:0 16px 40px rgba(0,0,0,.16)}
dialog label{display:block;margin:.8rem 0;font-weight:600}
dialog input, dialog select, dialog textarea{width:100%;padding:.7rem;border:1px solid var(--line);border-radius:10px;margin-top:.3rem;font:inherit;font-weight:400}
.stepper{display:flex;gap:.3rem;align-items:center}
.stepper input{flex:1;text-align:center}
.stepper button{padding:.6rem 1.1rem}
.notice{background:#fff8d6;border:1px solid #f0d95a;border-radius:12px;padding:.8rem;margin:1rem 0}
footer{max-width:960px;margin:0 auto;padding:0 1rem 2rem;color:var(--muted)}
.unit-photo{font-size:.85rem}
.admin-note{color:var(--muted);font-size:.9rem;background:var(--avocado-light);border-radius:10px;padding:.65rem .8rem}
.out-group{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:1rem 1.1rem;margin:1rem 0}
.out-group h3{margin:.25rem 0 .75rem}
.out-row{display:flex;gap:.75rem;justify-content:space-between;align-items:center;border-top:1px solid var(--line);padding:.7rem 0}
.out-row:first-of-type{border-top:0;padding-top:.25rem}
.out-row button{flex:0 0 auto;background:#fff;border:1px solid var(--line);border-radius:999px;padding:.55rem .95rem;font:inherit}
.small{color:var(--muted);font-size:.85rem}
@media (max-width:520px){
  .top{padding:.5rem .75rem;gap:.4rem}
  .brand img{height:40px;max-width:150px}
  .icon-btn{padding:.45rem .7rem}
  .brand h1{font-size:1.15rem}
  .brand .sub{display:none}
  .grid{grid-template-columns:repeat(2,1fr);gap:.65rem}
  /* Phone: menu dropdown stretches full width under the header. */
  .top-actions.open{left:1rem;right:1rem;min-width:auto}
}
/* Image pop-out: larger than a card thumbnail, but not huge —
   capped back from 900px so a small item photo does not blow
   up to fill the screen. */
#lightboxDialog{max-width:min(92vw,640px);width:min(92vw,640px)}
#lightboxDialog img{width:100%;height:auto}
/* Tint, in the category Background pop-up: one inline row under
   the texture/pattern choice — just "Tint", a tick box, and the
   colour swatch — not a full-width checkbox with a colour row
   underneath it. */
.tint-row{display:flex;align-items:center;gap:.6rem;margin:.8rem 0;font-weight:600}
.tint-row input[type="checkbox"]{width:auto;margin:0}
.tint-row input[type="color"]{width:44px;height:44px;padding:.3rem;margin:0}
.tint-row #catBgTintColorWrap{display:flex;align-items:center}
.tint-row #catBgTintColorWrap[hidden]{display:none}
/* Price, on cards, in detail, and on individual units: bold,
   full size again — the smaller version was too small to read.
   Categories and sub-categories never get a price — items and
   units only. */
.price-tag{font-weight:700;font-size:1rem}
.price-ask{color:#555;font-style:italic;font-weight:400}
/* Item pop-up gear menu: stacked buttons, inside the dialog. */
.popup-menu{background:#fff;border:1px solid var(--line);border-radius:12px;padding:.5rem;box-shadow:0 4px 16px rgba(0,0,0,.12);display:flex;flex-direction:column;gap:.5rem;margin-top:.5rem}
#itemPopupDialog{position:relative}
#itemPopupXBtn{position:absolute;top:.6rem;right:.6rem;width:44px;height:44px;padding:0;border-radius:999px;background:#fff;border:1px solid var(--line);box-shadow:0 2px 8px rgba(0,0,0,.12);font-size:1.4rem;line-height:1;z-index:2}
.popup-menu button{width:100%}
/* Rent out, everywhere: a flat bright avocado-yellow pill —
   the yellow from avocado flesh, different from green Edit and
   red Delete, still sleek, no gradient/shadow. Dark text, so
   it stays readable on yellow. Single-item detail gets a bigger
   version, right under the item details and above Edit/Delete,
   instead of buried below. */
.rent-btn{background:#ffcf00;color:#1a2e05;border:0;border-radius:999px;padding:.4rem .8rem;font-size:.85rem;font-weight:700}
.rent-btn:hover{background:#eab800}
#singleRentWrap{margin:1rem 0}
#singleRentWrap .rent-btn{padding:.55rem 1rem;font-size:.9rem}
.card .rent-btn{margin-top:.5rem}
/* Mark returned, everywhere: a flat grey pill, so it never
   looks like a plain box button or like Rent out. */
.return-btn{background:#4b5563;color:#fff;border:0;border-radius:999px;padding:.6rem 1.1rem;font:inherit;font-weight:700}
.return-btn:hover{background:#374151}
/* Rented-out things never disappear: fully-out item cards and
   rented unit cards stay in place, just greyed out. */
.card.all-out{opacity:.55}
.card.all-out img{filter:grayscale(1)}
/* Edit / Delete / Add-item action pills: small, sized to their
   text, same compact pill style — not stretched across the row
   by the .row flex rule. Applies to item detail actions, the
   Add-item rows in category/item views, and every button row
   inside Manage categories. */
#detailActions button,#subAdminRow button,#itemsAdminRow button,.out-group .row button{flex:0 0 auto;border-radius:999px;padding:.55rem 1rem}
/* Category / sub-category pills: size to the name, not a uniform
   grid box. Short names get a short pill, long names a wider one
   (very long names wrap inside the pill and grow taller). Item
   cards in itemsGrid keep the old grid layout — this is only for
   the main and sub-category lists. */
/* Tiles are small squares, not pills: a grid of centred square
   tiles, picture/icon on top, name and count below, rounded
   16px corners — never a wide pill stretched to the text. */
#categoryGrid,#subGrid,#subSubGrid,#itemsGrid,#searchResults .grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:.8rem;align-items:stretch}
#categoryGrid .tile,#subGrid .tile,#subSubGrid .tile,#itemsGrid .tile,#searchResults .tile{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;border-radius:16px;padding:1rem .75rem;min-height:160px;gap:.45rem;box-shadow:0 2px 8px rgba(0,0,0,.04)}
#categoryGrid .tile b,#subGrid .tile b,#subSubGrid .tile b,#itemsGrid .tile b,#searchResults .tile b{display:block;font-size:1.02rem;line-height:1.25;text-align:center}
#categoryGrid .tile span,#subGrid .tile span,#subSubGrid .tile span,#itemsGrid .tile span,#searchResults .tile span{text-align:center}
#categoryGrid .tile b,#subGrid .tile b{white-space:normal}
#categoryGrid .tile span,#subGrid .tile span{display:block}
/* Cart badge is blue, to match the cart icon, distinct from
   yellow Rent out, green Edit, red Delete, and grey Return. */
.rent-btn{margin-right:.5rem}
#pullView .pull-row{display:flex;gap:.75rem;align-items:center;border-top:1px solid var(--line);padding:.7rem 0}
#pullView .pull-row:first-of-type{border-top:0}

/* Main categories tryout: clean icon cards, not a pattern,
   not a colour wash, not a picture. White card, thin border,
   dark line icon, name + count below. Sub tiles unchanged. */
#categoryGrid .main-icon-tile{flex:1 1 140px;max-width:220px;width:auto;min-height:0;border-radius:16px;padding:1rem .75rem;text-align:center;background:#fff;border:1px solid var(--line);box-shadow:0 2px 8px rgba(0,0,0,.04)}
#categoryGrid .main-icon-tile:hover{border-color:var(--avocado);box-shadow:0 4px 14px rgba(90,127,34,.12)}
#categoryGrid .main-icon-tile .main-icon{display:block;margin:0 auto .5rem;color:#14210a}
#categoryGrid .main-icon-tile .main-icon svg{width:44px;height:44px;display:block;margin:0 auto}
#categoryGrid .main-icon-tile b{display:block;font-size:1rem;line-height:1.2}
#categoryGrid .main-icon-tile .count{display:block;color:var(--muted);font-size:.85rem;margin-top:.25rem}

/* Individual items: small square tile, square photo on top,
   name, qty/available and badge below — not a pill, and not
   a big card, so a whole sub-category fits on a phone screen
   without zooming out. */
#itemsGrid .item-tile,#searchResults .item-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:.45rem;padding:1rem .75rem;background:#fff}
#itemsGrid .item-tile img,#searchResults .item-tile img{width:96px;height:96px;flex:0 0 auto;object-fit:cover;border-radius:14px;background:#eef4e2}
#itemsGrid .item-tile .item-tile-text,#searchResults .item-tile .item-tile-text{display:block;text-align:center}
#itemsGrid .item-tile b,#searchResults .item-tile b{display:block;font-size:1.02rem;line-height:1.25;text-align:center}
#itemsGrid .item-tile .qty,#searchResults .item-tile .qty{display:block;color:var(--muted);font-size:.9rem;text-align:center}
#itemsGrid .item-tile .badge,#searchResults .item-tile .badge{display:inline-block;margin-top:.15rem}
#itemsGrid .item-tile.all-out,#searchResults .item-tile.all-out{opacity:.55}
#itemsGrid .item-tile.all-out img,#searchResults .item-tile.all-out img{filter:grayscale(1)}

/* Generic "no image" placeholder, wherever a photo is missing:
   grey box with a crossed-out picture icon. Same look in item
   tiles, unit cards, checkout, What's out, and Edit — so a
   missing photo reads as a placeholder, not a blank hole. */
.no-photo-thumb{display:inline-flex;align-items:center;justify-content:center;background:#eef2ea;border:1px solid var(--line);color:#8a9a8a;flex:0 0 auto}
.no-photo-thumb svg{width:60%;height:60%;display:block}
#itemsGrid .no-photo-thumb,#searchResults .no-photo-thumb{width:96px;height:96px;border-radius:14px}
.no-photo-large{width:100%;height:180px;border-radius:12px;background:#eef2ea;border:1px solid var(--line);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;color:#8a9a8a}
.no-photo-large svg{width:48px;height:48px}
.no-photo-large span{font-size:.9rem;font-style:italic}
.no-photo-unit{width:100%;height:130px;border-radius:10px;background:#eef2ea;border:1px solid var(--line);display:flex;align-items:center;justify-content:center;color:#8a9a8a}
.no-photo-unit svg{width:44px;height:44px}
/* Sub-category tiles: small square, generic icon on top
   (subs have no picture upload, so they always show the
   generic icon), name and count below, centred. */
#subGrid .sub-tile,#subSubGrid .sub-tile,#searchResults .sub-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:.45rem;box-shadow:0 2px 8px rgba(0,0,0,.04)}
#subGrid .sub-icon,#subSubGrid .sub-icon,#searchResults .sub-icon{flex:0 0 auto;color:#14210a;display:inline-flex}
#subGrid .sub-icon svg,#subSubGrid .sub-icon svg,#searchResults .sub-icon svg{width:48px;height:48px;display:block}
#subGrid .sub-tile-text,#subSubGrid .sub-tile-text,#searchResults .sub-tile-text{display:block;text-align:center}

/* Drag and move: lifted tile, ghost following the finger/cursor,
   drop targets. Admin only — public view never gets draggable tiles. */
.tile.dragging{opacity:.4}
.tile{-webkit-touch-callout:none}
.drag-ghost{position:fixed;z-index:100;pointer-events:none;opacity:.95;transform:rotate(-2deg) scale(1.02);box-shadow:0 12px 30px rgba(0,0,0,.25)}
body.dragging{user-select:none;-webkit-user-select:none}
.tile.drop-into{outline:3px solid var(--avocado);outline-offset:2px;background:var(--avocado-light) !important}
.tile.drop-before{box-shadow:-4px 0 0 var(--avocado)}
.tile.drop-after{box-shadow:4px 0 0 var(--avocado)}

/* Photos never spill over a tile/card border, even with a stale
   stylesheet: clip at the tile edge, and cap images at the tile. */
.tile, .card{overflow:hidden}
.tile img, .card img{max-width:100%;-webkit-user-drag:none;user-select:none;-webkit-user-select:none}

/* Main-category tiles: small squares, AI picture on top,
   name + count below, white card. Photo is a small square,
   not a full-width banner, and never spills over, even with
   a stale stylesheet. */
#categoryGrid .main-pic-tile{border-radius:16px;padding:1rem .75rem;text-align:center;background:#fff;border:1px solid var(--line);box-shadow:0 2px 8px rgba(0,0,0,.04)}
#categoryGrid .main-pic-tile:hover{border-color:var(--avocado);box-shadow:0 4px 14px rgba(90,127,34,.12)}
#categoryGrid .main-pic-tile img{width:96px;height:96px;object-fit:cover;display:block;margin:0 auto .5rem;border-radius:14px}
#categoryGrid .main-pic-tile b{display:block;font-size:1.02rem;line-height:1.25;padding:0;text-align:center}
#categoryGrid .main-pic-tile .count{display:block;color:var(--muted);font-size:.9rem;padding:0;text-align:center}
/* Item pop-up: picture, name, price and location, compact. */
#itemPopupDialog{max-width:min(92vw,420px);width:min(92vw,420px)}
#itemPopupPhotoWrap img{width:100%;max-height:280px;object-fit:cover;border-radius:12px;cursor:zoom-in;display:block}
#itemPopupActions button{flex:0 0 auto;border-radius:999px;padding:.55rem 1rem}

/* Category tiles: chevron marks a tile that goes deeper, unlike an item tile. */
.cat-chevron{font-size:1.6rem;line-height:1;color:var(--avocado)}

/* Stamp squares and pills, 2026-11-03: mains and subs are bigger
   squares with a large icon in the middle; sub-subs are compact
   pills with a small icon on the left. Backgrounds set in Manage
   categories still draw on the squares, via catTileStyle. */
#categoryGrid .sub-icon{display:block;margin:0 auto .5rem}
#categoryGrid .sub-icon svg{width:48px;height:48px;display:block;margin:0 auto}
#categoryGrid .sub-icon .initial{width:48px;height:48px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:1.4rem}
#subGrid .sub-icon .initial,#subSubGrid .sub-icon .initial,#searchResults .sub-icon .initial{width:48px;height:48px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:1.4rem}
.subsub-pill{display:flex;align-items:center;gap:.55rem;background:#f7faf2;border:1px solid var(--line);border-radius:999px;padding:.45rem .85rem .45rem .55rem;text-align:left}
.subsub-pill .pill-icon svg{width:24px;height:24px;display:block;color:#14210a}
.subsub-pill .pill-icon .initial{width:24px;height:24px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-weight:700;font-size:.95rem}
.pill-wrap{display:flex;flex-wrap:wrap;gap:.5rem}

/* Larger, nicer Due date fields and in-app calendar. */
dialog input[type="date"]{font-size:1.15rem;padding:.9rem .85rem;min-height:52px;border-radius:12px}
dialog input[type="date"]::-webkit-calendar-picker-indicator{width:26px;height:26px;cursor:pointer;opacity:.75}
dialog input[type="date"]:focus{border-color:var(--avocado);box-shadow:0 0 0 3px var(--avocado-light);outline:0}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:.35rem}
.cal-weekday{text-align:center;font-size:.85rem;color:var(--muted);font-weight:700;padding:.25rem 0}
.cal-day{min-height:48px;border:1px solid var(--line);border-radius:12px;background:#fff;font-size:1.05rem;cursor:pointer;padding:.25rem}
.cal-day.cal-empty{border:0;background:transparent;cursor:default}
.cal-day.cal-today{border-color:var(--avocado);box-shadow:0 0 0 2px var(--avocado-light);font-weight:700}
.cal-day.cal-selected{background:var(--avocado);color:#fff;border-color:var(--avocado);font-weight:700}

/* Item pop-up: View full item is a small link now, not a big pill,
   so Rent out stays the primary action. Tap target stays 44px tall. */
.item-view-link{background:none;border:0;color:var(--avocado);text-decoration:underline;text-underline-offset:3px;font-size:.95rem;font-weight:600;padding:.5rem 0;min-height:44px;flex:0 0 auto;text-align:left;cursor:pointer}
#itemPopupGearBtn{flex:0 0 auto}

/* Corner X on every pop-up, same as the item pop-up X. */
.dialog-x{position:absolute;top:.6rem;right:.6rem;width:44px;height:44px;padding:0;border-radius:999px;background:#fff;border:1px solid var(--line);box-shadow:0 2px 8px rgba(0,0,0,.12);font-size:1.4rem;line-height:1;z-index:2}
dialog h2{padding-right:3.25rem}

/* Device QR codes (v107): one code per phone / iPad / computer unit.
   The QR page prints as labels only — the header, menu and buttons
   stay off the printed page. */
.qr-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:1rem}
.qr-card{border:1px solid var(--line);border-radius:14px;padding:1rem;text-align:center;background:#fff}
.qr-card .qr-img{display:flex;justify-content:center;margin:.6rem 0}
.qr-card .qr-img img,.qr-card .qr-img canvas{image-rendering:pixelated}
.unit-highlight{outline:3px solid var(--avocado) !important;outline-offset:2px}
@media print{
  body *{visibility:hidden !important}
  #qrView,#qrView *{visibility:visible !important}
  #qrView{position:absolute;left:0;top:0;width:100%}
  #qrView .back,#qrPrintBtn{display:none !important}
  .qr-card{break-inside:avoid;page-break-inside:avoid}
}
