* { box-sizing: border-box; margin: 0; padding: 0; }

/* Self-hosted rather than pulled from a font CDN on every load - one less
   external dependency for a tool this business runs its day on. */
@font-face {
  font-family: 'Bebas Neue'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/fonts/bebas-neue-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400;
  font-display: swap; src: url('/fonts/inter-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('/fonts/inter-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('/fonts/inter-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700;
  font-display: swap; src: url('/fonts/inter-700.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500;
  font-display: swap; src: url('/fonts/ibm-plex-mono-500.woff2') format('woff2');
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 600;
  font-display: swap; src: url('/fonts/ibm-plex-mono-600.woff2') format('woff2');
}

/* ---------------------------------------------------------------------------
   Design system: a print shop's docket, not a SaaS dashboard.
   This app runs Molly's in-house print/design pipeline, so the visual
   language borrows from the artifacts of that world - job tickets, proof
   stamps, ledger sheets, halftone screening - rather than generic admin-
   panel chrome. One condensed poster face carries headlines, a mono face
   marks anything that reads like a docket number or a stamp, and a single
   navy accent (plus a lighter slate/sky tint scale) carries the brand.
   --------------------------------------------------------------------------- */
:root {
  --paper: #f3f5f7;
  --card: #ffffff;
  --ink: #384959;
  --muted: #6b7c8c;
  --line: #e3e7eb;
  --line-strong: #c2cbd3;

  --accent: #384959;
  --accent-dark: #24303b;
  --accent-tint: #e3effb;

  --stamp: #3f5b78;
  --stamp-tint: #bdddfc;

  --highlight: #88bdf2;

  --danger: #a8281c;
  --danger-dark: #841e15;

  --nav-height: 58px;
  --radius: 10px;
  --radius-sm: 6px;
  --radius-pill: 999px;
  --shadow: 0 1px 2px rgba(30, 41, 59, 0.04), 0 2px 8px rgba(30, 41, 59, 0.04);
  --shadow-lift: 0 6px 16px rgba(56, 73, 89, 0.12), 0 16px 34px rgba(56, 73, 89, 0.1);

  --font-display: 'Bebas Neue', 'Arial Narrow', sans-serif;
  --font-body: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', 'SFMono-Regular', Consolas, monospace;

  /* Custom curves for entering/exiting UI - the built-in `ease`/`ease-out`
     read as weak and don't give motion the punch of an intentional move. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
}

body {
  font-family: var(--font-body);
  background: var(--paper);
  color: var(--ink);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

p { line-height: 1.5; }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.icon { width: 14px; height: 14px; flex-shrink: 0; vertical-align: -2px; }

/* ---- nav ---- */
/* Sticky rather than translucent: it should stay reachable above a long
   settings table or ledger, but a frosted-glass surface would mix Apple's
   glass material language into a deliberately flat, ink-on-paper identity. */
nav {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--accent);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 20px;
  /* Nowrap by default: the section tabs (.nav-links) are the one item
     allowed to shrink and scroll internally (see below), so at in-between
     desktop widths the bar squeezes them instead of wrapping the whole nav
     onto a ragged second row. Only the phone layout below wraps by design. */
  flex-wrap: nowrap;
}
nav .brand {
  font-family: var(--font-display);
  font-size: 24px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 13px 18px 13px 0;
  order: 1;
}
nav .nav-links {
  display: flex; flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
  order: 2; scrollbar-width: none;
}
nav .nav-links::-webkit-scrollbar { display: none; }
nav a {
  color: rgba(255, 255, 255, 0.85);
  padding: 14px 12px;
  text-decoration: none;
  font-size: 13.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
  flex: 0 0 auto;
}
nav a:hover { color: #fff; background: rgba(0, 0, 0, 0.16); text-decoration: none; }
nav a.active { color: #fff; background: rgba(0, 0, 0, 0.16); text-decoration: none; box-shadow: inset 0 -3px 0 var(--highlight); }
nav .spacer { flex: 1; order: 3; min-width: 8px; }
/* Positioned so every menu panel below anchors to the whole icon cluster,
   not to its own individual trigger button - see the .nav-menu-panel
   comment for why that distinction matters. */
nav .nav-actions { display: flex; align-items: center; gap: 6px; order: 4; position: relative; }
nav button {
  background: none; border: 1px solid rgba(255, 255, 255, 0.45); color: #fff;
  padding: 6px 12px; border-radius: var(--radius-sm); cursor: pointer; font-size: 13px;
  font-weight: 600; letter-spacing: 0.02em;
}
nav button:hover { background: rgba(0, 0, 0, 0.16); }
nav .badge-count {
  background: #fff; color: var(--accent); border-radius: 10px;
  font-family: var(--font-mono); font-size: 11px; font-weight: 700; padding: 1px 7px; margin-left: 5px;
}

/* Icon-only nav utilities (settings, quick-add) - Xero-style chrome buttons
   that stay put instead of taking up a full text label's width, so the
   section tabs beside them have room to breathe at ordinary desktop widths. */
nav .icon-btn {
  display: flex; align-items: center; justify-content: center; position: relative;
  width: 34px; height: 34px; padding: 0; flex: 0 0 auto;
  border: 1px solid rgba(255, 255, 255, 0.45); border-radius: var(--radius-sm);
  color: rgba(255, 255, 255, 0.9); background: none; cursor: pointer;
}
nav .icon-btn:hover { color: #fff; background: rgba(0, 0, 0, 0.16); }
nav .icon-btn.active { color: #fff; background: rgba(0, 0, 0, 0.16); box-shadow: inset 0 -3px 0 var(--highlight); }
nav .icon-btn .icon { width: 18px; height: 18px; }
nav .icon-btn .badge-count { position: absolute; top: -6px; right: -6px; margin-left: 0; }

/* The account button: same square icon-btn footprint as settings/quick-add
   for visual rhythm, with a colour-initial circle standing in for an icon -
   a lighter-weight stand-in for a full avatar/org-switcher pattern. */
nav .avatar-initial {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--highlight); color: var(--accent-dark);
  font-family: var(--font-display); font-size: 13px; letter-spacing: 0.02em;
}

/* Deliberately NOT position:relative on .nav-menu itself - a panel anchored
   to its own trigger works fine on desktop, where every icon sits close
   together near the bar's right edge, but on the mobile layout the same
   cluster sits near the LEFT edge (right after the brand), so the
   right-most trigger's own right:0 anchor would push its panel off the
   right edge of the screen. Anchoring every panel to .nav-actions (the
   whole cluster) instead keeps them flush with the cluster's own edge
   regardless of which specific icon within it was clicked, which is
   on-screen in both layouts. */
nav .nav-menu-panel {
  display: none; flex-direction: column; position: absolute; top: calc(100% + 8px); right: 0;
  min-width: 210px; padding: 6px; margin: 0; background: var(--card); border-radius: var(--radius);
  box-shadow: var(--shadow-lift); z-index: 60;
}
nav .nav-menu-panel.open { display: flex; }
nav .nav-menu-panel a,
nav .nav-menu-panel button {
  display: flex; align-items: center; gap: 9px; padding: 10px 10px; border-radius: var(--radius-sm);
  color: var(--ink); font-size: 13.5px; font-weight: 600; letter-spacing: normal;
  width: 100%; background: none; border: none; text-align: left; cursor: pointer;
}
nav .nav-menu-panel a .icon { color: var(--muted); }
nav .nav-menu-panel a:hover,
nav .nav-menu-panel button:hover { background: var(--paper); color: var(--ink); }
nav .nav-menu-label {
  padding: 8px 10px 10px; font-size: 12.5px; color: var(--muted); font-weight: 600;
  border-bottom: 1px solid var(--line); margin-bottom: 4px;
}

main { max-width: 1180px; margin: 0 auto; padding: 28px 20px 60px; }
h1 {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 400;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  line-height: 1.15;
  margin-bottom: 20px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
}
h2 {
  font-family: var(--font-mono);
  font-size: 12.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--stamp);
  margin: 30px 0 12px;
  display: flex;
  align-items: center;
  gap: 7px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}
h2 .icon { color: var(--stamp); }

/* A real reference, not decoration - the request/artwork's own id, set like
   a docket number stamped in the corner of a job ticket. */
.job-tag {
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--stamp);
  background: var(--stamp-tint);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  padding: 3px 9px;
  letter-spacing: 0.03em;
}

/* ---- cards & tables ---- */
.card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow);
}

/* Dashboard stat strip: one floating card, stats divided internally rather
   than four separate boxes - closer to how Xero groups related numbers. */
.tiles-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; margin-bottom: 22px; }
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); }
.tile {
  padding: 18px 20px;
  display: flex; align-items: center; gap: 12px;
  border-right: 1px solid var(--line);
}
.tile:last-child { border-right: none; }
.tile .tile-icon { width: 38px; height: 38px; border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; background: var(--accent-tint); color: var(--accent); flex-shrink: 0; }
.tile .tile-icon .icon { width: 18px; height: 18px; }
.tile.warn .tile-icon { background: #f7ded9; color: var(--danger); }
.tile .n { font-family: var(--font-display); font-size: 30px; letter-spacing: 0.01em; line-height: 1.1; }
.tile .t { font-size: 12.5px; color: var(--muted); margin-top: 1px; }
.tile.warn .n { color: var(--danger); }

.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--radius); border: 1px solid var(--line); }
.table-scroll table { box-shadow: none; border: none; border-radius: 0; }
table { width: 100%; border-collapse: collapse; background: var(--card); border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); }
th, td { text-align: left; padding: 13px 14px; font-size: 14px; border-bottom: 1px solid var(--line); }
th {
  background: var(--card); font-family: var(--font-mono); font-size: 11px;
  text-transform: uppercase; letter-spacing: 0.07em; color: var(--muted); font-weight: 600;
  border-bottom: 1px solid var(--line-strong);
}
tr:last-child td { border-bottom: none; }
tr.overdue td { background: #fbeee9; }
tr { transition: background-color 0.12s ease; }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--paper); }
tr.overdue.clickable:hover td { background: #f6ddd2; }

/* ---- badges: outlined pills, not filled tiles ---- */
.badge {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 10px;
  border-radius: var(--radius-pill); font-family: var(--font-mono); font-size: 11px;
  font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap;
  border: 1.3px solid currentColor; background: transparent;
}
.badge.grey { color: var(--muted); }
.badge.blue { color: #1660b0; }
.badge.amber { color: #92640a; }
.badge.red { color: #b3400e; }
.badge.green { color: #1f7a2d; }
.badge.purple { color: #6a2d9c; }
.badge.darkgreen { color: #114d1c; }
.badge.outline { color: var(--muted); background: none; }

/* ---- empty states ---- */
.empty-state { text-align: center; padding: 40px 20px; color: var(--muted); }
.empty-state .empty-icon { width: 34px; height: 34px; color: var(--line-strong); margin-bottom: 10px; }
.empty-state p { font-size: 14px; margin-bottom: 10px; }

/* ---- forms ---- */
form.stack, .stack { display: flex; flex-direction: column; gap: 14px; max-width: 560px; }
label { font-size: 13px; font-weight: 600; color: var(--muted); display: block; margin-bottom: 5px; }
input, select, textarea {
  width: 100%; padding: 10px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
  font-size: 14px; font-family: inherit; background: #fafbfc; color: var(--ink);
  transition: border-color 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-tint); background: var(--card);
}
textarea { min-height: 80px; resize: vertical; }
button {
  font-family: var(--font-body); transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.14s var(--ease-out);
}
button.primary, .btn {
  background: var(--accent); color: #fff; border: none; padding: 10px 20px;
  border-radius: var(--radius-pill); font-size: 13.5px; font-weight: 700; letter-spacing: 0.01em;
  cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
}
button.primary:hover, .btn:hover { background: var(--accent-dark); }
button.secondary {
  background: var(--card); color: var(--ink); border: 1px solid var(--line-strong);
  padding: 9px 18px; border-radius: var(--radius-pill); font-size: 13.5px; font-weight: 600;
  letter-spacing: 0.01em; cursor: pointer;
  display: inline-flex; align-items: center; gap: 6px;
}
button.secondary:hover { border-color: var(--stamp); background: var(--paper); }
button.danger {
  background: var(--danger); color: #fff; border: none; padding: 10px 20px;
  border-radius: var(--radius-pill); font-size: 13.5px; font-weight: 700; letter-spacing: 0.01em;
  cursor: pointer;
}
button.danger:hover { background: var(--danger-dark); }
button:active:not(:disabled) { transform: scale(0.98); }
button:disabled { opacity: 0.55; cursor: not-allowed; }
.error { background: #f8e4de; color: var(--danger); padding: 10px 14px; border-radius: var(--radius-sm); font-size: 14px; display: none; align-items: center; gap: 8px; border: 1px solid #eec7ba; }
.muted { color: var(--muted); font-size: 13px; }

/* ---- spinner ---- */
.spinner {
  display: inline-block; width: 13px; height: 13px; border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.4); border-top-color: currentColor;
  animation: spin 0.6s linear infinite; vertical-align: -2px;
}
button.secondary .spinner { border-color: rgba(56, 73, 89, 0.2); border-top-color: currentColor; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---- toasts ---- */
#toast-root {
  position: fixed; top: 16px; right: 16px; left: 16px; z-index: 1000;
  display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
}
.toast {
  background: var(--ink); color: #fff; padding: 11px 14px; border-radius: var(--radius-sm);
  font-size: 13.5px; font-weight: 600; display: flex; align-items: center; gap: 8px;
  box-shadow: var(--shadow-lift); opacity: 0; transform: translateY(-8px);
  transition: opacity 0.18s var(--ease-out), transform 0.18s var(--ease-out); max-width: min(320px, 100%);
}
.toast.in { opacity: 1; transform: translateY(0); }
.toast.success { background: #1f5c2b; }
.toast.error { background: var(--danger-dark); }
.toast .icon { color: #fff; }

/* ---- modals ---- */
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 4px; }
dialog.modal { opacity: 0; transform: translateY(8px) scale(0.98); transition: opacity 0.2s var(--ease-out), transform 0.2s var(--ease-out); }
dialog.modal.in { opacity: 1; transform: translateY(0) scale(1); }
dialog.modal::backdrop { background: rgba(56, 73, 89, 0); transition: background-color 0.2s var(--ease-out); }
dialog.modal.in::backdrop { background: rgba(56, 73, 89, 0.5); }
dialog.modal h2 { margin: 0; font-family: var(--font-display); font-size: 22px; text-transform: uppercase; letter-spacing: 0.02em; color: var(--ink); border-bottom: none; padding-bottom: 0; }

/* ---- file thumbnails & preview ---- */
.thumb {
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  width: 48px; height: 48px; border-radius: var(--radius-sm); border: 1px solid var(--line-strong);
  background: var(--stamp-tint); flex-shrink: 0;
}
.thumb:hover { border-color: var(--stamp); }
.thumb img { width: 100%; height: 100%; object-fit: cover; }
.thumb .icon { width: 20px; height: 20px; color: var(--muted); }
dialog.preview-modal { max-width: min(900px, 92vw); width: 92vw; }
.preview-frame {
  width: 100%; height: min(75vh, 700px); border-radius: var(--radius-sm); overflow: hidden;
  border: 1px solid var(--line-strong); background: var(--stamp-tint);
}
.preview-frame iframe { width: 100%; height: 100%; border: none; }

/* ---- login ---- */
.login-wrap {
  display: flex; align-items: center; justify-content: center; min-height: 100vh; padding: 20px;
  background: var(--paper);
}
.login-box { width: 100%; max-width: 380px; padding: 36px 32px; box-shadow: var(--shadow-lift); }
.login-box h1 {
  text-align: center; justify-content: center; margin-bottom: 4px; font-size: 30px;
}
.login-box .sub { text-align: center; color: var(--muted); font-size: 13.5px; margin-bottom: 26px; }
.login-box button.primary { width: 100%; justify-content: center; padding: 11px 20px; margin-top: 4px; }

/* ---- library grid ---- */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.art-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 8px; }
.art-card h3 { font-size: 15px; }
.art-card .meta { font-size: 12.5px; color: var(--muted); }
.art-card .thumb { width: 100%; height: 130px; border-radius: var(--radius-sm); margin-bottom: 2px; }
.art-card .thumb .icon { width: 28px; height: 28px; }
.filters { display: flex; gap: 10px; margin-bottom: 18px; flex-wrap: wrap; }
.filters select { width: auto; }
/* The dashboard's filters sit inline with the "Active requests" heading
   (via .section-title's row layout) instead of on their own line like
   library/requests pages - no extra bottom margin needed there since
   .section-title already carries its own spacing below. */
.section-title .filters { margin-bottom: 0; }

/* ---- reprint basket ---- */
.basket-layout { display: grid; grid-template-columns: 1fr 300px; gap: 20px; align-items: start; }
.basket-side { position: sticky; top: calc(var(--nav-height) + 16px); }
.basket-item { font-size: 13.5px; padding: 7px 0; border-bottom: 1px solid var(--line); font-weight: 600; }
.basket-item .muted { font-weight: 400; margin-top: 1px; }

.item-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; }
.item-card {
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px; box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 10px;
}
.item-card .item-thumbs { display: flex; gap: 6px; }
.item-card .thumb { width: 100%; height: 100px; border-radius: var(--radius-sm); }
.item-card .item-thumbs .thumb { flex: 1; }
.item-card .item-thumbs .thumb .icon { width: 26px; height: 26px; }
.item-card h3 { font-size: 14.5px; }
.item-card .meta { font-size: 12.5px; color: var(--muted); }
.item-card input[type=number] { width: 100%; }

/* ---- tabs ---- */
.tabs { display: flex; gap: 4px; border-bottom: 2px solid var(--line); margin-bottom: 16px; }
.tabs button {
  background: none; border: none; padding: 10px 16px; font-size: 13px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; color: var(--muted);
  border-bottom: 2px solid transparent; margin-bottom: -2px;
}
.tabs button.active { color: var(--accent); border-bottom-color: var(--accent); }

.actions { display: flex; gap: 10px; flex-wrap: wrap; margin: 14px 0; }
.history-item { padding: 10px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.history-item:last-child { border-bottom: none; }
.history-item .when { color: var(--muted); font-size: 12px; font-family: var(--font-mono); }

.section-title { display: flex; align-items: center; justify-content: space-between; margin: 22px 0 10px; }
/* The global `* { margin: 0 }` reset above wipes out the browser's own
   margin: auto centering for <dialog>, so it has to be restored explicitly
   or every dialog opens pinned to the top-left instead of centered. */
dialog { border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; max-width: 480px; width: 90%; margin: auto; background: var(--card); color: var(--ink); }
dialog::backdrop { background: rgba(56, 73, 89, 0.5); }

/* ---- reduced motion ---- */
/* A blanket 0.001ms on everything replaces toasts/modals fading in with a
   jarring instant pop. Keep a short opacity/colour cross-fade for those -
   and the loading spinner, which is status, not decoration - and only kill
   transform-driven movement and one-shot entrance animations elsewhere. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
  .spinner { animation-duration: 0.6s !important; }
  .toast, dialog.modal, dialog.modal::backdrop {
    transition-property: opacity, background-color !important;
    transition-duration: 0.18s !important;
  }
  .toast, dialog.modal { transform: none !important; }
}

/* ---- mobile (phones) ---- */
@media (max-width: 680px) {
  main { padding: 16px 14px 48px; }
  h1 { font-size: 26px; }

  /* Nav: brand + the icon actions (quick-add, settings, account) stay on one
     row - now that name/role text and the logout button live inside the
     account dropdown instead of sitting in the bar itself, that row is just
     a handful of compact icon buttons and easily fits. Links move to their
     own horizontally-scrollable strip below. Both rows are trimmed down from
     their desktop sizing (smaller brand, tighter link/icon padding) - full
     desktop-sized touch targets ate close to a quarter of a phone screen
     before this, pushing content below the fold on the very first scroll. */
  nav { padding: 6px 12px; gap: 6px; flex-wrap: wrap; }
  nav .brand { font-size: 17px; padding: 6px 0; }
  nav .spacer { display: none; }
  nav .icon-btn { width: 30px; height: 30px; }
  nav .nav-links {
    order: 10; flex-basis: 100%; flex-wrap: nowrap; overflow-x: auto;
    -webkit-overflow-scrolling: touch; margin: 0 -12px -6px; padding: 0 12px 6px;
  }
  nav .nav-links a { flex: 0 0 auto; padding: 8px 10px; font-size: 13px; white-space: nowrap; }

  /* Tables scroll horizontally within their own box instead of forcing the
     whole page wider than the screen. */
  table { min-width: 540px; }
  /* Hint that there's more to scroll to - both of these are genuinely wider
     than the screen on mobile, with no scrollbar visible until touched. */
  .table-scroll, nav .nav-links {
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 20px), transparent 100%);
    mask-image: linear-gradient(to right, black calc(100% - 20px), transparent 100%);
  }
  /* The Dashboard/Requests list tables (dashboard.html, requests.html) drop
     their least-essential columns on mobile instead - Type and who raised
     it are a tap away on the request's own page, and Created just repeats
     what Due already sorts by. What's left (Artwork, Site, Status, Due)
     fits the screen width without needing a scroll to find any of it. */
  .request-list-table { min-width: 0; }
  .request-list-table th:nth-child(2), .request-list-table td:nth-child(2),
  .request-list-table th:nth-child(5), .request-list-table td:nth-child(5),
  .request-list-table th:nth-child(7), .request-list-table td:nth-child(7) {
    display: none;
  }

  /* Filters sit inline with the section heading on desktop (see
     .section-title .filters above) - once .section-title stacks them
     below it instead, that shared row's own spacing no longer does
     anything useful, so it needs its own again. */
  .section-title .filters { margin-bottom: 14px; width: 100%; }

  /* Reprint basket: stack instead of squeezing into a fixed 300px column. */
  .basket-layout { grid-template-columns: 1fr; }
  .basket-side { position: static; }

  .tiles { grid-template-columns: repeat(2, 1fr); }
  .tile { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
  .tile:nth-child(2n) { border-right: none; }
  .tile:nth-last-child(-n+2) { border-bottom: none; }
  .grid { grid-template-columns: 1fr; }
  .filters { flex-direction: column; align-items: stretch; }
  .filters select, .filters input { width: 100%; }
  .section-title { flex-direction: column; align-items: flex-start; gap: 10px; }
  /* Page-level action bars stack full-width. The compact per-row action
     pairs inside table cells (e.g. Edit/Deactivate) are overridden back to
     a row below - the table already scrolls, so there's no need to stack. */
  .actions { flex-direction: column; align-items: stretch; }
  .actions button, .actions a.btn { justify-content: center; }
  td .actions { flex-direction: row; flex-wrap: wrap; align-items: center; }
  td .actions button { justify-content: flex-start; }
  dialog { padding: 18px; }
}
