/* SmartStoring — rebuilt UI, keeping the shape and colours of the ASP system. */

:root {
  --ink: #333;
  --head: #054477;
  --blue: #034d86;
  --link: #1f6fb2;
  --line: #d4dbe2;
  --soft: #f3f6f9;
  --bar: #e8eef5;
  --panel: #fff;
  --radius: 4px;
}

* { box-sizing: border-box; }

/* Any `display` we set beats the hidden attribute, which has bitten the cookie
   bar and the wishlist panel. Say it once, here, for every element. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: #fff;
  color: var(--ink);
  font: 13px/1.5 Arial, "Helvetica Neue", Helvetica, sans-serif;
}

a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
img { border: 0; }

.page { max-width: 1180px; margin: 0 auto; padding: 16px 12px 40px; }

/* ---------------------------------------------------------------- cookie bar */
.cookiebar {
  background: #111; color: #fff; padding: 12px 16px; font-size: 12px;
  display: flex; gap: 16px; align-items: center; justify-content: center;
}
.cookiebar button {
  background: transparent; color: #fff; border: 1px solid #fff;
  padding: 7px 22px; cursor: pointer; font: inherit;
}
.cookiebar button:hover { background: #fff; color: #111; }

/* -------------------------------------------------------------------- header */
.brand { padding: 14px 0 10px; }
.brand img { display: block; height: 62px; width: auto; }

/* --------------------------------------------------------------------- frame */
.frame { border: 1px solid var(--line); background: var(--panel); }
.frame-cols { display: flex; align-items: stretch; }
.col-side { width: 260px; flex: 0 0 260px; border-inline-end: 1px solid var(--line); }

/* The basket and the file tree follow you down the page. The column itself
   still stretches, so the divider between the two columns is unbroken; it is
   the contents that stick. When they are taller than the window they get their
   own scrollbar instead of running off the bottom out of reach. */
.sidesticky {
  position: sticky; top: 0;
  max-height: 100vh; overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin;
}
.sidesticky::-webkit-scrollbar { width: 8px; }
.sidesticky::-webkit-scrollbar-thumb { background: #c6d2de; border-radius: 4px; }
.sidesticky::-webkit-scrollbar-thumb:hover { background: #a9bacb; }
/* a short page has nothing to scroll past, so do not pin it there */
@media (max-height: 420px) { .sidesticky { position: static; max-height: none; overflow: visible; } }
.col-main { flex: 1 1 auto; min-width: 0; }

.box { border-bottom: 1px solid var(--line); padding: 14px 16px; }
.box h2 {
  margin: 0 0 10px; font-size: 15px; color: var(--head); font-weight: bold;
  border-bottom: 1px solid var(--line); padding-bottom: 6px;
}

/* ---------------------------------------------------------------- top menu */
/* The menu and the search bar stay with you while the page scrolls; the banner
   is not part of that — it scrolls away behind them. --stickytop is the menu's
   own height, measured in base_app.html, so the search bar lands right under it
   however the menu happens to wrap. */
.topmenu {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 13px;
  position: sticky; top: 0; z-index: 520; background: var(--panel);
}
.topmenu .sep { color: #b9c4cf; }
.topmenu .spacer { flex: 1 1 auto; }
.topmenu form { display: inline; margin: 0; }
.topmenu .linkbtn {
  background: none; border: 0; padding: 0; font: inherit; color: var(--link); cursor: pointer;
}
.topmenu .linkbtn:hover { text-decoration: underline; }
/* the old menu put a small GIF beside the link; the glyph now sits inside it */
.menuicon { display: inline-flex; align-items: center; gap: 5px; }
.menuicon svg { display: block; width: 16px; height: 16px; flex: 0 0 16px; }

/* On the signed-in pages the logo lives in the menu bar rather than above the
   frame, so the sticky header carries the branding and the page starts higher.
   The login and public pages keep the full-size one. */
.menubrand { display: inline-flex; align-items: center; flex: 0 0 auto; }
.menubrand img { display: block; height: 36px; width: auto; }
.scrolled .menubrand img { height: 28px; }

.banner { padding: 10px 16px; }
/* the artwork is 639px wide natively; stretch it to the column so there is no
   gap beside it, the way the old header filled its cell */
.bannerimg { display: block; width: 100%; height: auto; }

/* -------------------------------------------------------------- search bar */
/* The search, the view switch and bulk tagging all sit in the breadcrumb bar
   now, so three strips down the page became one. The search is collapsed to
   its icon like the buttons beside it, and opens on hover or when the field
   takes focus — the label is the opener, so none of this needs script. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

.barsearch { display: flex; align-items: center; position: relative; }
.barsearch .searchicon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 31px; height: 27px; border: 1px solid var(--line); border-radius: 14px;
  background: #fff; color: #5c6b7a; cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.barsearch .searchicon svg { display: block; width: 17px; height: 17px; }
.barsearch:hover .searchicon,
.barsearch:focus-within .searchicon,
.barsearch.stay .searchicon { background: var(--blue); border-color: var(--blue); color: #fff; }

.barsearch .searchbody {
  display: flex; align-items: center; gap: 5px;
  max-width: 0; overflow: hidden; opacity: 0;
  transition: max-width .18s ease, opacity .12s ease, padding .18s ease;
  padding-inline-start: 0;
}
.barsearch:hover .searchbody,
.barsearch:focus-within .searchbody,
.barsearch.stay .searchbody { max-width: 320px; opacity: 1; padding-inline-start: 6px; }

.barsearch .go {
  border: 1px solid var(--blue); border-radius: var(--radius); background: var(--blue);
  color: #fff; padding: 4px 11px; font: inherit; font-size: 12px; cursor: pointer;
}
.barsearch .go:hover { opacity: .9; }

/* the two scopes drop below the field, so the bar keeps its height */
.barsearch .scopes {
  display: none; position: absolute; top: calc(100% + 6px); inset-inline-start: 37px; z-index: 560;
  flex-direction: column; gap: 4px; padding: 9px 12px; white-space: nowrap;
  background: #fff; border: 1px solid #9fb0c0; border-radius: 5px;
  box-shadow: 0 8px 22px rgba(16, 32, 48, .18); font-size: 12px;
}
.barsearch:hover .scopes, .barsearch:focus-within .scopes { display: flex; }
/* the gap between the field and this panel is dead ground: crossing it on the
   way to the radios drops :hover and the panel disappears. This invisible strip
   spans the gap, so the pointer never leaves the form. It only exists while the
   panel is shown, so it cannot sit over anything else. */
.barsearch .scopes::before {
  content: ""; position: absolute; left: -40px; right: -40px; top: -10px; height: 10px;
}
.barsearch .scopes label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
  .barsearch .searchbody { transition: none; }
}

/* once the banner has scrolled past, tighten the two bars and lift them off
   the content with a shadow, so the header reads as one compact strip */
.scrolled .topmenu { padding-top: 8px; padding-bottom: 8px; }
.scrolled .crumbbar { box-shadow: 0 3px 8px rgba(16, 32, 48, .13); }
/* No transition on the menu's padding: the height has to settle in one frame,
   or --stickytop is measured mid-animation and the page shows through. */
.barsearch input[type=text] {
  padding: 5px 8px; border: 1px solid #a9bacb; width: 180px; min-width: 110px; font: inherit;
}

.btn {
  display: inline-block; width: auto;
  background: var(--blue); color: #fff; border: 0; border-radius: var(--radius);
  padding: 7px 16px; font: inherit; cursor: pointer;
}
.btn:hover { opacity: .9; text-decoration: none; color: #fff; }
.btn.secondary { background: #6c7a89; }

/* -------------------------------------------------------------- breadcrumb */
/* this is the bar that sticks now, and it carries the search and the icons */
.crumbbar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 7px 16px; background: var(--bar); border-bottom: 1px solid var(--line);
  position: sticky; top: calc(var(--stickytop, 41px) - 1px); z-index: 510;
}
/* The folder names are Latin, so in a Hebrew page the bidi algorithm resolves
   the whole path as one left-to-right run and the deepest folder ends up on the
   right — the path reads backwards. A flex row lays the segments out in the
   page's own direction instead, parent first, which is how the old file
   manager showed it. Each name still reads left-to-right inside its own box. */
.crumbbar .crumbs {
  font-weight: bold; color: var(--head);
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 5px;
}
.crumbbar .crumbs a { color: var(--head); }
.crumbbar .spacer { flex: 1 1 auto; }
/* An icon that tells you what it is when you reach for it: the label is there
   all along for a screen reader, and it slides open on hover or keyboard focus.
   max-width animates (width:auto cannot), and the value only has to be larger
   than the longest label. */
.pill {
  display: inline-flex; align-items: center;
  height: 27px; padding: 0; border: 1px solid var(--line); border-radius: 14px;
  background: #fff; color: #5c6b7a; font: inherit; cursor: pointer; text-decoration: none;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
  overflow: hidden; max-width: 100%;
}
.pill svg { display: block; width: 17px; height: 17px; flex: 0 0 17px; margin: 0 6px; }
.pill > span {
  max-width: 0; opacity: 0; white-space: nowrap; font-size: 12px;
  transition: max-width .18s ease, opacity .12s ease, padding .18s ease;
  padding-inline-end: 0;
}
.pill:hover, .pill:focus-visible { background: var(--blue); border-color: var(--blue); color: #fff; }
.pill:hover > span, .pill:focus-visible > span { max-width: 210px; opacity: 1; padding-inline-end: 10px; }
.pill:hover svg [stroke="#2e9e4f"], .pill:focus-visible svg [stroke="#2e9e4f"] { stroke: #fff; }
.pill.danger:hover, .pill.danger:focus-visible { background: #c0392b; border-color: #c0392b; }
/* direct children only: the bulk-tag dropdown is also a <form> in here,
   and this rule outranked the one that keeps it closed */
.crumbbar .tools > form { display: inline-flex; margin: 0; }
@media (prefers-reduced-motion: reduce) {
  .pill > span { transition: none; }
}

/* the rule separates the search from the view/action icons beside it */
.crumbbar .tools {
  display: flex; gap: 6px; align-items: center;
  border-inline-start: 1px solid #c3cfda; padding-inline-start: 9px; margin-inline-start: 2px;
}
.crumbbar .tools:empty { border: 0; padding: 0; margin: 0; }

/* The old toolbar was three 36x25 jpegs with the bevels baked into the pixels.
   These are the same three actions drawn as inline SVG, so they stay sharp on a
   retina screen and the button state lives in CSS instead of in the image. */
.iconbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 27px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; color: #5c6b7a; text-decoration: none;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.iconbtn:hover { background: #eaf2fa; border-color: #8fb0cd; color: var(--blue); }
.iconbtn:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }
.iconbtn.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.iconbtn svg { display: block; width: 17px; height: 17px; }

/* ------------------------------------------------------------ folder cards */
/* same treatment for the folder cards above the file list */
.cards {
  display: grid; gap: 14px; padding: 16px;
  grid-template-columns: repeat(auto-fill, minmax(172px, 1fr));
}
.card {
  border: 1px solid var(--line); background: #fff; min-width: 0;
  display: flex; flex-direction: column;
}
.card .cap {
  background: var(--soft); border-bottom: 1px solid var(--line);
  padding: 6px 8px; text-align: center; font-size: 12px; min-height: 30px;
}
.card .pic {
  height: 150px; display: flex; align-items: center; justify-content: center; padding: 8px;
}
.card .pic img { max-width: 100%; max-height: 134px; }
.card .foot {
  border-top: 1px solid var(--line); background: var(--soft);
  padding: 5px 8px; text-align: center; font-size: 11px; color: #6b7883;
}

/* -------------------------------------------------------------- asset list */
.assets { padding: 0 16px 16px; }

.arow { border: 1px solid var(--line); margin-top: 14px; }
.arow .head {
  background: var(--soft); border-bottom: 1px solid var(--line);
  padding: 7px 10px; font-weight: bold; color: #262f38;
}
.arow .body { display: flex; gap: 14px; padding: 12px 10px; align-items: flex-start; }
.arow .meta { flex: 1 1 auto; min-width: 0; }
.arow .thumb { flex: 0 0 150px; text-align: center; }
.arow .thumb img { max-width: 100%; max-height: 140px; }

.facts { display: flex; flex-wrap: wrap; gap: 6px 28px; margin-bottom: 12px; }
.facts div { min-width: 180px; }
.facts b { display: block; color: #262f38; }
.facts span { font-style: italic; color: #5d6a75; }

.actions {
  display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  background: #eef3f8; border: 1px solid #dde5ed; padding: 6px 8px; border-radius: 20px;
}
.actions form { display: inline-flex; margin: 0; }
.actions img { width: 34px; height: 34px; display: block; }
.actions .off { opacity: .35; cursor: default; }

/* The old row was eight 40x40 glossy GIFs. Same actions, drawn as inline SVG so
   the hover and disabled states are CSS instead of a second image. */
.actbtn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0;
  border: 1px solid transparent; border-radius: 50%;
  background: #fff; color: #4c5c6c; cursor: pointer; text-decoration: none;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.actbtn:hover { background: var(--blue); border-color: var(--blue); color: #fff; }
.actbtn:focus-visible { outline: 2px solid var(--link); outline-offset: 1px; }
.actbtn.danger:hover { background: #c0392b; border-color: #c0392b; }
.actbtn svg { display: block; width: 18px; height: 18px; }
/* the plus/minus accents are coloured on their own; invert them on hover */
.actbtn:hover svg [stroke="#2e9e4f"], .actbtn:hover svg [stroke="#c0392b"] { stroke: #fff; }

/* the add/remove pair live in the same button; the form's class picks one */
.when-in, .when-out { display: none; }
.basketform .when-out { display: block; }
.basketform.in-basket .when-in { display: block; }
.basketform.in-basket .when-out { display: none; }

/* --------------------------------------------------------------- lightbox */
.noscroll { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: 900;
  display: flex; flex-direction: column;
  background: rgba(14, 22, 31, .88);
}
.lbbar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; background: rgba(0, 0, 0, .35); color: #fff;
}
.lbtitle { font-weight: bold; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lbspacer { flex: 1 1 auto; }
.lbbtn {
  border: 1px solid rgba(255, 255, 255, .45); border-radius: 4px;
  background: none; color: #fff; padding: 5px 12px; font: inherit; cursor: pointer;
  text-decoration: none; line-height: 1.3;
}
.lbbtn:hover { background: rgba(255, 255, 255, .16); color: #fff; text-decoration: none; }
.lbclose { font-size: 20px; line-height: 1; padding: 2px 11px 5px; }
.lbstage {
  flex: 1 1 auto; display: flex; align-items: center; justify-content: center;
  padding: 18px; min-height: 0; cursor: zoom-out;
}
.lbstage img { max-width: 100%; max-height: 100%; cursor: default; box-shadow: 0 6px 34px rgba(0, 0, 0, .5); }
.lbspin {
  position: absolute; width: 34px; height: 34px; border-radius: 50%;
  border: 3px solid rgba(255, 255, 255, .3); border-top-color: #fff;
  animation: lbspin .8s linear infinite;
}
@keyframes lbspin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .lbspin { animation: none; } }

/* the e-mail form that opens under a file */
.sharepanel {
  margin-top: 10px; padding: 12px 14px; max-width: 520px;
  border: 1px solid #c3cfda; border-radius: 5px; background: #f8fbfe;
  display: flex; flex-direction: column; gap: 9px;
}
.sharepanel .sharehead { display: flex; align-items: center; gap: 7px; color: var(--head); }
.sharepanel .sharehead svg { width: 18px; height: 18px; display: block; }
.sharepanel .f { display: flex; gap: 10px; align-items: flex-start; }
.sharepanel .f > span:first-child { flex: 0 0 104px; padding-top: 5px; color: #4a5a68; font-size: 12px; }
.sharepanel .pick { flex: 1 1 auto; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.sharepanel input, .sharepanel select, .sharepanel textarea {
  padding: 6px 9px; border: 1px solid #a9bacb; font: inherit; width: 100%;
}
.sharepanel textarea { flex: 1 1 auto; resize: vertical; }
.sharepanel .note { margin: 0; color: #6b7883; font-size: 11.5px; }
.sharepanel .row { display: flex; gap: 8px; }
@media (max-width: 560px) {
  .sharepanel .f { flex-direction: column; gap: 4px; }
  .sharepanel .f > span:first-child { flex: none; padding: 0; }
}

.tags { margin-top: 10px; font-size: 12px; }
.tags b { display: block; color: #262f38; margin-bottom: 2px; }

/* -------------------------------------------------------------- asset grid */
/* a grid, not a wrapping flex row: the tracks share the leftover width so the
   last card reaches the edge, and the minimum keeps every action icon on one
   line instead of spilling onto a second */
.agrid {
  display: grid; gap: 14px; padding: 16px;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
}
.acard { border: 1px solid var(--line); display: flex; flex-direction: column; min-width: 0; }
.acard .cap {
  background: var(--soft); border-bottom: 1px solid var(--line); padding: 6px 8px;
  font-size: 12px; font-weight: bold; text-align: center;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.acard .pic { height: 185px; display: flex; align-items: center; justify-content: center; padding: 8px; }
.acard .pic img { max-width: 100%; max-height: 169px; }
/* slightly tighter buttons in a card, so seven of them still fit on one line
   at the grid's minimum track width */
.acard .actions {
  border-radius: 0; border: 0; border-top: 1px solid var(--line);
  justify-content: center; gap: 5px; padding: 6px 8px;
}
.acard .actions .actbtn { width: 30px; height: 30px; }
.acard .actions .actbtn svg { width: 17px; height: 17px; }

/* ------------------------------------------------------------------ paging */
.paging { padding: 12px 16px; font-size: 12px; color: #5d6a75; }
.paging a { padding: 0 3px; }
.paging .cur { font-weight: bold; color: #000; }

/* -------------------------------------------------------------------- tree */
.tree, .tree ul { list-style: none; margin: 0; padding: 0; }
.tree ul { margin-inline-start: 16px; }
.tree li { margin: 3px 0; }
.tree .row { display: flex; gap: 6px; align-items: center; }
.tree .twisty {
  width: 13px; height: 13px; line-height: 11px; text-align: center; cursor: pointer;
  border: 1px solid #9fb0c0; background: #fff; font-size: 11px; color: #456; flex: 0 0 13px;
}
.tree .twisty.blank { border: 0; background: none; cursor: default; }
.tree a { color: #262f38; font-weight: bold; }
.tree ul.collapsed { display: none; }

/* A folder marker in front of every node, blue, red on the folder you are
   standing in — the two states the legacy tree had (one GIF, two colours).

   baseline, not centre or flex-start: an SVG has no baseline of its own, so
   the browser uses its bottom edge, which stands the folder on the text's
   baseline. The icon's viewBox is trimmed to the glyph, so that bottom edge
   is the folder's own bottom and not empty space. */
.tree a.node { display: inline-flex; align-items: baseline; gap: 6px; }
/* font-size:0 matters: the span wraps the <svg> in template whitespace, and a
   stray text node would give the box a line box of its own, whose baseline
   would then be used instead of the icon's bottom edge. */
.tree .ficon { flex: 0 0 auto; display: inline-block; color: #3f7ba8; font-size: 0; line-height: 0; }
.tree .ficon svg { display: block; width: 17px; height: 14px; }
.tree .nname { min-width: 0; }
.tree a.node:hover .ficon { color: #034d86; }
.tree li.on > .row > a { color: #c0392b; }
.tree li.on > .row > a .ficon { color: #c0392b; }
.tree li.on > .row > a .fshape { fill: #fbe2de; }

/* The folder glyph has its tab on the leading edge, so it has to turn round
   with the text. Mirroring the drawing rather than keeping a second file
   means the two can never drift apart. Only glyphs that actually have a
   handedness get this — a chart or a tag looks wrong backwards. */
[dir="rtl"] .tree .ficon svg,
[dir="rtl"] .mirror-rtl svg { transform: scaleX(-1); }

/* edit mode switch */
.editmode { display: flex; gap: 8px; align-items: center; margin: -4px 0 10px; }
.editmode button {
  border: 1px solid #c3cfda; background: #fff; color: #3f5160;
  padding: 4px 11px; border-radius: 4px; font: inherit; font-size: 12px; cursor: pointer;
}
.editmode button:hover { background: #eef5fb; border-color: #8fb0cd; color: #034d86; }
.editmode button.exit { border-color: #d7a6a1; color: #a4190f; }
.editmode button.exit:hover { background: #fdecea; border-color: #c0392b; color: #a4190f; }
.editmode .badge {
  background: #c0392b; color: #fff; font-size: 11px; padding: 2px 8px; border-radius: 10px;
}

/* editing affordances, shown only in edit mode */
.tree .nodeops { display: none; gap: 2px; margin-inline-start: 4px; }
.tree .row:hover .nodeops, .tree .row:focus-within .nodeops { display: inline-flex; }
.tree .nodeops button {
  border: 1px solid #c3cfda; background: #fff; color: #5a6b7a;
  width: 18px; height: 18px; line-height: 1; padding: 0; border-radius: 3px;
  font-size: 11px; cursor: pointer;
}
.tree .nodeops button:hover { background: #eef5fb; border-color: #8fb0cd; color: #034d86; }
.tree .row[draggable=true] a { cursor: grab; }
.tree .row.dropok { outline: 2px solid #034d86; outline-offset: 1px; background: #eef5fb; }

.dragging { opacity: .45; }
.head[draggable=true], .cap[draggable=true] { cursor: grab; }

#dropmenu {
  position: absolute; z-index: 600; display: none;  /* above the sticky header */
  background: #fff; border: 1px solid #9fb0c0; border-radius: 4px;
  box-shadow: 0 6px 18px rgba(0,0,0,.18); padding: 4px; min-width: 150px;
}
#dropmenu button {
  display: block; width: 100%; text-align: start; background: none; border: 0;
  padding: 7px 10px; font: inherit; cursor: pointer; color: #26323d; border-radius: 3px;
}
#dropmenu button:hover { background: #eef5fb; }

#toast {
  position: fixed; inset-inline-end: 16px; bottom: 16px; z-index: 950;
  background: #26323d; color: #fff; padding: 11px 16px; border-radius: 5px;
  display: none; max-width: 340px; box-shadow: 0 6px 18px rgba(0,0,0,.25);
}
#toast.bad { background: #a4190f; }

/* -------------------------------------------------------------- tag cloud */
.cloud a { margin-inline-end: 6px; color: #4f4f4f; }
.cloud .sep { color: #9aa7b2; }

/* ------------------------------------------------------------------ basket */
.btable { width: 100%; border-collapse: collapse; }
.btable th, .btable td { padding: 9px 10px; border-bottom: 1px solid var(--line); text-align: start; }
.btable th { background: var(--soft); font-size: 12px; color: #4a5a68; }
.btable img.th { max-width: 72px; max-height: 60px; }

.bulk { display: flex; gap: 10px; flex-wrap: wrap; padding: 14px 16px; background: var(--soft); border-bottom: 1px solid var(--line); }
.bulk form { display: inline; margin: 0; }

/* ------------------------------------------------------------ bulk tagging */
/* bulk tagging: an icon in the bar, with the form dropping out of it, so it
   takes no vertical space until someone opens it */
.bulktags { position: relative; display: inline-flex; }
.bulktags .panel {
  display: none; position: absolute; top: calc(100% + 7px); inset-inline-end: 0; z-index: 560;
  width: 330px; max-width: 86vw; flex-direction: column; gap: 8px;
  padding: 12px; background: #fff; border: 1px solid #9fb0c0; border-radius: 5px;
  box-shadow: 0 8px 22px rgba(16, 32, 48, .2); text-align: start;
}
.bulktags.open .panel { display: flex; }
.bulktags .paneltitle { color: var(--head); font-size: 13px; }
.bulktags .panel .row { display: flex; gap: 8px; }
.bulktags input[type=text] { width: 100%; padding: 6px 9px; border: 1px solid #a9bacb; font: inherit; }
.bulktags .hint { color: #6b7883; font-size: 11.5px; line-height: 1.45; }
@media (max-width: 560px) { .bulktags .panel { inset-inline-end: auto; inset-inline-start: 0; } }

.msg { padding: 10px 16px; border-bottom: 1px solid var(--line); }
.msg.success { background: #e8f5e9; color: #1b5e20; }
.msg.error { background: #fdecea; color: #a4190f; }
.msg.info { background: #e8f1fb; color: #0d3d6b; }

.empty { color: #7b8893; padding: 24px 16px; }

/* ------------------------------------------------------------------- login */
/* Login box beside the banner, the way index.asp laid them out. The old form
   sat in a 119px frame next to a 139px image, so the two read as one band;
   everything below is kept tight to hold that. */
.loginwrap { display: flex; gap: 12px; align-items: flex-start; padding: 12px; flex-wrap: wrap; }
.loginbox { width: 320px; border: 1px solid var(--line); padding: 8px 12px; }
.loginbox h2 { margin: 0 0 5px; font-size: 15px; color: var(--head); border-bottom: 1px solid var(--line); padding-bottom: 3px; }
.loginbox .f { margin-bottom: 5px; display: flex; gap: 8px; align-items: center; }
.loginbox .f label { width: 84px; color: #262f38; }
.loginbox input[type=text], .loginbox input[type=password] {
  flex: 1 1 auto; padding: 2px 6px; border: 1px solid #a9bacb; background: #eef3f8; font: inherit;
}
.loginbox .btn { padding: 2px 14px; }
/* The old form had no password-reset link, so this line is the one thing
   standing between the box and the banner's height. Small and tight. */
.loginbox .forgot { margin: 4px 0 0; font-size: 12px; }

/* The banner takes whatever is left of the row, and drops below the box once
   there is less than 300px for it. */
.loginbanner { flex: 1 1 420px; min-width: 300px; }
.publicmenu {
  display: flex; gap: 20px; flex-wrap: wrap; align-items: center;
  padding: 10px 16px; background: var(--bar); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.welcome { padding: 18px; }
.welcome h3 { margin: 0 0 8px; color: #262f38; font-size: 14px; }

/* ------------------------------------------------------------------- zoom */
.zoomwrap { padding: 16px; text-align: center; }
.zoomwrap img { max-width: 100%; height: auto; border: 1px solid var(--line); }

/* ------------------------------------------------------------------ share */
.form-rows { padding: 16px; max-width: 620px; }
.form-rows .f { margin-bottom: 12px; }
.form-rows label { display: block; margin-bottom: 4px; color: #4a5a68; }
.form-rows input[type=text], .form-rows input[type=email], .form-rows select, .form-rows textarea {
  width: 100%; padding: 6px 8px; border: 1px solid #a9bacb; font: inherit;
}
.form-rows textarea { min-height: 110px; }

@media (max-width: 860px) {
  .frame-cols { display: block; }
  .col-side { width: auto; flex: none; border-inline-end: 0; border-bottom: 1px solid var(--line); }

  /* Stacked, so there is no second column for the panel to follow — and
     leaving it as its own 100vh scroller is what made the phone unscrollable
     after sign-in: the sidebar filled the screen, every drag landed inside it
     instead of on the page, and overscroll-behavior:contain stopped that
     scroll from chaining through. The catalogue below was unreachable. */
  .sidesticky {
    position: static; max-height: none; overflow: visible; overscroll-behavior: auto;
  }
}
