/* ============================================================================
 * config.display — the device-class adaptation stylesheet (plan
 * `viz_display_config_coverage`, rrp:pl:p1gtm0gf4).
 *
 * The data-attribute contract set by BOTH runtimes (the Leptos detail page /
 * overview grid / design page via `viz::display::display_attributes`, the
 * React hosts via `applyDisplayResolution`):
 *   [data-rr-display-class]  desktop|laptop|tablet|phone|handheld_console|ereader
 *   [data-rr-rail-mode]      rails|drawers|stacked
 *   [data-rr-gap]            compact|comfortable|spacious
 *   [data-rr-padding]        compact|comfortable|spacious
 *   [data-rr-density]        compact|comfortable
 *   [data-rr-palette]        slate|ocean|violet|grayscale
 *   [data-rr-animations]     on|reduced|off
 *   [data-rr-chart-style]    full|compact
 * plus the CSS custom properties --rr-accent-hue / --rr-accent-saturation /
 * --rr-touch-target-scale / --rr-min-hit-target-px.
 *
 * This is the ONLY place phone/e-reader geometry rules live — no per-page CSS
 * forks (every adaptation flows through the centralized config.display
 * resolution; the /viz/design page remains the human tuning surface for the
 * VALUES, this file renders them). Selectors target the REAL DOM: the viz
 * pages' literal utility class names (`.container`, `.flex.gap-2` — plain
 * class attributes, selectable regardless of the missing Tailwind pipeline)
 * and the chat-window family's `rr-chat-*` classes.
 * ========================================================================== */

/* ── Rhythm tokens: the gap/padding values rebind the page rhythm ────────── */
[data-rr-display-class] {
    --rr-display-gap: 1rem;
    --rr-display-padding: 1rem;
}
[data-rr-display-class][data-rr-gap="compact"]     { --rr-display-gap: 0.5rem; }
[data-rr-display-class][data-rr-gap="spacious"]    { --rr-display-gap: 1.5rem; }
[data-rr-display-class][data-rr-padding="compact"] { --rr-display-padding: 0.5rem; }
[data-rr-display-class][data-rr-padding="spacious"]{ --rr-display-padding: 1.5rem; }

/* Phone-class pages: drop the desktop gutters so a 360px rail never gets
 * horizontal overflow from padding alone. */
[data-rr-display-class="phone"] .container,
[data-rr-display-class="handheld_console"] .container,
[data-rr-display-class="ereader"] .container {
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    max-width: 100%;
}
[data-rr-display-class="phone"] .container {
    padding-left: 0.375rem;
    padding-right: 0.375rem;
}

/* Long titles wrap instead of overflowing. */
[data-rr-display-class] h1 {
    overflow-wrap: break-word;
}
[data-rr-display-class="phone"] h1,
[data-rr-display-class="handheld_console"] h1,
[data-rr-display-class="ereader"] h1 {
    font-size: 1.75rem;
    line-height: 1.2;
}

/* Tag rows collapse to a scrollable single line on phone-class instead of
 * pushing the preview below the fold. */
[data-rr-display-class="phone"] .flex.gap-2,
[data-rr-display-class="handheld_console"] .flex.gap-2,
[data-rr-display-class="ereader"] .flex.gap-2 {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: thin;
}

/* ── Rail mode: rails → drawers → stacked ─────────────────────────────────
 * The chat-messenger two-pane surface is the canonical rail-mode consumer:
 * `stacked` forces the single-column arrangement (the list pane becomes a
 * compact strip; the divider — a col-resize drag — is meaningless in a
 * column and hides). */
[data-rr-rail-mode="stacked"] .rr-chat-messenger {
    flex-direction: column !important;
    max-height: none;
}
[data-rr-rail-mode="stacked"] .rr-chat-messenger .rr-chat-list-pane {
    width: 100% !important;
    max-width: 100% !important;
    max-height: 34vh;
    overflow-y: auto;
    border-right: none !important;
    border-bottom: 1px solid var(--rr-chat-border, #cbd5e1);
}
[data-rr-rail-mode="stacked"] .rr-chat-messenger .rr-chat-convo-list {
    width: 100% !important;
    border-right: none !important;
    border-bottom: 1px solid var(--rr-chat-border, #cbd5e1);
}
[data-rr-rail-mode="stacked"] .rr-chat-pane-divider {
    display: none !important;
}

/* Drawers mode: rails collapse into overlays; the list pane detaches and
 * overlays the thread (the surface keeps its pane affordances). */
[data-rr-rail-mode="drawers"] .rr-chat-messenger .rr-chat-list-pane {
    position: absolute;
    inset: 0 auto 0 0;
    z-index: 5;
    background: var(--rr-chat-surface, #ffffff);
    box-shadow: 0 0 0 1px var(--rr-chat-border, #cbd5e1);
}

/* ── Touch targets: every interactive affordance meets --rr-min-hit-target ─ */
[data-rr-display-class="tablet"] button,
[data-rr-display-class="tablet"] [role="button"],
[data-rr-display-class="phone"] button,
[data-rr-display-class="phone"] [role="button"],
[data-rr-display-class="handheld_console"] button,
[data-rr-display-class="handheld_console"] [role="button"],
[data-rr-display-class="ereader"] button,
[data-rr-display-class="ereader"] [role="button"] {
    min-height: var(--rr-min-hit-target-px, 44px);
    min-width: var(--rr-min-hit-target-px, 44px);
}

/* Compact icon-only controls (IIIF viewer buttons, geo controls) scale by the
 * resolution's touch-target factor. */
[data-rr-display-class="tablet"] .rr-icon-button,
[data-rr-display-class="phone"] .rr-icon-button,
[data-rr-display-class="handheld_console"] .rr-icon-button,
[data-rr-display-class="ereader"] .rr-icon-button {
    padding: calc(0.375rem * var(--rr-touch-target-scale, 1));
}

/* ── Animation policy ────────────────────────────────────────────────────── */
[data-rr-animations="off"] *,
[data-rr-animations="off"] *::before,
[data-rr-animations="off"] *::after {
    animation: none !important;
    transition: none !important;
    scroll-behavior: auto !important;
}
[data-rr-animations="reduced"] *,
[data-rr-animations="reduced"] *::before,
[data-rr-animations="reduced"] *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
}

/* ── E-ink palette: grayscale rendering for monochrome displays ──────────── */
[data-rr-palette="grayscale"],
[data-rr-palette="grayscale"] img,
[data-rr-palette="grayscale"] svg,
[data-rr-palette="grayscale"] canvas,
[data-rr-palette="grayscale"] video {
    filter: grayscale(1);
}

/* ── Chart compression: legends/margins tighten under compact style ──────── */
[data-rr-chart-style="compact"] .chart-shell { padding: 0.25rem; }
[data-rr-chart-style="compact"] .legend {
    font-size: 0.65rem;
    gap: 0.25rem;
}
[data-rr-chart-style="compact"] .legend span { padding: 0.1rem 0.4rem; }
[data-rr-chart-style="compact"] svg { border-radius: 0.5rem; }

/* Charts never force horizontal overflow: the SVG is fluid, the configured
 * width is a preferred size (holds for every device class). The flex-item
 * `min-width: auto` MUST also be cleared — a flex child's content-based
 * minimum OVERRIDES `max-width` (the census's sunburst/zoomable family
 * stayed 928px wide inside a 378px wrapper until this landed). */
[data-rr-display-class] svg[width] {
    max-width: 100%;
    height: auto;
}
[data-rr-display-class] .visualization-svg-wrapper,
[data-rr-display-class] .visualization-svg-wrapper > svg {
    min-width: 0;
    max-width: 100%;
}

/* Data tables (the census's widest offender, +853px): a real <table>
 * overflows by nature — it SCROLLS inside its frame instead of blowing the
 * page rail. */
[data-rr-display-class] .visualization-container,
[data-rr-display-class] .frame {
    overflow-x: auto;
}

/* Fixed-px frame elements that exceed the viewport (the 928px chart frames,
 * IIIF sidebars) become fluid below tablet. */
[data-rr-display-class="phone"] .visualization-container,
[data-rr-display-class="phone"] .frame,
[data-rr-display-class="handheld_console"] .visualization-container,
[data-rr-display-class="handheld_console"] .frame,
[data-rr-display-class="ereader"] .visualization-container,
[data-rr-display-class="ereader"] .frame {
    width: 100% !important;
    max-width: 100% !important;
}

/* ── The dev-config panel on handheld: the desktop-first drawer narrows ──── */
[data-rr-display-class="phone"] .dev-config-panel,
[data-rr-display-class="handheld_console"] .dev-config-panel,
[data-rr-display-class="ereader"] .dev-config-panel {
    width: 100%;
    max-width: 100%;
}
[data-rr-display-class="phone"] .dev-config-panel .nav-item,
[data-rr-display-class="handheld_console"] .dev-config-panel .nav-item,
[data-rr-display-class="ereader"] .dev-config-panel .nav-item {
    font-size: 0.8rem;
}

/* ── Density: compact panel rhythm inside rails ──────────────────────────── */
[data-rr-density="compact"] .dev-config-panel .nav-children .nav-item,
[data-rr-density="compact"] .dev-config-panel .control-row {
    padding-top: 0.25rem;
    padding-bottom: 0.25rem;
}

/* ── The flex min-width:auto blowout (the census's root geometry finding):
 * the app shell's main column is a flex item that cannot shrink below its
 * widest descendant (928px chart frames, the build banner) — the column
 * grows, the document scrollWidth follows, and every narrow viewport gets
 * +542..853px of clipped/scrollable overflow. `min-width: 0` on the shell's
 * flex items lets the column shrink; the wide descendants themselves are
 * made fluid by the rules above/below. Unscoped by design: it is the
 * standard flexbox fix and changes nothing when content fits. */
.app-layout > * {
    min-width: 0;
}

/* ── The build banner (local dev): a wide informational strip. It lives in
 * the shell chrome ABOVE the display-attr root, so the descendant selector
 * cannot reach it — `body:has(...)` scopes the shell chrome by the page's
 * resolved class (the design-page.css :has() precedent). Viewport-anchored
 * units cut the grown-parent chain. */
body:has([data-rr-display-class="phone"]) .rr-build-banner,
body:has([data-rr-display-class="handheld_console"]) .rr-build-banner,
body:has([data-rr-display-class="ereader"]) .rr-build-banner {
    width: 100vw !important;
    max-width: 100vw !important;
    overflow-x: auto;
    overflow-wrap: anywhere;
}

/* ── Rail-collapsed + tablet classes: flex-row/grid children shrink (the
 * min-width:auto blowout — the datatable chain grew 1162px inside a 390px
 * rail; the tablet-class census showed the same blowout at 820–1072px) and
 * wide data content SCROLLS in its frame instead of blowing the page. */
[data-rr-display-class="phone"] .flex > *,
[data-rr-display-class="phone"] .grid > *,
[data-rr-display-class="tablet"] .flex > *,
[data-rr-display-class="tablet"] .grid > *,
[data-rr-display-class="handheld_console"] .flex > *,
[data-rr-display-class="handheld_console"] .grid > *,
[data-rr-display-class="ereader"] .flex > *,
[data-rr-display-class="ereader"] .grid > * {
    min-width: 0;
}
[data-rr-display-class="phone"] .p-datatable-wrapper,
[data-rr-display-class="phone"] .p-datatable-table-container,
[data-rr-display-class="tablet"] .p-datatable-wrapper,
[data-rr-display-class="handheld_console"] .p-datatable-wrapper,
[data-rr-display-class="ereader"] .p-datatable-wrapper {
    overflow-x: auto;
}

/* The React preview wrappers render as `inline-block` with `min-width: 100%`
 * (the census's datatable chain: the p-datatable's 1162px min-content grew
 * the wrapper past the rail). `max-width: 100%` caps an inline-block; the
 * wide table SCROLLS inside it. */
[data-rr-display-class="phone"] section,
[data-rr-display-class="phone"] .space-y-4,
[data-rr-display-class="tablet"] section,
[data-rr-display-class="tablet"] .space-y-4,
[data-rr-display-class="handheld_console"] section,
[data-rr-display-class="handheld_console"] .space-y-4,
[data-rr-display-class="ereader"] section,
[data-rr-display-class="ereader"] .space-y-4 {
    max-width: 100%;
    overflow-x: auto;
}

/* The overview page's header row (title + the performance trigger) and the
 * core-type toggle group (PrimeReact button row, 555px min-content at
 * 390px): both wrap instead of pushing the document wide. */
[data-rr-display-class="phone"] .items-start.justify-between,
[data-rr-display-class="tablet"] .items-start.justify-between,
[data-rr-display-class="handheld_console"] .items-start.justify-between,
[data-rr-display-class="ereader"] .items-start.justify-between {
    flex-wrap: wrap;
}
[data-rr-display-class="phone"] .p-togglebuttongroup,
[data-rr-display-class="tablet"] .p-togglebuttongroup,
[data-rr-display-class="handheld_console"] .p-togglebuttongroup,
[data-rr-display-class="ereader"] .p-togglebuttongroup {
    flex-wrap: wrap;
    max-width: 100%;
}

/* ── The viz overview grid: phone-class forces the single column regardless
 * of the ResponsiveGrid's inline md/lg span assumptions. ─────────────────── */
[data-rr-display-class="phone"] .rr-viz-overview-grid,
[data-rr-display-class="handheld_console"] .rr-viz-overview-grid,
[data-rr-display-class="ereader"] .rr-viz-overview-grid {
    grid-template-columns: 1fr !important;
}
[data-rr-display-class="phone"] .rr-viz-overview-grid > *,
[data-rr-display-class="handheld_console"] .rr-viz-overview-grid > *,
[data-rr-display-class="ereader"] .rr-viz-overview-grid > * {
    grid-column: 1 / -1 !important;
}
