/* hugo/assets/css/browse.css — /browse/ page styles (issue #174 PR 2).
   Page-level layout (banner, shell grid, rails, mobile drawer breakpoint,
   animations). Card-internal styles live in hugo-apps/src/shared/cards/card.css
   (PR 1) and load via the Vue card components.
*/

/* ── CLS guard: nav-card geometry before island CSS injects ──────────────
   card.css is loaded by the browse island via vite-plugin-css-injected-by-js
   (CSS injected into <style> tags when the island JS executes). That means
   .nav-card rules from card.css don't apply until JS runs, AFTER first paint.
   Without these rules, SSR'd cards render at one height and reflow when the
   island JS fires and injects card.css → CLS.

   #1842 duplicated ONLY `min-height:200px` + flex here. That floored short
   cards (0.503→0.187) but left every card taller than the floor to grow or
   shrink on injection — because card.css ALSO sets `padding:1.5rem`, the desc
   `-webkit-line-clamp:3`, and text metrics/margins/borders, none of which were
   mirrored. The residual 0.187 (#1854) was those late-arriving declarations,
   not the createApp DOM replacement (card markup is already byte-parity — see
   card-template-parity.test.ts; even createSSRApp wouldn't help because the
   CSS still injects after paint).

   Fix (#1854): mirror EVERY layout-affecting declaration from card.css here so
   SSR and post-mount card heights are byte-equal and the fresh render is
   height-neutral. Cosmetics (colour, background, box-shadow, border-radius,
   transition) stay in card.css — they don't affect layout, and when card.css
   loads it re-sets these same layout values (cascade no-op) plus the polish.

   DRIFT GUARD: the region between the @card-geometry-guard markers below is
   asserted to stay in sync with card.css by
   hugo-apps/src/browse/__tests__/card-geometry-parity.test.ts. If you change a
   layout property in card.css, update the mirror here or the test fails.
*/
/* @card-geometry-guard:start */
.nav-card {
  display: flex;
  flex-direction: column;
  padding: 1.5rem;
  min-height: 200px;
  position: relative;
}
.nav-card__type {
  font-size: 0.6875rem;
  font-weight: 700;
  margin-bottom: 0.75rem;
  display: flex;
  align-items: center;
  gap: 0.375rem;
}
.nav-card__title {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.4;
  margin: 0 0 0.5rem;
}
.nav-card__desc {
  font-size: 0.8125rem;
  line-height: 1.6;
  margin: 0;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.nav-card__meta {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  margin-top: 1rem;
  font-size: 0.75rem;
  flex-wrap: wrap;
}
.nav-card__meta-item {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.nav-card__tag {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--sapGroup_ContentBorderColor, #e5e5e5);
  font-size: 0.75rem;
  font-weight: 600;
}
.card-category-chip {
  display: inline-block;
  margin-top: 0.5rem;
  padding: 0.125rem 0.5rem;
  border: 1px solid var(--sapAccentColor5, #507090);
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
}
/* @card-geometry-guard:end */

/* ── Desktop layout ──────────────────────────────────────────── */

.browse-shell {
  display: grid;
  grid-template-columns: 280px 1fr;
  gap: 1.5rem;
  max-width: 1440px;
  margin: 0 auto;
  padding: 1rem;
}

.browse-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1rem;
}

.browse-rail-curation {
  display: grid;
  grid-template-columns: repeat(5, minmax(220px, 1fr));
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.browse-rail-curation > * { scroll-snap-align: start; }

/* ── Banner ──────────────────────────────────────────────────── */

.browse-banner {
  background: var(--sapShellColor);
  padding: 1.5rem 1rem;
  text-align: center;
}
.browse-banner h1 { margin: 0 0 1rem; }
.browse-banner__search {
  width: 100%;
  max-width: 480px;
  padding: 0.5rem 0.75rem;
}

/* ── Skip-link (a11y) ────────────────────────────────────────── */

.skip-link {
  position: absolute;
  top: -40px;
  left: 0;
  padding: 0.5rem 1rem;
  background: var(--sapShellColor);
}
.skip-link:focus { top: 0; }

/* ── Mobile filter drawer (#216) ─────────────────────────────────────
   - Filters button is hidden on desktop, sticky-bar above the grid on mobile.
   - Below 1024px: keep the SSR'd #browse-filter-rail hidden in its original
     parent (controller.ts moves it into <ui5-dialog> on first open). The
     rail is unconditionally visible *inside* the dialog so it renders
     correctly when the drawer opens.
*/

/* Default desktop: hide the toggle button entirely. */
.browse-filter-toggle { display: none; }

/* Active-filter count badge inside the toggle button. */
.browse-filter-toggle__count {
  display: inline-block;
  margin-inline-start: 0.25rem;
  min-width: 1.5em;
  padding: 0 0.4em;
  border-radius: 999px;
  background: var(--sapButton_Selected_Background, #0a6ed1);
  color: var(--sapButton_Selected_TextColor, #fff);
  font-size: 0.85em;
  font-weight: 600;
  text-align: center;
}
.browse-filter-toggle__count[hidden] { display: none; }

@media (max-width: 1023px) {
  .browse-shell { grid-template-columns: 1fr; }
  /* Hide the rail in its original DOM position; the dialog re-shows it. */
  #browse-filter-rail { display: none; }
  .browse-rail-curation {
    grid-template-columns: repeat(3, minmax(200px, 80vw));
  }

  /* Sticky bar above the grid: button + title + sort, single row. */
  .browse-grid-header {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--sapBackgroundColor, #fff);
    padding-block: 0.5rem;
    margin-bottom: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
  }
  .browse-filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.85rem;
    border: 1px solid var(--sapButton_BorderColor, #b3b3b3);
    background: var(--sapButton_Background, #fff);
    color: var(--sapButton_TextColor, inherit);
    border-radius: 0.5rem;
    cursor: pointer;
    font: inherit;
    line-height: 1;
  }
  .browse-filter-toggle:hover { background: var(--sapButton_Hover_Background, #ebf5fe); }
  .browse-filter-toggle:focus-visible {
    outline: 2px solid var(--sapButton_Focus_BorderColor, #0a6ed1);
    outline-offset: 2px;
  }
  /* Title shrinks but stays visible; sort sits at the end. */
  .browse-grid-title { font-size: 1rem; margin: 0; }
  .browse-sort { margin-inline-start: auto; }
}

/* Inside the dialog the rail is always visible regardless of viewport
   (the dialog is only opened on mobile, but we don't want the @media
   rule above to keep #browse-filter-rail { display: none } when it's a
   dialog descendant). The descendant selector wins on specificity. */
ui5-dialog#browse-filter-drawer #browse-filter-rail {
  display: block;
}

/* ── Progress-ring draw-in (decision #13) ────────────────────── */
/* The Vue island adds nav-card__progress--animate-in to the ring on
   hydration; this keyframe sweeps the stroke-dashoffset from full
   (empty ring) to its target value (actual progress). The marker
   class is rendered by ProgressOverlay.vue (PR 1); the keyframes
   live here so /browse/ owns the visual layer.
*/
.nav-card__progress--animate-in circle.ring__indicator {
  animation: ring-draw-in 250ms ease forwards;
}
@keyframes ring-draw-in {
  from { stroke-dashoffset: var(--ring-circumference); }
  to   { stroke-dashoffset: var(--ring-target); }
}
@media (prefers-reduced-motion: reduce) {
  .nav-card__progress--animate-in circle.ring__indicator { animation: none; }
}

/* ── Filter rail (aside, fieldset, label) ───────────────────────────
   The rail is a static SSR'd <aside> with <fieldset> groups. Without
   block layout on the labels the checkbox + text wrap independently
   when the column is narrow — e.g. 'Advanced' wraps to its own line
   while its checkbox stays at the end of the prior line. Block-style
   labels (display: flex) keep checkbox and text together, one filter
   per row. */

.browse-rail {
  /* The .browse-shell grid column is 280px on desktop; the rail just
     needs vertical stacking and a comfortable type scale. */
  font-size: 0.875rem;
}

.browse-filter-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.browse-filter-group {
  border: 1px solid var(--sapGroup_ContentBorderColor, #d9d9d9);
  border-radius: 0.25rem;
  padding: 0.5rem 0.75rem 0.75rem;
  margin: 0;
}

.browse-filter-group legend {
  padding: 0 0.25rem;
  font-weight: 600;
  color: var(--sapGroup_TitleTextColor, inherit);
}

.browse-filter-group label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.25rem 0;
  cursor: pointer;
}

.browse-filter-group label input[type="checkbox"] {
  flex: 0 0 auto;   /* checkbox keeps its native size; text fills remainder */
}

.browse-filter-clear {
  align-self: flex-start;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--sapButton_BorderColor, #b3b3b3);
  border-radius: 0.5rem;
  background: var(--sapButton_Background, #fff);
  color: var(--sapButton_TextColor, inherit);
  cursor: pointer;
  font: inherit;
}
.browse-filter-clear:hover { background: var(--sapButton_Hover_Background, #ebf5fe); }
.browse-filter-clear:focus-visible {
  outline: 2px solid var(--sapButton_Focus_BorderColor, #0a6ed1);
  outline-offset: 2px;
}

/* ── Rails hidden when filter/search active (decision Q4, issue #281) ──── */
/* Vue island sets [data-rails-hidden] on the data-rails-container div
   when any filter is active or a search query is present. The container
   must collapse from layout — not just fade — so the card grid moves up
   to fill the space. The original implementation used `opacity: 0` only,
   which left a ~1400px-tall invisible block above the grid and made the
   page appear empty after any filter click (#281).
   If a smooth fade-then-collapse animation is needed later, follow up
   with a JS hook that toggles `display: none` on `transitionend`; for
   now layout integrity beats a 150ms transition. */
[data-rails-container][data-rails-hidden] {
  display: none;
}

/* ── Per-rail collapse + Customize popover (#285) ─────────────────────── */
/* Each <section data-rail data-rail-id="..."> gets a chevron toggle in its
   header. When [data-collapsed], the cards strip is hidden but the header
   stays visible so the user can expand again. When [data-rail-hidden]
   (set from the Customize popover), the whole rail is removed from layout
   — same idiom as data-rails-hidden above but per-rail. */

.browse-rail__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  background: none;
  border: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  text-align: start;
}
.browse-rail__toggle:hover .browse-rail__title { text-decoration: underline; }
.browse-rail__toggle:focus-visible {
  outline: 2px solid var(--sapButton_Focus_BorderColor, #0a6ed1);
  outline-offset: 2px;
  border-radius: 0.25rem;
}

.browse-rail__chevron {
  display: inline-block;
  transition: transform 150ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .browse-rail__chevron { transition: none; }
}
[data-rail][data-collapsed] .browse-rail__chevron {
  transform: rotate(-90deg);   /* ▾ → ▸ */
}

[data-rail][data-collapsed] .browse-rail-curation { display: none; }
[data-rail][data-rail-hidden] { display: none; }

/* Customize button reuses the Filters-toggle vocabulary (button styling
   shared via CSS so the two buttons look like a coherent toolbar group). */
.browse-customize-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem 0.85rem;
  border: 1px solid var(--sapButton_BorderColor, #b3b3b3);
  background: var(--sapButton_Background, #fff);
  color: var(--sapButton_TextColor, inherit);
  border-radius: 0.5rem;
  cursor: pointer;
  font: inherit;
  line-height: 1;
}
.browse-customize-toggle:hover { background: var(--sapButton_Hover_Background, #ebf5fe); }
.browse-customize-toggle:focus-visible {
  outline: 2px solid var(--sapButton_Focus_BorderColor, #0a6ed1);
  outline-offset: 2px;
}

.browse-customize-popover__body {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.75rem 1rem;
}
.browse-customize-popover__body label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  cursor: pointer;
}
