/* ─────────────────────────────────────────────────────────────
   Babykare ERP — Mobile Dashboard Redesign (2026-05-15)

   Goal: dedicated mobile-first treatment for the Home Dashboard
   (route "/", view dashboard/v2.html.erb). DESKTOP UNTOUCHED.

   Spec: docs/superpowers/specs/2026-05-15-mobile-dashboard-redesign-design.md
   Audit: docs/superpowers/audits/2026-05-15-mobile-dashboard-redesign-audit.md

   Boundary: this file lives ENTIRELY inside @media (max-width: 1023px).
   Above 1024px the dashboard renders as before.

   Sections
     0. Visibility helpers (md-only / md-hidden)
     1. Filter bar — single-button trigger + chip rail + bottom sheet
     2. Compact KPI grid + tap affordance
     3. Full-screen KPI detail dialog + carousel rail + dots
     4. Animations + reduced motion
   ───────────────────────────────────────────────────────────── */

/* ── 0. Visibility helpers ───────────────────────────────────
   md-only  → visible <1024px, hidden ≥1024px (mobile-only DOM)
   md-hidden → visible ≥1024px, hidden <1024px (desktop-only DOM)
   Use these on dashboard partials so the same view template
   contains both layouts; CSS swaps them at breakpoint.

   Implementation note: we use `display: none !important` for the
   hidden state so it beats Tailwind utilities like `flex` /
   `inline-flex`. The visible state is achieved by simply NOT
   applying `display: none` — which means the element falls back
   to whatever display value the rest of the cascade gives it
   (e.g. `flex` from a Tailwind utility, `block` for <p>, etc.).
   ───────────────────────────────────────────────────────────── */
/* Default: hide mobile-only DOM at desktop sizes. */
@media (min-width: 1024px) {
  .md-only { display: none !important; }
}
/* Default: hide desktop-only DOM at mobile/tablet sizes. */
@media (max-width: 1023px) {
  .md-hidden { display: none !important; }
}

/* ─────────────────────────────────────────────────────────────
   EVERYTHING BELOW IS GUARDED BY <1024px.
   The dashboard at desktop sizes must remain visually identical
   to the pre-existing implementation.
   ───────────────────────────────────────────────────────────── */

@media (max-width: 1023px) {

  /* ── Body lock when a dashboard sheet/dialog is open ───────── */
  body[data-mobile-dashboard-open="true"] { overflow: hidden; }

  /* ── Line-chart data labels — hide on mobile (2026-05-19) ─────
     ApexCharts renders per-point numeric annotations into two SVG
     group classes. On narrow viewports they overlap and create noise;
     desktop keeps the labels unchanged (this rule is inside the
     <1024px media query only). Scoped to #dashboard-v2-content so
     it does not affect other charts on other pages.
     ───────────────────────────────────────────────────────────── */
  #dashboard-v2-content [data-controller~="apex-chart"] .apexcharts-datalabels,
  #dashboard-v2-content [data-controller~="apex-chart"] .apexcharts-data-labels {
    display: none !important;
  }

  /* ── Mobile chart density (2026-05-18) ───────────────────────
     Operator ask: charts (Ventes au fil du temps, CA par marketplace,
     Donut, Détail par marketplace, Geo, Returns) waste too much
     horizontal/vertical real-estate on phone. Shrink the outer
     `<main>` lateral padding, the gap between cards, and the
     internal `.card-base` padding so the chart area itself takes
     ~94% of the viewport width. Scoped to the dashboard turbo-frame
     so we don't touch other pages.
     ───────────────────────────────────────────────────────────── */
  #main-content {
    padding-left: var(--space-3) !important;
    padding-right: var(--space-3) !important;
    padding-top: var(--space-3) !important;
  }
  #dashboard-v2-content .space-y-5 > * + * {
    margin-top: var(--space-3) !important;
  }
  #dashboard-v2-content .card-base {
    padding: var(--space-3);
  }
  #dashboard-v2-content .card-base .card__header,
  #dashboard-v2-content .card-base > .mb-3 {
    margin-bottom: var(--space-2) !important;
  }

  /* ── 1. Topbar slimming — turn off the old desktop padding ─── */
  /* The dashboard topbar in this view (.filters-topbar) gets the
     desktop padding from inline style. Override on mobile so we don't
     waste 32px each side. */
  .filters-topbar {
    padding: var(--space-2) var(--space-3) !important;
  }
  .filters-topbar__row {
    /* Row 1: hamburger | logo | title (mr-auto) | bell — no wrap */
    flex-wrap: nowrap !important;
    gap: var(--space-2) !important;
  }
  .filters-topbar__title h1 {
    font-size: 13px;
    line-height: 1.2;
  }

  /* ── 2. Mobile filter chip rail ─────────────────────────────
     Operator decision (2026-05-17): collapsed to TWO equal slots —
     [Filtre] (opens bottom-sheet with all 3 filters) and [Objectif]
     (opens targets modal). Chip width is ISO with the KPI compact
     card grid below (same 2-col layout + same gap), so the eye
     reads the topbar and the KPI grid as a single rhythm. */
  .mobile-filter-chips {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
    margin-top: var(--space-2);
    width: 100%;
  }

  .mobile-filter-chip {
    /* Touch target preserved (>=40px), but shorter than the previous
       44px so the topbar takes less vertical real-estate above the KPI
       grid on iPhone-class viewports. */
    min-height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0 var(--space-3);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text-primary);
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    /* min-width 0 so flexbox children may shrink for ellipsis */
    min-width: 0;
    transition: background var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default),
                transform var(--duration-fast) var(--ease-default);
  }
  .mobile-filter-chip:hover { background: var(--color-surface-raised); }
  .mobile-filter-chip:active { transform: scale(0.97); }
  .mobile-filter-chip:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  .mobile-filter-chip--icon {
    padding: 0;
    background: var(--color-accent-soft);
    border-color: var(--color-accent-soft);
    color: var(--color-accent);
  }
  .mobile-filter-chip--icon:hover {
    background: var(--color-accent);
    color: white;
    border-color: var(--color-accent);
  }

  /* CTA variant — Objectifs button on the chip rail. Visually distinct
     from filter chips (filled accent) so the operator reads it as an
     action (open modal) rather than a filter that opens the sheet. */
  .mobile-filter-chip--cta {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: white;
    text-decoration: none;
  }
  .mobile-filter-chip--cta:hover {
    background: var(--color-accent-hover, #9a6b61);
    border-color: var(--color-accent-hover, #9a6b61);
    color: white;
  }
  .mobile-filter-chip--cta:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  .mobile-filter-chip__label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
  }

  .mobile-filter-chip__dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
  }

  /* ── 3. Mobile bottom-sheet dialog (filters) ──────────────── */
  .mobile-sheet[open] {
    /* Reset native <dialog> defaults that would center us */
    position: fixed;
    inset: auto 0 0 0;
    margin: 0;
    width: 100vw;
    max-width: 100vw;
    max-height: 85vh;
    height: auto;
    padding: 0;
    border: 0;
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
    background: var(--color-surface);
    box-shadow: var(--shadow-lg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Slide-up animation */
    animation: mobile-sheet-rise 250ms var(--ease-out-expo);
  }
  /* Backdrop styling for native <dialog> */
  .mobile-sheet::backdrop {
    background: rgba(26, 18, 8, 0.45);
    animation: mobile-sheet-backdrop-in 250ms var(--ease-default);
  }

  .mobile-sheet__handle {
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--color-border-strong);
    margin: var(--space-2) auto;
    flex-shrink: 0;
  }

  .mobile-sheet__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-1) var(--space-3) var(--space-2);
    flex-shrink: 0;
  }
  .mobile-sheet__title {
    font-size: 17px;
    font-weight: 700;
    color: var(--color-text-primary);
    margin: 0;
  }
  .mobile-sheet__close {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
    color: var(--color-text-muted);
    margin-right: -8px; /* balance optical alignment */
  }
  .mobile-sheet__close:hover {
    background: var(--color-bg);
    color: var(--color-text-primary);
  }
  .mobile-sheet__close:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  .mobile-sheet__body {
    padding: 0 var(--space-3) var(--space-3);
    overflow-y: auto;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
  }

  .mobile-sheet__field { display: flex; flex-direction: column; gap: 6px; }

  .mobile-sheet__label {
    font-size: 12px;
    font-weight: 700;
    color: var(--color-text-secondary);
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }

  .mobile-sheet__footer {
    padding: var(--space-3);
    border-top: 1px solid var(--color-border);
    flex-shrink: 0;
    padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  }

  /* Stretch-to-100% combobox variants used inside the sheet */
  .combobox--full,
  .combobox--full .combobox-trigger {
    width: 100%;
  }
  .combobox--full .combobox-trigger {
    min-height: 48px;
    justify-content: space-between;
    font-size: 14px;
  }
  .combobox--full .combobox-menu {
    width: 100%;
    max-width: calc(100vw - 32px);
    max-height: 50vh;
  }

  /* ── 4. Compact KPI grid ──────────────────────────────────── */
  .kpi-compact-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-2);
  }

  /* iPad-landscape band (≥900 and <1024): 4-up so each card breathes.
     Below 900 we stay 2-up because the sidebar already eats ~256px
     of horizontal real-estate at ≥sm, leaving cards too narrow to
     show a 7-digit euro value. */
  @media (min-width: 900px) {
    .kpi-compact-grid {
      grid-template-columns: repeat(4, minmax(0, 1fr));
      gap: var(--space-3);
    }
  }

  .kpi-compact {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    box-shadow: var(--shadow-xs);
    cursor: pointer;
    color: var(--color-text-primary);
    /* Touch + visual hierarchy: aim ~104px tall so two rows fit
       comfortably above the first chart on iPhone 14. */
    min-height: 104px;
    transition: box-shadow var(--duration-fast) var(--ease-default),
                border-color var(--duration-fast) var(--ease-default),
                transform 100ms var(--ease-default);
    /* No tap-highlight overlay on iOS */
    -webkit-tap-highlight-color: transparent;
  }
  .kpi-compact:hover {
    border-color: var(--color-accent);
    box-shadow: var(--shadow-sm);
  }
  .kpi-compact:active { transform: scale(0.97); }
  .kpi-compact:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }

  .kpi-compact__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-2);
  }

  .kpi-compact__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    background: var(--color-accent-soft);
    flex-shrink: 0;
  }

  .kpi-compact__delta {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.01em;
    white-space: nowrap;
  }

  .kpi-compact__value {
    font-size: 22px;
    font-weight: 700;
    font-family: var(--font-mono);
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--color-text-primary);
    margin: 0;
    /* truncate big numbers on narrowest viewport (320px) */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .kpi-compact__value--text {
    /* SKU strings — slightly smaller, monospace stays */
    font-size: 16px;
  }

  .kpi-compact__label {
    font-size: 11px;
    font-weight: 600;
    color: var(--color-text-secondary);
    margin: 4px 0 0;
    letter-spacing: 0.02em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* ── 5. KPI detail full-screen dialog ─────────────────────── */
  .kpi-detail-dialog[open] {
    position: fixed;
    inset: 0;
    margin: 0;
    width: 100vw;
    height: 100vh;
    /* Use dvh on supporting browsers so iOS URL bar doesn't clip us */
    height: 100dvh;
    max-width: 100vw;
    max-height: 100dvh;
    padding: 0;
    border: 0;
    background: var(--color-bg);
    color: var(--color-text-primary);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    /* Slide-up entry */
    animation: kpi-detail-rise 250ms var(--ease-out-expo);
  }
  .kpi-detail-dialog::backdrop {
    background: rgba(26, 18, 8, 0.45);
  }

  /* Topbar inside the dialog */
  .kpi-detail-dialog__topbar {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    flex-shrink: 0;
    /* iOS notch padding */
    padding-top: max(var(--space-1), env(safe-area-inset-top, 0px));
    /* Touch target for swipe-down — make the whole header swipeable */
    touch-action: pan-y;
  }
  .kpi-detail-dialog__handle {
    width: 36px;
    height: 4px;
    border-radius: 2px;
    background: var(--color-border-strong);
    margin: var(--space-1) auto var(--space-1);
    flex-shrink: 0;
  }
  .kpi-detail-dialog__topbar-row {
    display: grid;
    grid-template-columns: 44px 1fr auto;
    align-items: center;
    gap: var(--space-2);
    padding: 0 var(--space-3) var(--space-2);
  }
  .kpi-detail-dialog__close {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    cursor: pointer;
    color: var(--color-text-primary);
  }
  .kpi-detail-dialog__close:hover { background: var(--color-bg); }
  .kpi-detail-dialog__close:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
  }
  .kpi-detail-dialog__title {
    font-size: 15px;
    font-weight: 700;
    color: var(--color-text-primary);
    text-align: center;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .kpi-detail-dialog__counter {
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-muted);
    font-family: var(--font-mono);
    padding-right: var(--space-1);
    min-width: 40px;
    text-align: right;
  }

  /* Inline filter chip row (in-dialog) — sits below the title so the
     operator can switch period or canal without bouncing back. Reuses
     `mobile-filter-chip` styling at a slightly smaller scale. */
  .kpi-detail-dialog__filters {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: 0 var(--space-3) var(--space-2);
  }
  .mobile-filter-chip--compact {
    min-height: 36px;
    padding: 0 var(--space-2);
    font-size: 11px;
    letter-spacing: 0.02em;
    flex: 1 1 50%;
    min-width: 0;
  }

  /* Horizontal scroll-snap rail */
  .kpi-detail-dialog__rail {
    flex: 1 1 auto;
    display: flex;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    -webkit-overflow-scrolling: touch;
    /* Hide horizontal scrollbar for clean look */
    scrollbar-width: none;
    overscroll-behavior-x: contain;
  }
  .kpi-detail-dialog__rail::-webkit-scrollbar { display: none; }

  .kpi-detail-page {
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    scroll-snap-align: start;
    scroll-snap-stop: always;
  }
  .kpi-detail-page__inner {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-3) calc(var(--space-7) + env(safe-area-inset-bottom, 0px));
  }

  /* Hero (icon + value + delta) */
  .kpi-detail-page__hero {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-4) var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    box-shadow: var(--shadow-xs);
    align-items: flex-start;
  }
  .kpi-detail-page__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    background: var(--color-accent-soft);
  }
  .kpi-detail-page__value {
    font-size: 36px;
    font-weight: 700;
    font-family: var(--font-mono);
    line-height: 1;
    letter-spacing: -0.025em;
    color: var(--color-text-primary);
    margin: 0;
    word-break: break-word;
  }
  .kpi-detail-page__value--text { font-size: 24px; }
  .kpi-detail-page__sub {
    font-size: 13px;
    color: var(--color-text-secondary);
    margin: -4px 0 0;
    line-height: 1.4;
  }
  .kpi-detail-page__delta {
    font-size: 13px;
    font-weight: 700;
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
  }
  .kpi-detail-page__delta-vs {
    font-weight: 500;
    color: var(--color-text-muted);
    font-size: 12px;
  }

  /* Generic compare row (N-1, etc.) */
  .kpi-detail-page__row {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    display: grid;
    grid-template-columns: 80px 1fr auto;
    gap: var(--space-2);
    align-items: center;
  }
  .kpi-detail-page__row-label {
    font-size: 11px;
    font-weight: 700;
    color: var(--color-text-secondary);
    letter-spacing: 0.04em;
    text-transform: uppercase;
  }
  .kpi-detail-page__row-value {
    font-size: 16px;
    font-weight: 700;
    color: var(--color-text-primary);
    font-family: var(--font-mono);
  }
  .kpi-detail-page__row-meta {
    font-size: 13px;
    font-weight: 700;
  }

  /* Target progress card */
  .kpi-detail-page__target {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
  }
  .kpi-detail-page__target-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
  }
  .kpi-detail-page__progress {
    width: 100%;
    height: 8px;
    border-radius: 4px;
    background: var(--color-bg);
    overflow: hidden;
  }
  .kpi-detail-page__progress-fill {
    height: 100%;
    border-radius: 4px;
    transition: width var(--duration-slow) var(--ease-out-expo);
  }
  .kpi-detail-page__progress-label {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 0;
    font-weight: 600;
  }

  /* Per-marketplace breakdown list */
  .kpi-detail-page__list {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
  }
  .kpi-detail-page__list-title {
    font-size: 11px;
    font-weight: 700;
    color: var(--color-text-secondary);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    margin: 0 0 var(--space-2);
  }
  .kpi-detail-page__list-ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
  }
  .kpi-detail-page__list-item {
    display: grid;
    grid-template-columns: 12px 1fr auto;
    gap: var(--space-2);
    align-items: center;
    font-size: 13px;
    padding: 6px 0;
    border-bottom: 1px solid var(--color-border);
  }
  .kpi-detail-page__list-item:last-child { border-bottom: 0; }
  .kpi-detail-page__list-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex-shrink: 0;
  }
  .kpi-detail-page__list-label {
    color: var(--color-text-primary);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .kpi-detail-page__list-value {
    color: var(--color-text-primary);
    font-family: var(--font-mono);
    font-weight: 700;
  }
  /* Stacked list item — used by Top SKU per MKP where each row has
     two lines of label (marketplace + SKU). The grid keeps the
     leading dot tight against the column gap. */
  .kpi-detail-page__list-item--stacked {
    grid-template-columns: 12px 1fr auto;
    align-items: center;
  }
  .kpi-detail-page__list-stack {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
  }
  .kpi-detail-page__list-sub {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--color-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .kpi-detail-page__list-foot {
    margin: var(--space-2) 0 0;
    padding-top: var(--space-2);
    border-top: 1px solid var(--color-border);
    font-size: 11px;
    color: var(--color-text-muted);
    font-weight: 500;
  }

  /* Bottom dot navigation */
  .kpi-detail-dialog__dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3) calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    flex-shrink: 0;
  }
  .kpi-detail-dialog__dot {
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    cursor: pointer;
    /* The dot itself is drawn as a pseudo-element so the outer 32px is a
       generous touch target without making a giant visible disc */
    position: relative;
  }
  .kpi-detail-dialog__dot::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-border-strong);
    transition: width var(--duration-fast) var(--ease-default),
                background var(--duration-fast) var(--ease-default);
  }
  .kpi-detail-dialog__dot--active::before {
    width: 24px;
    border-radius: 4px;
    background: var(--color-accent);
  }
  .kpi-detail-dialog__dot:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
  }
}

@keyframes kpi-detail-rise {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .kpi-detail-dialog[open] { animation: none; }
}

@keyframes mobile-sheet-rise {
  from { transform: translateY(100%); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
@keyframes mobile-sheet-backdrop-in {
  from { background: rgba(26, 18, 8, 0); }
  to   { background: rgba(26, 18, 8, 0.45); }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-sheet[open] { animation: none; }
  .mobile-sheet::backdrop { animation: none; }
}

