/* ==========================================================================
   Browse content: panel, breadcrumb, toolbar, grid, cards, empty states, FAB.
   Owning feature: browse
   Load order is defined in Views/Shared/_CssIncludes.cshtml — do not reorder.
   ========================================================================== */

/* --- Browse content -----------------------------------------------------
   Section rhythm lives on .fh-panel (nested browse/shared panels and
   single-layer surfaces like Home/Search). The layout .fh-content well
   keeps page padding/background only — see the consolidated rule below. */
.fh-panel {
  display: flex;
  flex-direction: column;
  gap: var(--fh-section-gap, 1.1rem);
  min-width: 0;
}

/* Infinite-scroll metadata carriers are read by JS but must not occupy a
   flex-gap slot between the page header and the listing. */
#browse-feed,
#shared-feed {
  display: none;
}

/* --- Modern & Responsive Breadcrumb (.fh-breadcrumb) -------------------- */
.fh-breadcrumb {
  display: flex;
  align-items: center;
  margin: 0 0 0.35rem 0;
  padding: 0;
  min-width: 0;
  width: 100%;
}

.fh-breadcrumb-list {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  list-style: none;
  margin: 0;
  padding: 0;
  flex-wrap: nowrap;
  min-width: 0;
  max-width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE/Edge */
}

.fh-breadcrumb-list::-webkit-scrollbar {
  display: none; /* Chrome/Safari */
}

.fh-breadcrumb-item {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  flex-shrink: 1;
}

.fh-breadcrumb-item:first-child {
  flex-shrink: 0;
}

.fh-breadcrumb-item:last-child {
  flex-shrink: 0;
  min-width: 0;
}

.fh-breadcrumb-link {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--fh-muted, #6b7280);
  text-decoration: none;
  font-size: var(--fh-text-sm);
  font-weight: var(--fh-weight-medium);
  padding: 0.2rem 0.45rem;
  border-radius: 0.375rem;
  max-width: 180px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 0.15s ease, background-color 0.15s ease;
  outline: none;
}

.fh-breadcrumb-link:hover {
  color: var(--fh-primary, #2563eb);
  background-color: rgba(37, 99, 235, 0.08);
}

.fh-breadcrumb-link:focus-visible {
  color: var(--fh-primary-dark, #1d4ed8);
  background-color: var(--fh-soft, #f8fafc);
  box-shadow: 0 0 0 2px rgba(37, 99, 235, 0.35);
}

.fh-breadcrumb-current {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--fh-text, #1e293b);
  font-size: var(--fh-text-sm);
  font-weight: var(--fh-weight-semibold);
  padding: 0.2rem 0.55rem;
  border-radius: 0.375rem;
  background-color: var(--fh-soft, #f8fafc);
  border: 1px solid var(--fh-border, #e2e8f0);
  max-width: 220px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fh-breadcrumb-separator {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fh-muted);
  font-size: var(--fh-text-2xs);
  flex-shrink: 0;
  user-select: none;
  opacity: 0.8;
  margin: 0 0.1rem;
}

.fh-breadcrumb-home-icon {
  font-size: var(--fh-text-xs);
  flex-shrink: 0;
}

/* Fallback for unnested/legacy markup */
.fh-breadcrumb a:not(.fh-breadcrumb-link) {
  color: var(--fh-muted, #6b7280);
  text-decoration: none;
  font-size: var(--fh-text-sm);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fh-breadcrumb .current:not(.fh-breadcrumb-current) {
  color: var(--fh-text, #1e293b);
  font-weight: var(--fh-weight-semibold);
  font-size: var(--fh-text-sm);
}

/* Responsive adjustments (.98 upper bound — see the breakpoint note on
   :root / --fh-read-max above). */
@media (max-width: 767.98px) {
  .fh-breadcrumb-link {
    max-width: 120px;
    font-size: var(--fh-text-xs);
  }
  .fh-breadcrumb-current {
    max-width: 160px;
    font-size: var(--fh-text-xs);
  }
}

@media (max-width: 575.98px) {
  .fh-breadcrumb-list {
    gap: 0.2rem;
  }
  .fh-breadcrumb-link {
    max-width: 80px;
    padding: 0.15rem 0.3rem;
    font-size: var(--fh-text-xs);
  }
  .fh-breadcrumb-current {
    max-width: 130px;
    padding: 0.15rem 0.4rem;
    font-size: var(--fh-text-xs);
  }
  .fh-breadcrumb-separator {
    font-size: var(--fh-text-2xs);
    margin: 0 0.05rem;
  }
  .fh-breadcrumb-item.crumb-intermediate .fh-breadcrumb-link {
    max-width: 55px;
  }
}

/* Toolbar: Visually lighter, transparent stage framing. On wide screens this
   is the right-hand cluster of .fh-content-head-main, sized to its contents and
   sitting opposite the page title; below 768px it wraps to a full-width row of
   its own (see the media query in the Focused browse surface section). Its two
   groups — .fh-toolbar-group (view/filter controls) and
   .fh-toolbar-group-end (the primary "+ New" action) — wrap as units rather
   than every control reflowing individually. */
.fh-toolbar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex: 0 1 auto;
  gap: 0.6rem;
  flex-wrap: wrap;
  background: transparent;
  border: none;
  border-radius: 0;
  padding: 0;
}
.fh-toolbar-group {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
/* Belt-and-suspenders alongside .fh-toolbar's justify-content (flex-end when
   inline beside the title, space-between once it wraps to its own row) — keeps
   the primary action pinned right in both cases, and even if a future edit adds
   a third group before it. */
.fh-toolbar-group-end {
  margin-left: auto;
}
.fh-toolbar .btn {
  font-size: var(--fh-text-sm);
  border-radius: 0.5rem;
}
.fh-toolbar .btn-outline-secondary {
  background: #fff;
  border-color: var(--fh-border);
  color: var(--fh-muted);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.03);
  transition: all 0.15s ease;
}
.fh-toolbar .btn-outline-secondary:hover {
  background: var(--fh-primary-soft, #eff6ff);
  border-color: var(--fh-primary-soft-border, #bfdbfe);
  color: var(--fh-primary);
}

/* "+ New" primary action — the single most important CTA on the toolbar,
   sized and shadowed up to read unmistakably as primary. */
.fh-new-btn {
  font-size: var(--fh-text-md);
  font-weight: var(--fh-weight-bold);
  padding: 0.55rem 1.3rem;
  border-radius: 0.6rem;
  box-shadow: 0 2px 8px rgba(37, 99, 235, 0.35);
  transition: all 0.15s ease;
}
.fh-new-btn:hover {
  transform: translateY(-1.5px);
  box-shadow: 0 6px 16px rgba(37, 99, 235, 0.4);
}
.fh-new-btn:active {
  transform: translateY(0);
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.3);
}

/* View toggle: sleek segmented control */
.fh-view-toggle {
  border: 1px solid var(--fh-border);
  border-radius: 0.55rem;
  overflow: hidden;
  display: inline-flex;
  background: #f1f5f9;
  padding: 2px;
  gap: 2px;
}
.fh-view-toggle .btn {
  border: 0;
  border-radius: 0.4rem;
  background: transparent;
  color: var(--fh-muted);
  font-weight: var(--fh-weight-medium);
  font-size: var(--fh-text-xs);
  padding: 0.32rem 0.65rem;
  transition: all 0.15s ease;
}
.fh-view-toggle .btn:not(:last-child) {
  border-right: none;
}
.fh-view-toggle .btn:hover {
  color: var(--fh-primary);
}
.fh-view-toggle .btn.active {
  background: #ffffff;
  color: var(--fh-primary);
  font-weight: var(--fh-weight-semibold);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
}
.fh-view-toggle .btn.active:hover {
  color: var(--fh-primary-dark);
}
/* Item count — a quiet chip pinned beside the page title, so it reads as
   metadata belonging to the title rather than a heading of its own. Never
   shrinks or wraps; the title ellipsizes instead. */
.fh-count {
  flex-shrink: 0;
  padding: 0.15rem 0.6rem;
  background: var(--fh-soft);
  border: 1px solid var(--fh-border);
  border-radius: var(--bs-border-radius-pill, 50rem);
  font-size: var(--fh-text-xs);
  color: var(--fh-muted);
  font-weight: var(--fh-weight-medium);
  letter-spacing: var(--fh-tracking-wide);
  white-space: nowrap;
}

/* Grid: Hero Content Stage. Horizontal inset shares .fh-content-head's
   `--fh-head-inset` token so cards line up under the header text instead of
   sitting flush against the page edge while the header is indented. The base
   rule below is the explicit fallback — the responsive ladder covers every
   width. Desktop tiers use rem track minima so they follow the root type
   ramp; at 1920px+ the rem floor also steps up so cards grow, not only
   multiply. Phone/tablet tiers keep px minima (unchanged). */
.fh-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--fh-grid-gap, 1.1rem);
  padding: 0 var(--fh-head-inset, 0.25rem);
}

@media (max-width: 575.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  }
}

@media (min-width: 576px) and (max-width: 767.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(175px, 1fr));
  }
}

@media (min-width: 768px) and (max-width: 1023.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(195px, 1fr));
  }
}

@media (min-width: 1024px) and (max-width: 1439.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(13.125rem, 1fr));
  }
}

@media (min-width: 1440px) and (max-width: 1919.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(14.375rem, 1fr));
  }
}

@media (min-width: 1920px) and (max-width: 2559.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(16.25rem, 1fr));
  }
}

@media (min-width: 2560px) and (max-width: 3839.98px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(18.75rem, 1fr));
  }
}

@media (min-width: 3840px) {
  .fh-grid {
    grid-template-columns: repeat(auto-fill, minmax(21.25rem, 1fr));
  }
}

/* Grid view is split into a Folders section and a Files section (mockup) —
   #grid-view itself is now just a vertical stack of the two; each section's
   .fh-grid above is the actual card grid. Shares --fh-section-gap so the
   folders→files seam matches every other seam on the page. */
.fh-grid-sections {
  display: flex;
  flex-direction: column;
  gap: var(--fh-section-gap, 1.1rem);
}
.fh-grid-section[hidden] { display: none; }

/* Infinite scroll (Browse) */
#feed-sentinel { height: 1px; width: 100%; }
.fh-feed-status {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 2.5rem;
  padding: 0;
  font-size: var(--fh-text-sm);
  color: var(--fh-muted);
}
.fh-feed-error { color: var(--fh-danger, #dc2626); }

/* Grid Cards */
.fh-card {
  position: relative;
  background: #ffffff;
  border: 1px solid var(--fh-border);
  border-radius: var(--fh-radius-xl, 0.85rem);
  padding: 1rem;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  min-height: 8rem;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.03);
  transition: box-shadow 0.2s cubic-bezier(0.16, 1, 0.3, 1),
              border-color 0.2s ease,
              background-color 0.2s ease;
  user-select: none;
  -webkit-user-select: none;
}
.fh-card:hover {
  border-color: var(--fh-primary-soft-border, #bfdbfe);
  background-color: var(--fh-primary-soft, #eff6ff);
  box-shadow: 0 10px 24px -4px rgba(37, 99, 235, 0.08), 0 4px 8px -2px rgba(37, 99, 235, 0.04);
}
.fh-card:active {
  color: var(--fh-primary-dark);
  box-shadow: 0 4px 12px -2px rgba(37, 99, 235, 0.06);
}

@media (max-width: 575.98px) {
  .fh-card {
    padding: 0.75rem;
    min-height: 6.875rem;
    border-radius: var(--fh-radius-xl, 0.75rem);
  }
}

@media (min-width: 1920px) and (max-width: 2559.98px) {
  .fh-card {
    padding: 1.15rem;
    min-height: 8.5rem;
  }
}
@media (min-width: 2560px) and (max-width: 3839.98px) {
  .fh-card {
    padding: 1.25rem;
    min-height: 9rem;
  }
}
@media (min-width: 3840px) {
  .fh-card {
    padding: 1.4rem;
    min-height: 9.5rem;
  }
}

/* Click-to-select (Google Drive style) */
.fh-card.is-selected {
  border-color: var(--fh-primary);
  background-color: var(--fh-selected-bg, #f0f7ff);
  box-shadow: 0 0 0 1.5px var(--fh-primary), 0 4px 14px rgba(37, 99, 235, 0.12);
}
.fh-card.is-selected:hover {
  border-color: var(--fh-primary);
  box-shadow: 0 0 0 1.5px var(--fh-primary), 0 8px 22px rgba(37, 99, 235, 0.18);
}
/* Ensure .fh-card never acts as containing block or stacking context for
   position: fixed dropdown menus. Deliberately no z-index here (and none on
   .fh-card-menu either): cards are grid items that never overlap each other,
   so painting above a sibling was never the point, and a z-index on a
   positioned element creates a stacking context that would cap the fixed
   .fh-dropdown (1060) back down to whatever this rule said — previously
   tying it with .fh-navbar (1050) (hamburger vs menu) and, with z-index:5
   on the menu wrapper, sitting under .fh-content-head (1020). */
.fh-card:has(.dropdown-menu.show),
.fh-card:has([aria-expanded="true"]),
.fh-card.has-open-menu {
  position: relative;
  transform: none !important;
  transition: none !important;
}
.fh-card-icon {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 0.7rem;
  background: var(--fh-soft);
  border: 1px solid rgba(226, 232, 240, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.75rem;
  font-size: var(--fh-text-2xl);
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.fh-card:hover .fh-card-icon {
  transform: scale(1.05);
}
/* Per-type tinted icon tiles — shared with the upload dock's item list
   (.fh-upload-item-icon), one declaration per type serving both surfaces so
   the palette can't drift between them. FileTypeDisplay.Group() supplies the
   browse-side `icon-*` class (document/spreadsheet/presentation/image/
   archive/video/audio/other); `icon-folder` is browse-only. */
.fh-upload-item-icon.icon-image, .fh-card-icon.icon-image { background: #e0f2fe; color: #0284c7; }
.fh-upload-item-icon.icon-pdf { background: #ffe4e6; color: #e11d48; }
.fh-upload-item-icon.icon-archive, .fh-card-icon.icon-archive { background: #fef3c7; color: #d97706; }
.fh-upload-item-icon.icon-code { background: #dcfce7; color: #059669; }
.fh-upload-item-icon.icon-doc, .fh-card-icon.icon-document { background: #dbeafe; color: #2563eb; }
.fh-upload-item-icon.icon-excel, .fh-card-icon.icon-spreadsheet { background: #dcfce7; color: #16a34a; }
.fh-upload-item-icon.icon-presentation, .fh-card-icon.icon-presentation { background: #ffedd5; color: #ea580c; }
.fh-upload-item-icon.icon-text, .fh-card-icon.icon-other { background: #f1f5f9; color: var(--fh-muted); }
.fh-upload-item-icon.icon-video, .fh-card-icon.icon-video { background: #f3e8ff; color: #9333ea; }
.fh-upload-item-icon.icon-audio, .fh-card-icon.icon-audio { background: #fdf2f8; color: #db2777; }
.fh-card-icon.icon-folder { background: rgba(245, 158, 11, 0.12); color: #f59e0b; }
.fh-card-name {
  font-size: var(--fh-text-base);
  font-weight: var(--fh-weight-semibold);
  color: var(--fh-text);
  line-height: var(--fh-leading-snug);
  margin-bottom: 0.35rem;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: break-word;
}
.fh-card-name a,
.fh-card-name button {
  color: inherit;
  text-decoration: none;
}
/* A file card's name is a <button> (it opens the preview modal). Without this
   it renders with the UA's border/background/padding, and its block-ish box
   also defeats the -webkit-line-clamp above — hence `display: inline`. */
.fh-card-name button {
  display: inline;
  border: 0;
  background: transparent;
  padding: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.fh-card-name a:hover,
.fh-card-name button:hover {
  color: var(--fh-primary);
}

/* Card Thumbnails (Inline Image & Video Preview in Grid View) */
.fh-card-thumb {
  position: relative;
  width: 100%;
  /* Was a flat `height: 120px`. The card's width is fluid (auto-fill track),
     so a fixed height meant the thumbnail letterboxed harder the wider the
     card got — on a 4K grid a 300px-wide card showed its preview through a
     120px slot. A ratio keeps the preview proportional to the card at every
     breakpoint; the clamp stops it from becoming a tall panel on the widest
     cards or collapsing on the narrowest. */
  aspect-ratio: 4 / 3;
  height: auto;
  min-height: 5.5rem;
  max-height: 15rem;
  border-radius: 0.65rem;
  background: var(--fh-soft, #f8fafc);
  border: 1px solid rgba(226, 232, 240, 0.7);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 0.75rem;
  flex-shrink: 0;
  user-select: none;
  -webkit-user-select: none;
}

@media (min-width: 2560px) and (max-width: 3839.98px) {
  .fh-card-thumb {
    max-height: 16rem;
  }
}
@media (min-width: 3840px) {
  .fh-card-thumb {
    max-height: 18rem;
  }
}

.fh-card-thumb-media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.fh-card-thumb-media.fh-card-thumb-media--contain {
  object-fit: contain;
  background: #ffffff;
  padding: 4px;
}

.fh-card:hover .fh-card-thumb-media {
  transform: scale(1.04);
}

.fh-card-thumb-canvas {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
  background: #ffffff;
  padding: 4px;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.fh-card:hover .fh-card-thumb-canvas {
  transform: scale(1.04);
}

.fh-card-thumb--pdf {
  background: #f8fafc;
}

/* An unsized <canvas> defaults to 300x150 and would flash as a blank white sheet
   (the canvas paints its own white background) before pdf.js has drawn page 1.
   Keep it hidden until the render lands. */
.fh-card-thumb--pdf:not(.is-rendered) .fh-card-thumb-canvas {
  visibility: hidden;
}

/* Soft skeleton shimmer while pdf.js fetches and rasterises the first page. */
.fh-card-thumb--pdf.is-loading {
  background-image: linear-gradient(100deg, rgba(226, 232, 240, 0) 30%, rgba(226, 232, 240, 0.85) 50%, rgba(226, 232, 240, 0) 70%);
  background-size: 220% 100%;
  background-repeat: no-repeat;
  animation: fh-thumb-skeleton 1.4s ease-in-out infinite;
}

@keyframes fh-thumb-skeleton {
  0% {
    background-position: 130% 0;
  }
  100% {
    background-position: -30% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fh-card-thumb--pdf.is-loading {
    animation: none;
    background-image: none;
    background-color: var(--fh-soft, #f8fafc);
  }
}

/* Audio Card (Hash-colored gradient, icon, title, play badge) */
.fh-card-audio {
  background: var(--fh-audio-gradient, linear-gradient(135deg, #4f46e5, #ec4899));
  color: #ffffff;
  padding: 0.75rem;
}

.fh-card-audio-cover {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  width: 100%;
  pointer-events: none;
}

.fh-card-audio-icon {
  font-size: var(--fh-text-4xl);
  margin-bottom: 0.35rem;
  color: rgba(255, 255, 255, 0.95);
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.25));
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}

.fh-card:hover .fh-card-audio-icon {
  transform: scale(1.08);
}

.fh-card-audio-title {
  font-size: var(--fh-text-xs);
  font-weight: var(--fh-weight-semibold);
  max-width: 90%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: #ffffff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
  opacity: 0.95;
}

.fh-card-audio-play {
  position: absolute;
  bottom: 0.45rem;
  right: 0.45rem;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  border: none;
  color: #0f172a;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fh-text-sm);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.2s ease, box-shadow 0.2s ease;
  z-index: 2;
  padding-left: 2px;
}

.fh-card-audio-play:hover {
  transform: scale(1.12);
  background: #ffffff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
  color: var(--fh-primary, #2563eb);
}

/* Snippet Cards (Text / Code / Markdown ~12 lines with bottom mask fade-out) */
.fh-card-thumb--snippet {
  background: var(--fh-soft, #f8fafc);
  cursor: pointer;
  align-items: stretch;
  justify-content: stretch;
}

.fh-card-snippet-content {
  width: 100%;
  height: 100%;
  padding: 0.55rem 0.65rem;
  overflow: hidden;
  text-align: left;
  font-size: var(--fh-text-xs);
  line-height: var(--fh-leading-snug);
  color: var(--fh-text, #1e293b);
  -webkit-mask-image: linear-gradient(to bottom, black 65%, transparent 100%);
  mask-image: linear-gradient(to bottom, black 65%, transparent 100%);
  pointer-events: none;
}

.fh-card-snippet-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: var(--fh-text-3xl);
  opacity: 0.35;
}

.fh-card-text {
  font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: var(--fh-text-xs);
  line-height: var(--fh-leading-snug);
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--fh-text, #1e293b);
  background: transparent;
  border: none;
  padding: 0;
}

.fh-card-md h1, .fh-card-md h2, .fh-card-md h3, .fh-card-md h4, .fh-card-md h5, .fh-card-md h6 {
  font-size: var(--fh-text-xs);
  font-weight: var(--fh-weight-bold);
  margin: 0 0 0.2rem;
  line-height: var(--fh-leading-tight);
  color: var(--fh-text, #1e293b);
}

.fh-card-md p {
  margin: 0 0 0.25rem;
  font-size: var(--fh-text-xs);
}

.fh-card-md ul, .fh-card-md ol {
  margin: 0 0 0.25rem;
  padding-left: 1rem;
}

.fh-card-md li {
  font-size: var(--fh-text-xs);
  margin-bottom: 0.1rem;
}

.fh-card-md code {
  font-size: var(--fh-text-xs);
  background: rgba(0, 0, 0, 0.05);
  padding: 0.1rem 0.25rem;
  border-radius: 0.25rem;
}

.fh-card-md blockquote {
  margin: 0 0 0.25rem;
  padding-left: 0.5rem;
  border-left: 2px solid var(--fh-border, #cbd5e1);
  color: var(--fh-muted, #6b7280);
}

.fh-card-md .table-responsive {
  margin-bottom: 0.25rem;
}

/* Fallback state when image/video/pdf/text fails to load */
.fh-card-thumb .fh-card-thumb-fallback {
  display: none;
  margin-bottom: 0;
}

.fh-card-thumb.is-fallback {
  background: var(--fh-soft, #f8fafc);
}

.fh-card-thumb.is-fallback .fh-card-thumb-media,
.fh-card-thumb.is-fallback .fh-card-thumb-canvas,
.fh-card-thumb.is-fallback .fh-card-audio-cover,
.fh-card-thumb.is-fallback .fh-card-audio-play,
.fh-card-thumb.is-fallback .fh-card-snippet-content {
  display: none !important;
}

.fh-card-thumb.is-fallback .fh-card-thumb-fallback {
  display: flex !important;
}

@media (max-width: 575.98px) {
  .fh-card-thumb {
    /* The 4/3 ratio above already lands near the old 90px at phone card
       widths; only the trim and rhythm change here. */
    min-height: 4.5rem;
    border-radius: 0.55rem;
    margin-bottom: 0.5rem;
  }
}

/* Item actions: 3-dot (⋮) menu.
   The wrapper is position:absolute so it overlays the card, but it must NOT
   set a z-index: that creates a stacking context and traps the
   position:fixed .fh-dropdown (1060) at this layer, so the sticky
   .fh-content-head (1020) paints over the open menu. The toggle's own
   z-index (below) keeps the ⋮ button above .fh-card-thumb (position:relative)
   without wrapping the dropdown in that context. */
.fh-card-menu {
  position: absolute;
  top: 0.45rem;
  right: 0.45rem;
}
.fh-row-menu {
  display: inline-flex;
}
.fh-row-menu:has(.dropdown-menu.show),
.fh-row-menu:has([aria-expanded="true"]) {
  position: relative;
}
.fh-card-menu-toggle,
.fh-row-menu-toggle {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  color: var(--fh-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fh-text-base);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  transition: background-color 0.15s, color 0.15s, transform 0.15s, box-shadow 0.15s;
  /* On the toggle, not .fh-card-menu: a z-index on the wrapper traps the
     fixed dropdown under .fh-content-head (see the wrapper comment above). */
  z-index: 2;
}
.fh-card-menu-toggle:hover,
.fh-card-menu-toggle:focus-visible,
.fh-card-menu-toggle.show,
.fh-row-menu-toggle:hover,
.fh-row-menu-toggle:focus-visible,
.fh-row-menu-toggle.show {
  background: #ffffff;
  color: var(--fh-text);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.14);
  outline: 0;
}
.fh-card-menu .dropdown-menu,
.fh-row-menu .dropdown-menu {
  min-width: 12rem;
  font-size: var(--fh-text-sm);
  right: auto !important;
  bottom: auto !important;
}
.fh-card-menu .dropdown-item i,
.fh-row-menu .dropdown-item i {
  width: 1rem;
  text-align: center;
}
.fh-card-menu form,
.fh-row-menu form {
  margin: 0;
}
.fh-card-menu form .dropdown-item,
.fh-row-menu form .dropdown-item {
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
}

/* Empty / no-results / no-access / denied state — one component, rendered
   everywhere through Views/Shared/_EmptyState.cshtml. A calm, self-contained
   card by default (.fh-empty--card); .fh-empty--bare drops the chrome and
   fills its parent pane; .fh-empty--status widens it for a lock/title/actions
   status block; .fh-empty--compact shrinks it for narrow side panels.
   Icon tone comes from .fh-empty-icon--{default,muted,warning,danger}.
   Vertical rhythm is explicit (margins on each block) so the composition
   stays balanced with or without a subtitle or actions. Title / subtitle /
   actions rules live further down near the other content-panel typography. */
.fh-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  max-width: 32rem;
  margin-inline: auto;
  padding: 3rem 1.75rem;
  color: var(--fh-muted);
  font-size: var(--fh-text-base);
}
.fh-empty--card {
  background: var(--fh-surface, #ffffff);
  border: 1px solid var(--fh-border);
  border-radius: var(--fh-radius-xl, 0.85rem);
  box-shadow: var(--fh-shadow-sm, 0 1px 2px rgba(15, 23, 42, 0.06));
}
/* Fills the panel it sits in (admin file listing, permission detail/access
   panes, user-lookup pane, table-row empties) rather than floating as a short
   card at the top. Replaces the old per-pane copy-pasted overrides. */
.fh-empty--bare {
  flex: 1 1 auto;
  width: 100%;
  padding: 2rem 1rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* Wider so the icon / title / subtitle / actions read as one status block. */
.fh-empty--status {
  background: var(--fh-surface, #ffffff);
  border: 1px solid var(--fh-border);
  border-radius: var(--fh-radius-xl, 0.85rem);
  box-shadow: var(--fh-shadow-sm, 0 1px 2px rgba(15, 23, 42, 0.06));
  max-width: 38rem;
  width: 100%;
}
.fh-empty--compact {
  padding: 1.75rem 1rem;
}

/* Icon rides in a soft rounded badge — same family as the app's dialog icons,
   chips and avatars — instead of floating as an oversized muted glyph. */
.fh-empty-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 4rem;
  height: 4rem;
  margin-bottom: 1.1rem;
  border-radius: 50%;
  font-size: var(--fh-text-4xl);
  line-height: 1;
}
.fh-empty--compact .fh-empty-icon {
  width: 3rem;
  height: 3rem;
  margin-bottom: 0.75rem;
  font-size: var(--fh-text-2xl);
}
.fh-empty-icon--default {
  background: var(--fh-primary-soft, #eff6ff);
  color: var(--fh-primary, #2563eb);
}
.fh-empty-icon--muted {
  background: var(--fh-hover, #f1f5f9);
  color: var(--fh-muted, #6b7280);
}
.fh-empty-icon--warning {
  background: rgba(var(--fh-warning-rgb, 217, 119, 6), 0.12);
  color: var(--fh-warning, #d97706);
}
.fh-empty-icon--danger {
  background: rgba(var(--fh-danger-rgb, 220, 38, 38), 0.1);
  color: var(--fh-danger, #dc2626);
}

/* Dropzone — the visible drop band was removed; the real drag-active feedback
   is upload.js's full-page .fh-drag-overlay (styled separately below). */

/* Floating upload button (mockup) — fixed bottom-right, same trigger as the
   toolbar's "+ New" → File upload. Below the upload dock (1060) so an
   in-flight upload's status stays on top, and below the modal drawer's
   backdrop (1030 — see the z-index ladder above .fh-app) so a mobile/tablet
   user opening the sidebar can't still tap through to it. */
.fh-upload-fab {
  position: fixed;
  right: var(--fh-float-inset, 1.5rem);
  bottom: var(--fh-float-inset, 1.5rem);
  z-index: 1022;
  width: 3.25rem;
  height: 3.25rem;
  border: 0;
  border-radius: 50%;
  background: var(--fh-primary);
  color: #fff;
  font-size: var(--fh-text-xl);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 14px rgba(37, 99, 235, 0.35);
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.fh-upload-fab:hover {
  background: var(--fh-primary-dark);
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(37, 99, 235, 0.4);
}
@media (max-width: 575.98px) {
  .fh-upload-fab {
    right: var(--fh-float-inset, 1rem);
    bottom: var(--fh-float-inset, 1rem);
    width: 2.9rem;
    height: 2.9rem;
  }
}

body:has(#upload-dock:not(.is-hidden)) .fh-upload-fab {
  opacity: 0;
  pointer-events: none;
}

