/*
  TRAP-53 (P1) — responsive layer for the shared foundation layouts (EntityListLayout/
  EntityDetailLayout/EntityFormLayout) and building blocks (FilterBar/PageHero/Breadcrumbs) plus
  MudBlazor dialogs. These ship no CSS isolation and no responsive handling of their own
  (Starruk.Platform.Blazor.Components v1.4.6 / .DesignSystem v1.4.4 source read directly — see
  acceptance/TRAP-49/runbook.md Voortgang) — per CLAUDE.md "Foundation via NuGet, niet forken"
  this file is the local override seam instead of a foundation fork. Selectors target the
  foundation's s-* class contract plus MudBlazor's own utility/table/dialog classes (verified
  against the installed MudBlazor.min.css 9.4.0), never foundation-internal implementation detail
  that isn't part of either contract.
*/

@media (max-width: 599.98px) {
    /* EntityListLayout's toolbar row (SearchContent/FilterBar + spacer + PrimaryAction) is a
       <MudStack Row AlignItems="Center" Spacing="3" Class="mt-4 mb-4">. MudStack has no CSS-class
       rule of its own (MudBlazor.min.css defines zero mud-stack* selectors) — Row/AlignItems
       render as the utility classes below, and MudBlazor ships those utilities !important
       (.flex-row{flex-direction:row!important}, .align-center{align-items:center!important}),
       so beating them here also needs !important; this selector's 5-class specificity still wins
       over their single-class rules. AC-1: search + primary action each get their own full-width
       row instead of being squeezed onto one line. */
    .d-flex.flex-row.align-center.gap-3.mt-4.mb-4 {
        flex-direction: column !important;
        align-items: stretch !important;
    }

    /* FilterBar's search field (.s-filter-grow) already wraps onto its own line once the bar runs
       out of room (.s-filter-bar has flex-wrap:wrap), but AC-1 wants it deterministically
       full-width rather than merely "happens to be alone on a line". */
    .s-filter-bar .s-filter-grow {
        flex-basis: 100%;
        min-width: 0;
    }

    /* EntityDetailLayout's title+actions header (<div class="d-flex align-center
       justify-space-between">) and the same hand-authored toolbar idiom on a few detail pages
       (e.g. CustomerDetail's Properties-tab search+add row) — allow wrapping instead of
       overflowing. AC-2 allows "gestapeld OF overflow-menu"; buttons keep their natural width
       and simply wrap onto their own line rather than being forced full-width. */
    .d-flex.align-center.justify-space-between {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .d-flex.align-center.justify-space-between > h1 {
        min-width: 0;
        overflow-wrap: break-word;
    }

    /* The Actions slot renders as a nested <MudStack Row Spacing="2"> (d-flex flex-row gap-2, no
       Class param) — scope to a direct child of the header row above so this doesn't reach into
       unrelated stacks elsewhere on the page. */
    .d-flex.align-center.justify-space-between > .d-flex.flex-row.gap-2 {
        flex-wrap: wrap;
    }

    /* PageHero: starruk-components.css already ships a compact-padding modifier (.s-page-hero-sm)
       that PageHero.razor never applies (no Class passthrough on that component) — reproduce its
       effect via a plain media query instead of forking the component to add the class. */
    .s-page-hero {
        padding: 18px 20px 20px;
    }

    .s-page-hero-title {
        font-size: 1.3rem;
    }

    /* Breadcrumbs: never hide an ancestor level (everything must stay navigable per the shared
       breadcrumb convention) — scroll the crumb row itself instead of letting a long trail push
       the whole page into horizontal overflow. */
    .mud-breadcrumbs {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    .mud-breadcrumbs li {
        white-space: nowrap;
    }

    /* MudDialogProvider carries no global DialogOptions and ConfirmDialog sets none of its own
       (ShowAsync callers don't pass a per-instance FullScreen either) — full-screen-below-sm has
       to be a CSS-only override. .mud-dialog is already display:flex;flex-direction:column with
       .mud-dialog-title/-content/-actions at flex 0-0-auto / 1-1-auto / 0-0-auto (a pinned-header,
       scrolling-body, pinned-footer layout already built into MudBlazor's base CSS) — only the
       outer box needs to fill the viewport for AC-3's "acties bereikbaar" to fall out for free. */
    .mud-dialog-container .mud-dialog {
        position: fixed !important;
        inset: 0 !important;
        width: 100% !important;
        height: 100% !important;
        max-width: 100% !important;
        max-height: none !important;
        margin: 0 !important;
        border-radius: 0 !important;
        /* TRAP-52: full-screen now means genuinely edge-to-edge, so the notch/home-indicator
           safe area has to be paid for explicitly instead of falling out of normal box flow. */
        padding-top: env(safe-area-inset-top);
        padding-bottom: env(safe-area-inset-bottom);
    }

    /* Breadcrumbs (continued): truncate an individual long crumb label with an ellipsis rather
       than letting it dominate the scrollable row — AC-2's "ellipsis" clause. Every crumb stays
       present and tappable (nothing is removed from the DOM), satisfying "blijven navigeerbaar
       naar elk voorouder-niveau" — this narrows a label's display width, it doesn't hide a level. */
    .mud-breadcrumbs li a,
    .mud-breadcrumbs li p {
        display: inline-block;
        max-width: 120px;
        overflow: hidden;
        text-overflow: ellipsis;
        vertical-align: bottom;
    }
}

/*
  TRAP-52 (P2) — app-shell mobile-first: drawer default-state + auto-close (MainLayout.razor
  companion, see drawer-prepaint.js + the _isMobileViewport wiring), touch targets, safe-area-
  insets. Unlike the P1 block above, most of this is NOT media-queried — see each rule for why.
*/

/* AC-1: suppresses the flash of the server-rendered default-open drawer on a fresh mobile visit,
   until MainLayout's own OnAfterRenderAsync (drawer-prepaint.js's isMobile() check) sets
   _drawerOpen=false and re-renders with the real .mud-drawer--closed class. Only ever engages when
   drawer-prepaint.js already determined innerWidth < 960 — no separate breakpoint needed here.
   Same off-screen mechanism MudBlazor's own .mud-drawer--closed rule uses (verified in the
   compiled CSS), not a guess. */
html[data-drawer-hint="closed"] .mud-drawer--open {
    left: calc(-1 * var(--mud-drawer-width, var(--mud-drawer-width-left))) !important;
}

html[data-drawer-hint="closed"] .mud-drawer-overlay {
    display: none !important;
}

/* AC-2: appbar icon buttons (nav-toggle, alerts bell) and drawer nav links default to ~36px in
   MudBlazor (padding 4-6px + a 24px icon) — under the 44px touch-target floor. Scoped to the
   appbar/drawer rather than every .mud-icon-button app-wide (e.g. dense table row actions
   elsewhere are deliberately compact). Applies at every width — a taller nav link or a slightly
   more generous appbar button isn't a desktop regression. */
.mud-appbar .mud-icon-button {
    min-width: 44px;
    min-height: 44px;
}

.mud-drawer .mud-nav-link {
    min-height: 44px;
}

/* AC-2 (continued): the user-menu trigger (MudAvatar, Size.Small = 32px) isn't a .mud-icon-button
   so the rule above misses it; its display name is d-none below sm, leaving just the 32px avatar
   as the visible tap target. Grow the clickable wrapper to the 44px floor via padding rather than
   resizing the avatar itself (keeps the visual mark unchanged, per WCAG's "target can be smaller
   than the touch area" allowance) — safe unconditionally, same reasoning as the icon-button rule. */
.mud-appbar .mud-menu .d-flex.flex-row.align-center.gap-0 {
    min-width: 44px;
    min-height: 44px;
    justify-content: center;
}

/* AC-2 (continued): found via staging Playwright verification (390x844) — Dashboard specifically
   (not other pages) showed 19px of real horizontal scroll on the shell. Root cause, isolated by
   bisecting the page section by section: the 5-card KPI MudGrid (Spacing=6, default) carries
   MudBlazor's standard gutter-compensation `margin-left:-24px` on the grid with matching
   `padding-left:24px` on each item — normally an invisible wash, but on this viewport it's enough
   to trip Chromium's mobile-layout-viewport-expansion heuristic (content that would otherwise be
   clipped left-of-origin widens the whole layout viewport instead), which is why the *appbar*
   (window.innerWidth-driven, `position:fixed`) measured wide even though the grid's own box never
   crosses the right edge (confirmed: hiding just the KPI grid restored scrollWidth to 390, nothing
   else on the page mattered). Any current or future MudGrid elsewhere in the app can trigger the
   same mechanism, so the fix belongs on the document's scroll root, not the one grid instance —
   MudBlazor's negative-margin gutter technique is only ever safe when a `overflow-x:hidden`
   ancestor backstops it, which nothing in the foundation or this app provided before now. */
html, body {
    overflow-x: hidden;
}

/* Safe-area-insets (notch / home-indicator): env() resolves to 0 on non-notched devices/desktop
   browsers, so these are harmless no-ops there — no media query needed. Requires
   viewport-fit=cover on the <meta name="viewport"> tag (App.razor) or env() always returns 0. */
.mud-appbar {
    padding-top: env(safe-area-inset-top);
}

.mud-drawer-header {
    padding-top: calc(12px + env(safe-area-inset-top));
}

/*
  TRAP-54 (P4) — full mobile sweep (390px + 320px) across every routed page. Most of the app was
  already clean (P1's shared-layout fixes + P2's shell fixes cover the vast majority of the ~35
  entity pages by construction); this block is the small residue of page-specific touch-target
  gaps the sweep actually found. Dense per-row icon-buttons in data-dense tables/streams (e.g.
  /ttn-events, list-page row actions) are a deliberate, pre-existing exception (documented on the
  AC-2 .mud-appbar .mud-icon-button rule above) and are intentionally NOT touched here — this
  block only covers prominent, non-dense interactive elements.
*/

/* Found via the route sweep: the trial/blocked-tenant banner (MainLayout.razor, MudAlert) renders
   its billing CTA at Size.Small (31px) — appears on every authenticated page while a tenant is on
   trial or blocked, so unlike a table row action this is a persistent, prominent, business-critical
   CTA (the upgrade-to-paid path) a thumb needs to land on reliably. Scoped via a dedicated class on
   the two MainLayout buttons rather than every Size.Small button app-wide, which would reach into
   the already-decided dense-action exception above. */
.tw-banner-cta {
    min-height: 44px;
}

/* TRAP-56/AC-5: suspicious-connection banner (MainLayout.razor) — gold-accent (huisstijl waarschuwing)
   instead of MudBlazor's stock warning amber, reusing the foundation's own tint/border recipe
   (Starruk.Platform.Blazor.DesignSystem's .s-filter-notice) rather than inventing new hex values. */
.tw-risk-banner {
    background: var(--s-tint-warning) !important;
    border: 1px solid color-mix(in srgb, var(--s-tertiary) 30%, transparent);
}

/* Dismiss control is icon-only/square, so — unlike .tw-banner-cta above, which only needed
   min-height for its existing text buttons — both dimensions need the 44px touch-target floor. */
.tw-risk-banner-dismiss {
    min-width: 44px;
    min-height: 44px;
}

/* Found via the route sweep: MudButton's Size="Size.Large" (MudBlazor's own convention for a
   page's primary/hero action, e.g. Dashboard's "Install trap" CTA) renders at 42px — 2px under the
   floor in this MudBlazor version's default theme, regardless of variant (filled/outlined/text all
   compose the size suffix the same way, verified against the installed MudBlazor.min.css 9.4.0:
   .mud-button-{variant}-size-large). A Large button is never used for a dense/compact context by
   MudBlazor's own convention, so this is safe to apply unconditionally app-wide. */
[class*="-size-large"] {
    min-height: 44px;
}

/* Found via the same sweep, across all three onboarding-family wizards (/devices/onboard,
   /devices/onboard/bulk, /devices/commissioning): every step's Back/Cancel + Next/Save action
   pair renders as a plain flex row (a raw `d-flex gap-2` div, or a `MudStack Row Spacing`) with no
   `.flex-row` class, so it falls outside the P1 wrap rule above (written for EntityDetailLayout's
   `d-flex flex-row gap-2` action rows) — the two buttons stay side by side at roughly half width
   each instead of the full-width, thumb-reachable steps AC-2 asks for. Marker classes rather than
   a broader utility-class match, same reasoning as .tw-banner-cta above: a bare `d-flex gap-2` or
   `MudStack Row` is used all over the app for contexts that should stay compact. */
/* Found via staging re-verification of the fix above: these Back/Next buttons carry no explicit
   Size, so they render at MudBlazor's default-size height (37px) — under the floor regardless of
   the width fix. Wizard step-navigation is never a dense/compact context at any viewport (it's the
   primary way through a multi-step form), so — like the Size.Large rule above — this applies
   unconditionally rather than mobile-only; unlike the width stacking below, stretching button
   *height* on desktop isn't a visual regression. */
.tw-wizard-actions-group .mud-button-root {
    min-height: 44px;
}

@media (max-width: 640px) {
    .tw-wizard-actions {
        flex-wrap: wrap;
        row-gap: 8px;
    }

    .tw-wizard-actions-group {
        flex-wrap: wrap;
        width: 100%;
    }

    .tw-wizard-actions-group .mud-button-root {
        flex: 1 1 auto;
    }
}

#components-reconnect-modal {
    padding-top: calc(1rem + env(safe-area-inset-top));
    padding-bottom: calc(1rem + env(safe-area-inset-bottom));
}
