/* Windowed workspace.
 *
 * Loaded on every page but inert unless MainLayout renders the desk, which needs both the
 * tenant module and the user's own opt-in.
 *
 * Deliberately hand-written rather than Tailwind: window geometry is computed at runtime, and
 * wwwroot/css/app.css is a precompiled artifact that would need `npm run build:css` for every
 * tweak in here. Colours come from the same rgb() triplets Styles/app.css defines, so both
 * themes follow automatically.
 */

.m1-desk {
  position: relative;
  flex: 1;
  min-height: 0;
  overflow: hidden;
  background:
    radial-gradient(circle at 1px 1px, rgb(var(--border)) 1px, transparent 0) 0 0 / 16px 16px,
    rgb(var(--muted));
}

.m1-desk-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 4px;
  text-align: center;
  pointer-events: none;
  padding: 0 20px;
}

/* ---------- window ---------- */

.m1-win {
  position: absolute;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: rgb(var(--card));
  border: 1px solid rgb(var(--border));
  border-radius: 0;
  box-shadow: 0 1px 2px rgb(8 14 20 / .18), 0 10px 20px -14px rgb(8 14 20 / .5);
  transition: left .16s ease, top .16s ease, width .16s ease, height .16s ease,
              box-shadow .16s ease, transform .18s cubic-bezier(.2, .9, .25, 1);
}

/* Hidden, never unmounted. Rendering a minimised window away would dispose the page inside
   it and lose the state the drawer exists to protect. */
.m1-win-hidden { display: none; }

.m1-win-focused {
  box-shadow:
    0 4px 10px rgb(8 14 20 / .3),
    0 26px 50px -18px rgb(8 14 20 / .7),
    0 0 0 1px rgb(255 255 255 / .06) inset;
}

/* While the pointer owns the position, CSS must not animate it or the window lags. */
.m1-win-dragging {
  transition: none;
  user-select: none;
}

.m1-win-bar {
  position: relative;
  flex: 0 0 36px;
  height: 36px;
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 5px 0 12px;
  background: rgb(var(--muted));
  border-bottom: 1px solid rgb(var(--border));
  font-size: 12px;
  color: rgb(var(--muted-foreground));
  cursor: grab;
  user-select: none;
  touch-action: none;
}

.m1-win-bar:active { cursor: grabbing; }
.m1-win-focused .m1-win-bar {
  color: rgb(var(--foreground));
  background: rgb(var(--secondary));
}

.m1-win-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}

.m1-win-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(245 158 11);
  flex: 0 0 6px;
}

/* The grabber: every layout command lives behind it, so the app header stays clean. */
.m1-win-grab {
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  width: 48px;
  height: 100%;
  border: 0;
  background: transparent;
  cursor: pointer;
  padding: 0;
  display: grid;
  place-items: center;
}

.m1-win-grab i {
  display: block;
  width: 22px;
  height: 4px;
  border-radius: 99px;
  background: rgb(var(--muted-foreground) / .35);
  transition: background .16s ease, width .16s ease;
}

.m1-win-focused .m1-win-grab i {
  width: 34px;
  background: rgb(var(--muted-foreground) / .85);
}

.m1-win-grab:hover i {
  background: rgb(var(--accent));
  width: 32px;
}

.m1-win-grab:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: -4px;
  border-radius: 6px;
}

.m1-win-btn {
  width: 30px;
  height: 26px;
  border: 0;
  background: transparent;
  color: rgb(var(--muted-foreground));
  cursor: pointer;
  border-radius: 4px;
  display: grid;
  place-items: center;
  font-size: 19px;
  line-height: 1;
  flex: 0 0 30px;
}

/* Full screen. Drawn rather than set as a glyph: the two states have to read apart at 10px,
   and the box characters the font ships do not. */
.m1-win-btn-zoom i {
  position: relative;
  display: block;
  width: 10px;
  height: 10px;
  border: 1.5px solid currentColor;
  border-radius: 2px;
}

/* Already full screen, so the button offers the way back — two boxes, the way every other
   window on the machine draws restore. */
.m1-win-btn-zoom i.m1-win-zoom-back::before {
  content: "";
  position: absolute;
  inset: 1.5px;
  border: 1.5px solid currentColor;
  border-radius: 1px;
}

.m1-win-btn:hover {
  background: rgb(var(--border));
  color: rgb(var(--foreground));
}

.m1-win-btn-close:hover {
  background: rgb(var(--destructive));
  color: #fff;
}

.m1-win-btn:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: -2px;
}

.m1-win-body {
  flex: 1;
  min-height: 0;
  padding: 14px 16px;

  /* Never sideways. A window's content is meant to fit its width, so a horizontal bar here
     only ever means a page laid itself out for a viewport it does not have — and scrolling
     is not the fix for that, fitting is. Genuinely wide things, chiefly big tables, keep
     their own .overflow-x-auto wrapper and scroll inside it. */
  overflow-x: hidden;
  overflow-y: auto;
}

.m1-win-grip {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 15px;
  height: 15px;
  cursor: nwse-resize;
  touch-action: none;
  opacity: .5;
  background: linear-gradient(135deg,
    transparent 46%, rgb(var(--muted-foreground)) 46%, rgb(var(--muted-foreground)) 54%,
    transparent 54%, transparent 70%, rgb(var(--muted-foreground)) 70%,
    rgb(var(--muted-foreground)) 78%, transparent 78%);
}

.m1-win-grip:hover { opacity: 1; }


@media (prefers-reduced-motion: reduce) {
  .m1-win { transition: none; }
  .m1-win-grab i { transition: none; }
}

/* ---------- edge drawer ---------- */

/* The container covers the desk but ignores the pointer, so only the tab and the panel are
   hit targets — hovering either keeps it open, and windows underneath stay clickable. */
.m1-drawer {
  position: absolute;
  inset: 0;
  z-index: 50;
  pointer-events: none;
}

.m1-drawer-tab {
  position: absolute;
  right: 3px;
  top: 42%;
  width: 14px;
  height: 80px;
  border: 0;
  border-radius: 8px;
  padding: 0;
  cursor: pointer;
  pointer-events: auto;
  background: linear-gradient(180deg, rgb(var(--accent)), rgb(var(--accent) / .75));
  box-shadow: 0 2px 12px -2px rgb(var(--accent) / .6);
  transition: width .2s cubic-bezier(.2, .9, .25, 1);
}

.m1-drawer-tab:hover { width: 18px; }

.m1-drawer-tab:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: 2px;
}

/* Pinned reads differently from merely hovered, so the state is obvious at a glance. */
.m1-drawer-pinned .m1-drawer-tab {
  background: linear-gradient(180deg, rgb(var(--primary)), rgb(var(--primary) / .75));
  box-shadow: 0 2px 12px -2px rgb(var(--primary) / .6);
}

.m1-drawer-count {
  position: absolute;
  right: 100%;
  margin-right: 6px;
  top: -3px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 99px;
  background: rgb(var(--card));
  color: rgb(var(--accent));
  border: 1px solid rgb(var(--accent) / .5);
  font-size: 10px;
  display: grid;
  place-items: center;
  transition: opacity .16s ease;
}

.m1-drawer:hover .m1-drawer-count,
.m1-drawer-pinned .m1-drawer-count { opacity: 0; }

.m1-drawer-panel {
  position: absolute;
  right: 25px;
  top: 50%;
  width: 216px;
  max-height: 80%;
  overflow: visible;
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  opacity: 0;
  pointer-events: none;
  transform: translate(16px, -50%) scale(.97);
  transform-origin: right center;
  background: rgb(var(--card));
  border: 1px solid rgb(var(--border));
  border-radius: 13px;
  box-shadow: 0 8px 18px -8px rgb(8 14 20 / .3), 0 32px 64px -30px rgb(8 14 20 / .75);
  transition: opacity .18s ease, transform .26s cubic-bezier(.2, .9, .25, 1);
}

/* Bridges the gap between the tab and the panel. Without it the pointer crosses dead space
   on the way in and the panel starts closing under the cursor.
   It deliberately sticks out past the panel's right edge, which is why the panel must not be
   a scroll container: overflow-y:auto would compute overflow-x to auto and this would show
   up as a horizontal scrollbar along the bottom of the drawer. */
.m1-drawer-panel::after {
  content: "";
  position: absolute;
  left: 100%;
  top: 0;
  bottom: 0;
  width: 27px;
}

.m1-drawer:hover .m1-drawer-panel,
.m1-drawer-pinned .m1-drawer-panel {
  opacity: 1;
  pointer-events: auto;
  transform: translate(0, -50%) scale(1);
}

.m1-drawer-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 0 2px 7px;
  margin-bottom: 3px;
  border-bottom: 1px solid rgb(var(--border));
  font-size: 12px;
  color: rgb(var(--foreground));
}

.m1-drawer-head em {
  font-style: normal;
  color: rgb(var(--muted-foreground));
}

/* The list scrolls, not the panel — see the note on .m1-drawer-panel::after. Header and
   footer stay put, so the desk counter and Minimize all are always reachable. */
.m1-drawer-items {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
}

.m1-drawer-empty {
  font-size: 12px;
  color: rgb(var(--muted-foreground));
  padding: 8px 3px;
  text-align: center;
}

.m1-drawer-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border-radius: 7px;
  cursor: pointer;
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card));
  color: rgb(var(--muted-foreground));
  font-size: 12px;
  text-align: left;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.m1-drawer-item:hover {
  border-color: rgb(var(--accent));
  color: rgb(var(--accent));
  background: rgb(var(--muted));
}

/* Dashed: this one is on another screen, so clicking it will not bring the page back. */
.m1-drawer-item-out {
  border-style: dashed;
  cursor: default;
}

.m1-drawer-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 7px;
  padding-top: 7px;
  border-top: 1px solid rgb(var(--border));
  font-size: 10px;
  color: rgb(var(--muted-foreground));
  flex-wrap: wrap;
  flex: 0 0 auto;
}

.m1-drawer-slots {
  display: flex;
  gap: 3px;
}

.m1-drawer-slots i {
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: rgb(var(--border));
  display: block;
}

.m1-drawer-slots i.on { background: rgb(var(--accent)); }

.m1-drawer-minall {
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card));
  color: rgb(var(--muted-foreground));
  border-radius: 5px;
  padding: 2px 7px;
  font-size: 10px;
  cursor: pointer;
}

.m1-drawer-minall:hover {
  border-color: rgb(var(--accent));
  color: rgb(var(--accent));
}

@media (prefers-reduced-motion: reduce) {
  .m1-drawer-panel,
  .m1-drawer-tab,
  .m1-drawer-count { transition: none; }
}

/* ---------- grabber menu ---------- */

.m1-menu-anchor {
  position: absolute;
  z-index: 60;
}

.m1-menu {
  width: 190px;
  padding: 7px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: rgb(var(--card));
  border: 1px solid rgb(var(--border));
  border-radius: 11px;
  box-shadow: 0 8px 18px -8px rgb(8 14 20 / .3), 0 30px 60px -28px rgb(8 14 20 / .75);
}

.m1-menu > button {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-radius: 6px;
  border: 0;
  background: transparent;
  color: rgb(var(--muted-foreground));
  font-size: 12px;
  text-align: left;
  cursor: pointer;
  width: 100%;
}

/* The shortcut, pushed to the far edge of its row. Nobody finds Ctrl+` on their own, and the
   menu is where they go looking for the thing it does. */
.m1-menu > button > kbd {
  margin-left: auto;
  padding: 1px 5px;
  border: 1px solid rgb(var(--border));
  border-radius: 4px;
  background: rgb(var(--muted));
  font-family: inherit;
  font-size: 10px;
  letter-spacing: .02em;
}

.m1-menu > button:hover {
  background: rgb(var(--muted));
  color: rgb(var(--foreground));
}

.m1-menu > button:focus-visible {
  outline: 2px solid rgb(var(--accent));
  outline-offset: -2px;
}

.m1-menu-danger:hover {
  background: rgb(var(--destructive));
  color: #fff;
}

.m1-menu hr {
  border: 0;
  border-top: 1px solid rgb(var(--border));
  margin: 4px 2px;
  width: 100%;
}

.m1-menu-label {
  font-size: 9px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgb(var(--muted-foreground));
  padding: 3px 3px 4px;
}

.m1-menu-grid {
  position: relative;
  height: 62px;
  margin: 0 2px 5px;
  border-radius: 7px;
  background: rgb(var(--muted));
  border: 1px solid rgb(var(--border));
}

.m1-menu-cell {
  position: absolute;
  border-radius: 4px;
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card));
  cursor: pointer;
  padding: 0;
  transition: background .14s ease, border-color .14s ease;
}

.m1-menu-cell:hover {
  border-color: rgb(var(--accent));
  background: rgb(var(--accent) / .18);
}

.m1-menu-cell-self {
  background: rgb(var(--accent));
  border-color: rgb(var(--accent));
  cursor: default;
}

.m1-menu-cell-self:hover { background: rgb(var(--accent)); }

@media (prefers-reduced-motion: reduce) {
  .m1-menu-cell { transition: none; }
}

/* ---------- fitting a full-page layout into a window ---------- */

/* Tailwind's sm:/md:/lg:/xl: prefixes respond to the viewport, not to this window. On a wide
 * monitor a page in a 580px window still applies every one of them — four-across grids, rows
 * told to go horizontal, controls that overflow the frame and leave a sideways scrollbar.
 *
 * AppWindow stamps one class per breakpoint the window is narrower than, so each rule below
 * undoes exactly the prefix that should not have applied. Descendant selectors outrank
 * Tailwind's single class, so none of this needs !important.
 *
 * Not container queries on purpose: container-type implies layout containment, which makes
 * the element a containing block for position:fixed descendants and would drag every modal
 * dialog inside the window.
 */

/* Grid and flex children only shrink below their content size when told they may. Without
   this a single long word or a wide table pushes the whole row out. */
.m1-win-body :where(.grid, .flex) > * { min-width: 0; }

/* A wide table scrolls inside its own wrapper rather than dragging the window with it. */
.m1-win-body .overflow-x-auto {
  max-width: 100%;
  min-width: 0;
}

/* No control is ever wider than the window holding it. */
.m1-win-body :where(select, input, textarea, button, .btn) { max-width: 100%; }

/* Rows told to go horizontal at a width this window does not have. This is what puts a
   filter bar's select and its buttons back on separate lines instead of off the edge. */
.m1-lt-sm .m1-win-body .sm\:flex-row,
.m1-lt-md .m1-win-body .md\:flex-row,
.m1-lt-lg .m1-win-body .lg\:flex-row,
.m1-lt-xl .m1-win-body .xl\:flex-row {
  flex-direction: column;
  align-items: stretch;
}

/* Anything still in a row wraps rather than overflowing. Only bites when it would have
   overflowed anyway, so a row that already fits looks no different. */
.m1-lt-lg .m1-win-body .flex:not(.flex-nowrap) { flex-wrap: wrap; }

/* Two columns where the page asked for three or four. */
.m1-lt-lg .m1-win-body :where(
  .md\:grid-cols-3, .md\:grid-cols-4,
  .lg\:grid-cols-3, .lg\:grid-cols-4,
  .xl\:grid-cols-3, .xl\:grid-cols-4
) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Narrower than a phone: everything stacks. */
.m1-lt-md .m1-win-body :where(
  .sm\:grid-cols-2, .sm\:grid-cols-3, .sm\:grid-cols-4,
  .md\:grid-cols-2, .md\:grid-cols-3, .md\:grid-cols-4,
  .lg\:grid-cols-2, .lg\:grid-cols-3, .lg\:grid-cols-4,
  .xl\:grid-cols-2, .xl\:grid-cols-3, .xl\:grid-cols-4,
  .grid-cols-2, .grid-cols-3, .grid-cols-4
) {
  grid-template-columns: minmax(0, 1fr);
}

/* Header rows put a title and its buttons in one line that refuses to give. */
.m1-lt-md .m1-win-body :where(.flex.items-center.justify-between, .page-header) {
  flex-wrap: wrap;
  gap: 8px;
}

/* Tighter gutters buy back room that matters at this width. */
.m1-lt-sm .m1-win-body { padding: 10px 11px; }
.m1-lt-sm .m1-win-body :where(.gap-6, .gap-8) { gap: 12px; }
.m1-lt-sm .m1-win-body :where(.p-6, .p-8) { padding: 12px; }

/* A page title sized for a full screen dominates a small window. */
.m1-lt-sm .m1-win-body :where(.page-title, h1) { font-size: 1.25rem; }
.m1-lt-md .m1-win-body :where(.page-title, h1) { font-size: 1.5rem; }

/* ---------- resize handles ---------- */

/* One per edge and corner, so width and height can be changed independently. They sit just
   outside the border and stay invisible; the cursor is the affordance, as it is on a desktop
   window manager. */
.m1-win-edge,
.m1-win-grip {
  position: absolute;
  z-index: 2;
  touch-action: none;
}

.m1-win-n { top: -3px; left: 10px; right: 10px; height: 8px; cursor: ns-resize; }
.m1-win-s { bottom: -3px; left: 10px; right: 10px; height: 8px; cursor: ns-resize; }
.m1-win-w { left: -3px; top: 10px; bottom: 10px; width: 8px; cursor: ew-resize; }
.m1-win-e { right: -3px; top: 10px; bottom: 10px; width: 8px; cursor: ew-resize; }

.m1-win-nw { top: -3px; left: -3px; width: 14px; height: 14px; cursor: nwse-resize; }
.m1-win-ne { top: -3px; right: -3px; width: 14px; height: 14px; cursor: nesw-resize; }
.m1-win-sw { bottom: -3px; left: -3px; width: 14px; height: 14px; cursor: nesw-resize; }

/* The bottom-right corner keeps a visible grip, the one place people look for it. */
.m1-win-se {
  right: 0;
  bottom: 0;
  width: 16px;
  height: 16px;
  cursor: nwse-resize;
  opacity: .45;
  background: linear-gradient(135deg,
    transparent 46%, rgb(var(--muted-foreground)) 46%, rgb(var(--muted-foreground)) 54%,
    transparent 54%, transparent 70%, rgb(var(--muted-foreground)) 70%,
    rgb(var(--muted-foreground)) 78%, transparent 78%);
}

.m1-win-se:hover { opacity: 1; }

/* ---------- scrollbars ---------- */

/* Windows were falling back to the platform's own scrollbars, which on Windows are wide,
   pale and squared off — they read as part of the page rather than chrome, and the corner
   where the two meet leaves a solid block. This matches the app's own .scrollbar-thin
   convention and extends it to the horizontal bar and the corner, which that utility never
   covered. */
.m1-win-body,
.m1-drawer-items,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto) {
  scrollbar-width: thin;
  scrollbar-color: transparent transparent;
}

/* Firefox has no pseudo-elements for this, so the colour is swapped on the container. */
.m1-win:hover .m1-win-body,
.m1-win-focused .m1-win-body,
.m1-drawer:hover .m1-drawer-items {
  scrollbar-color: rgb(var(--muted-foreground) / .4) transparent;
}

.m1-win-body::-webkit-scrollbar,
.m1-drawer-items::-webkit-scrollbar,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.m1-win-body::-webkit-scrollbar-track,
.m1-drawer-items::-webkit-scrollbar-track,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar-track {
  background: transparent;
}

/* Padded in with a transparent border so the thumb reads as a floating pill rather than a
   bar wedged against the window frame. */
/* Invisible at rest. Resizing the window is the way to see more at once; the bar is there
   for content no window could ever be tall enough for, so it should not be furniture. The
   8px stays reserved either way, so nothing reflows when it fades in. */
.m1-win-body::-webkit-scrollbar-thumb,
.m1-drawer-items::-webkit-scrollbar-thumb,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar-thumb {
  background: transparent;
  border-radius: 99px;
  border: 2px solid transparent;
  background-clip: content-box;
  transition: background .18s ease;
}

.m1-win:hover .m1-win-body::-webkit-scrollbar-thumb,
.m1-win-focused .m1-win-body::-webkit-scrollbar-thumb,
.m1-drawer:hover .m1-drawer-items::-webkit-scrollbar-thumb,
.m1-win:hover .m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar-thumb {
  background: rgb(var(--muted-foreground) / .35);
  background-clip: content-box;
}

.m1-win-body::-webkit-scrollbar-thumb:hover,
.m1-drawer-items::-webkit-scrollbar-thumb:hover,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar-thumb:hover {
  background: rgb(var(--muted-foreground) / .65);
  background-clip: content-box;
}

/* The square where a horizontal and a vertical bar meet. Left unstyled it is an opaque
   block in the corner of the window. */
.m1-win-body::-webkit-scrollbar-corner,
.m1-drawer-items::-webkit-scrollbar-corner,
.m1-win-body :where(.overflow-x-auto, .overflow-y-auto, .overflow-auto)::-webkit-scrollbar-corner {
  background: transparent;
}

/* ---------- tile view ---------- */

/* Browsing every window at once to pick one. Distinct from Arrange all, which permanently
   relays the desk — tile view moves nothing and goes away again. */

.m1-desk-tiling {
  /* Dimmed so the tiles read as a layer over the desk rather than as the desk itself. */
  background:
    linear-gradient(rgb(8 14 20 / .55), rgb(8 14 20 / .55)),
    radial-gradient(circle at 1px 1px, rgb(var(--border)) 1px, transparent 0) 0 0 / 16px 16px,
    rgb(var(--muted));
  cursor: zoom-out;
}

/* A tile is the real window, drawn smaller by a transform on .m1-win — see AppWindow.Style.
   Its own chrome is inert here, so the frame reads as a picture rather than something to
   operate. */
.m1-win-tile {
  box-shadow: 0 10px 24px -8px rgb(8 14 20 / .5), 0 30px 60px -30px rgb(8 14 20 / .8);
  cursor: pointer;
}

.m1-win-tile .m1-win-bar { cursor: pointer; }

/* No resizing while browsing: the handles would fight the tile layout, and the pointer is
   there to choose a window rather than reshape one. */
.m1-win-tile .m1-win-edge,
.m1-win-tile .m1-win-grip { display: none; }

/* Over the whole window, so a click picks the tile instead of pressing whatever sits under
   the pointer. Also what keeps a hosted page from reacting to hover while it is a picture. */
.m1-win-tilecatch {
  position: absolute;
  inset: 0;
  z-index: 5;
  cursor: pointer;
  background: transparent;
  transition: background .14s ease;

  /* It is a button now, so that the keyboard can reach it. Stripped back to the plain
     rectangle it was as a div. */
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
}

/* Hovered, keyboard-selected and tab-focused all look the same on purpose: there is one
   "this is the tile you are about to open", however the user got to it. */
.m1-win-tilecatch:hover,
.m1-win-tilecatch:focus-visible,
.m1-win-tilesel {
  background: rgb(var(--accent) / .14);
  box-shadow: 0 0 0 3px rgb(var(--accent)) inset;
  outline: none;
}

/* Ruled out by what the user typed. Still in its cell, so the grid does not reflow and the
   jump numbers do not shift while they are still typing. */
.m1-win-tiledim {
  opacity: .3;
  filter: saturate(.35);
}

/* Which Alt+number opens this one. Sized in em so it scales with the caption, which is itself
   sized up to survive the tile's transform. */
.m1-win-tilenum {
  display: inline-block;
  min-width: 1.5em;
  margin-right: .4em;
  padding: 0 .25em;
  border-radius: .28em;
  background: rgb(var(--accent));
  color: #fff;
  text-align: center;
}

/* What the keyboard can do, and what has been typed so far. Above the tiles but below the
   drawer, which stays reachable throughout. */
.m1-tile-hint {
  position: absolute;
  left: 50%;
  bottom: 14px;
  transform: translateX(-50%);
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 60px);
  padding: 7px 14px;
  border-radius: 99px;
  border: 1px solid rgb(var(--border));
  background: rgb(var(--card) / .92);
  backdrop-filter: blur(6px);
  box-shadow: 0 8px 24px -10px rgb(8 14 20 / .7);
  font-size: 12px;
  color: rgb(var(--muted-foreground));
  white-space: nowrap;
  overflow: hidden;
  pointer-events: none;
}

.m1-tile-hint b {
  padding: 1px 8px;
  border-radius: 99px;
  background: rgb(var(--accent));
  color: #fff;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The caption is scaled down with the window, so it is sized back up to stay readable in a
   small tile — a 12px label at 0.25 scale would be 3px. */
.m1-win-tilecap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 14px;
  font-size: 2.2em;
  font-weight: 600;
  color: #fff;
  background: linear-gradient(transparent, rgb(8 14 20 / .85));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
}
