/* ==========================================================================
   MabunCrib — Responsive
   File: css/responsive.css

   Loaded LAST. Only cross-cutting adjustments. Component-specific
   responsive rules stay inside their own component files.

   Documented breakpoints:
     xs:  360px   ← small phones (defined in :root override below)
     sm:  480px   ← larger phones
     md:  768px   ← tablets portrait
     lg:  1024px  ← tablets landscape / small laptops
     xl:  1200px  ← laptops
     2xl: 1440px  ← large displays

   Requires from css/core/variables.css:
     --content-max, --content-narrow, --content-wide
     --space-*, --radius-*, --fs-*, --fw-*, --tracking-tight,
     --header-height, --bottom-nav-height, --safe-area-bottom,
     --color-text, --color-text-soft, --color-border, --color-white
   ========================================================================== */


/* ==========================================================================
   Root adjustments
   --------------------------------------------------------------------------
   These apply across every page and every chrome state.
   ========================================================================== */

html {
  /* Anchor links land below the sticky header */
  scroll-padding-top: calc(var(--header-height) + var(--space-4));

  /* Reserve the scrollbar gutter to prevent layout shift when content
     grows or shrinks (list loading, modals, etc.) */
  scrollbar-gutter: stable;
}

@media (max-width: 1023px) {
  html {
    scroll-padding-top: calc(var(--header-height) + var(--space-3));
  }
}

/* Modern font rendering — antialiased over subpixel for large type */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* Safer default for text wrapping when the property is supported */
@supports (text-wrap: balance) {
  h1, h2, h3,
  .page-title,
  .hero-title,
  .display {
    text-wrap: balance;
  }

  p, .lede, .hero-subtitle, .page-subtitle {
    text-wrap: pretty;
  }
}


/* ==========================================================================
   Container system
   --------------------------------------------------------------------------
   Four widths, one padding scale. Pages use .container by default; use
   .container-narrow for reading-focused pages, .container-wide for
   dashboard-style layouts that benefit from more horizontal room.
   ========================================================================== */

.container,
.container-narrow,
.container-wide,
.container-full {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--space-4);
}

.container        { max-width: var(--content-max); }
.container-narrow { max-width: var(--content-narrow); }
.container-wide   { max-width: var(--content-wide); }
.container-full   { max-width: 100%; }

@media (min-width: 480px) {
  .container,
  .container-narrow,
  .container-wide,
  .container-full {
    padding-inline: var(--space-5);
  }
}

@media (min-width: 768px) {
  .container,
  .container-narrow,
  .container-wide,
  .container-full {
    padding-inline: var(--space-6);
  }
}

@media (min-width: 1024px) {
  .container,
  .container-wide,
  .container-full {
    padding-inline: var(--space-8);
  }
}

@media (min-width: 1440px) {
  .container,
  .container-wide,
  .container-full {
    padding-inline: var(--space-10);
  }
}


/* ==========================================================================
   Section rhythm
   --------------------------------------------------------------------------
   Vertical spacing for top-level content sections on public and
   authenticated pages. Aligned with the rest of the design system —
   generous, not cramped.
   ========================================================================== */

.section {
  padding-block: var(--space-12);
}

.section-tight {
  padding-block: var(--space-8);
}

.section-loose {
  padding-block: var(--space-16);
}

@media (min-width: 768px) {
  .section        { padding-block: var(--space-16); }
  .section-tight  { padding-block: var(--space-10); }
  .section-loose  { padding-block: var(--space-20); }
}

@media (min-width: 1024px) {
  .section        { padding-block: var(--space-20); }
  .section-tight  { padding-block: var(--space-12); }
  .section-loose  { padding-block: var(--space-20); padding-block-end: calc(var(--space-20) + var(--space-8)); }
}

/* First and last sections in a container flow — collapse extra space */
.section + .section-tight,
.section-tight + .section {
  padding-top: 0;
}


/* ==========================================================================
   Page header
   ========================================================================== */

.page-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding-block: var(--space-5) var(--space-4);
}

@media (min-width: 768px) {
  .page-head {
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-6);
    padding-block: var(--space-6) var(--space-5);
  }
}

.page-head-main {
  min-width: 0;
  flex: 1 1 auto;
}

.page-head-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  flex: 0 0 auto;
}

.page-title {
  font-size: var(--fs-h1-mobile);
  font-weight: var(--fw-bold);
  line-height: 1.15;
  color: var(--color-text);
  letter-spacing: var(--tracking-tight);
  overflow-wrap: anywhere;
}

@media (min-width: 768px) {
  .page-title {
    font-size: var(--fs-h1-desktop);
  }
}

.page-subtitle {
  font-size: var(--fs-body-sm);
  color: var(--color-text-soft);
  margin-top: var(--space-2);
  max-width: 62ch;
  line-height: 1.55;
}


/* ==========================================================================
   Stack — single column with optional sticky aside
   --------------------------------------------------------------------------
   DOM order is always: main content first, aside second.
   .stack-aside         → main | aside (right)
   .stack-aside-reverse → aside (left) | main
   ========================================================================== */

.stack {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
}

@media (min-width: 1024px) {
  .stack-aside {
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: var(--space-6);
    align-items: start;
  }

  .stack-aside-reverse {
    grid-template-columns: 320px minmax(0, 1fr);
    gap: var(--space-6);
    align-items: start;
  }

  .stack-aside > aside,
  .stack-aside-reverse > aside {
    position: sticky;
    top: calc(var(--header-height) + var(--space-4));
    align-self: start;
    max-height: calc(100vh - var(--header-height) - var(--space-8));
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  @supports (max-height: 100dvh) {
    .stack-aside > aside,
    .stack-aside-reverse > aside {
      max-height: calc(100dvh - var(--header-height) - var(--space-8));
    }
  }
}


/* ==========================================================================
   Split — equal-column grids
   ========================================================================== */

.split {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-5);
}

@media (min-width: 768px) {
  .split-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .split-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-6); }
}

/* Auto-fit — the same split, but column count adapts to available width.
   Used for card grids that don't have a fixed target count. */
.split-auto {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: var(--space-4);
}

@media (min-width: 1024px) {
  .split-auto { gap: var(--space-5); }
}


/* ==========================================================================
   Mobile table → stacked records
   --------------------------------------------------------------------------
   The .table component in tables.css already handles this internally.
   This utility is for legacy tables that don't yet use .table.
   ========================================================================== */

@media (max-width: 767px) {
  .responsive-table {
    border: 0;
    border-collapse: collapse;
    width: 100%;
  }

  .responsive-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .responsive-table tbody,
  .responsive-table tr,
  .responsive-table td {
    display: block;
    width: 100%;
  }

  .responsive-table tr {
    padding: var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-3);
    background-color: var(--color-white);
  }

  .responsive-table td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) 0;
    border: 0;
    font-size: var(--fs-body-sm);
    text-align: right;
  }

  .responsive-table td + td {
    border-top: 1px solid var(--color-border);
  }

  .responsive-table td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    max-width: 45%;
    font-size: 11px;
    font-weight: var(--fw-semibold);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--color-text-soft);
    text-align: left;
  }
}


/* ==========================================================================
   Visibility utilities
   --------------------------------------------------------------------------
   Uses media-query gating instead of display: none + revert, which is
   unreliable across browsers. Each class only applies inside its own
   media query, so no reset is needed.
   ========================================================================== */

@media (max-width: 767px) {
  .hide-mobile { display: none !important; }
}

@media (min-width: 768px) {
  .hide-desktop { display: none !important; }
}

@media (min-width: 1024px) {
  .hide-lg { display: none !important; }
}

@media (max-width: 1023px) {
  .hide-below-lg { display: none !important; }
}

@media (max-width: 479px) {
  .hide-xs { display: none !important; }
}

@media (min-width: 1440px) {
  .hide-2xl { display: none !important; }
}


/* ==========================================================================
   Small viewport safety (320px–359px)
   --------------------------------------------------------------------------
   Only type scales are adjusted. Do NOT override spacing tokens here —
   they cascade to every component and cause layout drift.
   ========================================================================== */

@media (max-width: 359px) {
  :root {
    --fs-hero-mobile: 28px;
    --fs-h1-mobile:   24px;
    --fs-h2-mobile:   20px;
  }

  /* Slightly tighter padding for cards and page chrome on very small screens */
  .card { padding: var(--space-4); }
  .container,
  .container-narrow,
  .container-wide,
  .container-full { padding-inline: var(--space-3); }
}


/* ==========================================================================
   Overflow protection
   --------------------------------------------------------------------------
   Prevents long words, URLs, and user-generated content from breaking
   layout at every viewport size.
   ========================================================================== */

.break-anywhere {
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
}

/* Global safety net for user content inside cards */
.card,
.table tbody td,
.alert,
.toast {
  min-width: 0;
}

/* Images and media never overflow their containers */
img,
video,
canvas,
svg {
  max-width: 100%;
  height: auto;
}


/* ==========================================================================
   Wide viewport controls
   --------------------------------------------------------------------------
   At large sizes, don't let text stretch indefinitely. Cap reading widths
   and give layouts more breathing room rather than wider content.
   ========================================================================== */

@media (min-width: 1440px) {
  .prose,
  .lede,
  .hero-subtitle,
  .page-subtitle {
    max-width: 72ch;
  }

  /* Give big grids extra gap without widening columns */
  .card-grid,
  .split-auto {
    gap: var(--space-6);
  }
}


/* ==========================================================================
   Landscape phones
   --------------------------------------------------------------------------
   Drawers, modals, and sheets need tighter chrome on short viewports.
   ========================================================================== */

@media (max-height: 480px) and (orientation: landscape) {
  .drawer-panel {
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  .drawer-header {
    min-height: 44px;
    padding-block: var(--space-2);
  }

  .drawer-body {
    padding: var(--space-3);
  }

  .modal-panel {
    max-height: calc(100vh - var(--space-4));
  }

  .modal-header {
    min-height: 48px;
    padding-block: var(--space-3);
  }

  .modal-foot {
    padding-block: var(--space-3);
  }

  .action-sheet-panel {
    max-width: 640px;
  }
}


/* ==========================================================================
   Safe-area handling
   --------------------------------------------------------------------------
   Authenticated pages on mobile carry a fixed bottom nav. The last element
   in the page flow needs to clear it.
   ========================================================================== */

@media (max-width: 1023px) {
  [data-authenticated="true"] {
    /* Applies to the body or any wrapper with this attribute */
  }

  [data-authenticated="true"] .site-footer,
  [data-authenticated="true"] .page-foot {
    padding-bottom: calc(
      var(--bottom-nav-height) +
      var(--safe-area-bottom) +
      var(--space-6)
    );
  }
}

/* Landscape mode on iOS: no safe-area-top, but the notch is on the side */
@media (orientation: landscape) {
  [data-authenticated="true"] .site-footer,
  [data-authenticated="true"] .page-foot {
    padding-left: env(safe-area-inset-left, 0px);
    padding-right: env(safe-area-inset-right, 0px);
  }
}


/* ==========================================================================
   Touch vs hover
   --------------------------------------------------------------------------
   Disable hover-only lift effects on touch devices — otherwise they
   trigger on tap and stick until the user taps elsewhere.
   ========================================================================== */

@media (hover: none) {
  .card-interactive:hover,
  .metric:hover,
  .cat-card:hover,
  .pro-card:hover,
  .org-select:hover,
  .nav-inline .nav-link:hover {
    transform: none;
    box-shadow: none;
  }

  .card-interactive:hover,
  .cat-card:hover,
  .metric:hover {
    border-color: var(--color-border);
  }

  /* Active state carries the tap feedback on touch devices */
  .card-interactive:active,
  .cat-card:active,
  .metric:active {
    background-color: var(--state-hover);
  }
}

/* Enforce touch-target minimum on coarse pointers */
@media (pointer: coarse) {
  .pagination-item,
  .load-more-button,
  .tab,
  .segmented .tab,
  .filter-option,
  .bottom-nav-item,
  .action-sheet-item,
  .dropdown-item {
    min-height: 44px;
  }
}


/* ==========================================================================
   Reduced motion — global safety net
   --------------------------------------------------------------------------
   Individual components handle their own reduced-motion states. This rule
   catches anything that slipped through and disables smooth scrolling.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }

  /* A single sweeping rule for any component that missed its own bailout.
     Uses the targeted selector so we don't kill informational animation
     (progress bars, spinners) which reduced-motion users still need. */
  [data-motion="decorative"],
  [data-motion="decorative"] *,
  [data-motion="decorative"] *::before,
  [data-motion="decorative"] *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}


/* ==========================================================================
   Reduced data
   --------------------------------------------------------------------------
   For users on metered connections. Components that opt in by attribute
   stop rendering decorative media.
   ========================================================================== */

@media (prefers-reduced-data: reduce) {
  [data-decorative-media] {
    display: none !important;
  }

  .org-header-cover,
  .frame-decoration,
  .card-cover-image {
    display: none !important;
  }
}


/* ==========================================================================
   Container queries
   --------------------------------------------------------------------------
   Progressive enhancement for modern browsers. Components that adopt
   container queries opt in by setting container-type on a parent.
   ========================================================================== */

@supports (container-type: inline-size) {
  .card-grid,
  .split-auto,
  .metric-grid {
    container-type: inline-size;
  }

  /* Sidebar becomes stacked inside narrow containers */
  @container (max-width: 600px) {
    .stack-aside,
    .stack-aside-reverse {
      grid-template-columns: minmax(0, 1fr);
    }

    .stack-aside > aside,
    .stack-aside-reverse > aside {
      position: static;
      max-height: none;
    }
  }
}


/* ==========================================================================
   Print
   --------------------------------------------------------------------------
   Strip interaction-only chrome. Keep semantic structure intact.
   ========================================================================== */

@media print {
  /* Remove navigation, overlays, and interactive-only chrome */
  #site-header,
  #site-sidebar,
  #mobile-bottom-nav,
  .drawer,
  .modal,
  .modal-scrim,
  .action-sheet,
  .action-sheet-scrim,
  .toast-region,
  .scroll-cue,
  .grain,
  .progress,
  .skip-link,
  .table-check,
  .pagination,
  .load-more,
  .filters-sheet,
  .filter-toolbar,
  .alert-dismiss,
  .toast-dismiss,
  .upload,
  .upload-list,
  .nav,
  .nav-links,
  .breadcrumbs {
    display: none !important;
  }

  /* Reset the app shell to a single column */
  #app-layout,
  #app-layout[data-authenticated="true"] {
    display: block !important;
    grid-template-columns: none !important;
  }

  /* Full-width containers on paper */
  .container,
  .container-narrow,
  .container-wide,
  .container-full {
    max-width: 100% !important;
    padding-inline: 0 !important;
  }

  /* Clean, legible body */
  body {
    background: #fff !important;
    color: #000 !important;
    font-size: 11pt;
    line-height: 1.5;
  }

  /* Ensure headings and cards don't break across pages */
  h1, h2, h3, h4 {
    page-break-after: avoid;
    break-after: avoid;
  }

  .card,
  .metric,
  .chart,
  .quote,
  .org-team-row,
  .upload-item {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  /* Show URLs after links, but only inside content regions */
  .prose a[href]:not([href^="#"]):not([href^="javascript:"])::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #555;
    word-break: break-all;
  }

  /* Page margins and link underline */
  a {
    color: #000;
    text-decoration: underline;
    text-underline-offset: 2px;
  }

  /* Flatten shadows — they print as muddy grey */
  .card,
  .metric,
  .chart,
  .form-card,
  .dropdown-panel {
    box-shadow: none !important;
    border: 1px solid #ccc !important;
  }
}


/* ==========================================================================
   Forced colors (Windows High Contrast Mode)
   --------------------------------------------------------------------------
   A global safety net. Individual components carry their own overrides.
   ========================================================================== */

@media (forced-colors: active) {
  /* Ensure every focus ring uses the system Highlight color */
  :focus-visible {
    outline: 2px solid Highlight !important;
    outline-offset: 2px !important;
  }

  /* Links inside content should always be underlined in HC mode */
  .prose a,
  .alert-text a {
    text-decoration: underline;
  }
}