/*
 * Project Outpost — viewport workspace contract.
 *
 * Desktop owns one viewport-sized shell. Topbar, navigation and the Quick Bar
 * stay stable while each active workspace receives the remaining block size.
 * Long records scroll inside their content track; board-like workspaces can
 * consume the same track without creating a second page-sized canvas.
 */

@media (min-width: 821px) {
  html {
    height: 100%;
    overflow: hidden;
  }

  body.outpost-real-page-preview {
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }

  body.outpost-real-page-preview:not(.character-onboarding) .app,
  body.outpost-real-page-preview:not(.character-onboarding).profile-mode .app {
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) .app > main,
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding).profile-mode .app > main {
    align-self: stretch;
    height: 100%;
    min-height: 0;
    overflow: hidden;
  }

  /* Routine destinations already have a persistent topbar and primary nav.
   * Their page heading is therefore a compact orientation rail, not a second
   * hero. Character Creation and the Director Console keep their dedicated
   * explanatory compositions. */
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-header {
    align-items: center;
    min-height: 54px;
    padding: 0 0 9px;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-heading {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-rows: auto;
    align-items: baseline;
    gap: 0 13px;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-header :is(h1, h2) {
    overflow: hidden;
    margin: 0;
    font-size: clamp(23px, 2vw, 30px);
    line-height: 1.05;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-description {
    display: none;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-header-aside {
    align-self: center;
  }

  /* The Battle hand is intentionally an overlay, like a physical hand of
   * cards. Reserving its full height made the board collapse on laptop-sized
   * viewports. Battle therefore reserves the fixed Quick Bar only; ordinary
   * workspaces continue to use the full measured safe-area contract. */
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding):has(
    #encounter.workspace-view.active .encounter-workspace[data-encounter-workspace-kind="battle"]
  ) .app > main {
    padding-bottom: var(--op-quick-bar-block-size);
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) .app > main > .workspace-view,
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) .app > main > .workspace-view.active {
    height: 100% !important;
    min-height: 0 !important;
    max-height: 100% !important;
    overflow: auto !important;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
  }

  /* Character Profile and Management predate the `.workspace-view` marker.
   * Treat their stable ids as first-class workspace roots instead of forcing
   * renderer-specific classes into the shared shell. */
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) .app > main > :is(#profile, #character).active {
    height: 100% !important;
    min-height: 0 !important;
    max-height: 100% !important;
    overflow: auto !important;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
  }

  /* Shared player pages all render the same three structural regions:
   * page heading, context navigation, and the live content track. */
  body.outpost-real-page-preview:not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ).active > :is(
    .op-character-page,
    .party-workspace,
    .inventory-layout-player,
    .skillbook-layout-player,
    .dice-workspace,
    .encounter-workspace,
    .options-workspace
  ) {
    display: grid !important;
    grid-template-rows: auto auto minmax(0, 1fr);
    align-content: stretch;
    width: 100%;
    height: 100%;
    min-height: 0;
    max-height: 100%;
    padding-bottom: 0;
    overflow: hidden;
  }

  body.outpost-real-page-preview:not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ).active > :is(
    .op-character-page,
    .party-workspace,
    .inventory-layout-player,
    .skillbook-layout-player,
    .dice-workspace,
    .encounter-workspace,
    .options-workspace
  ) > :last-child {
    min-height: 0;
    max-height: 100%;
    overflow: auto;
    overscroll-behavior: contain;
    scrollbar-gutter: stable;
  }

  /* These established content regions are the only scroll owners on their
   * page. Their columns may still scroll independently where already designed. */
  body.outpost-real-page-preview :is(
    .op-character-profile-layout,
    .op-character-manage-layout,
    .party-layout,
    .inventory-content-grid,
    .skill-overview-workspace,
    .progression-dashboard,
    .dice-layout-v3,
    .encounter-live-content,
    .options-layout
  ) {
    min-height: 0;
  }

  /* Battle is a true fit workspace. All other Encounter types keep the
   * general content-track scroll contract because their records may be long. */
  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .encounter-live-content,
  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .encounter-live-content > .panel,
  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .player-battle-experience {
    height: 100%;
    min-height: 0;
    overflow: hidden;
  }

  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .player-battle-experience {
    grid-template-rows: auto minmax(0, 1fr);
  }

  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .encounter-battle-frame {
    display: grid;
    grid-template-rows: minmax(0, 1fr) auto;
    height: 100%;
    min-height: 0;
    overflow: hidden;
  }

  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .battle-shell {
    height: 100%;
    min-height: 0;
    max-height: none;
  }

  /* The shared Phaser surface normally derives height from its aspect ratio
   * for unbounded embeds. Player Battle is bounded here, just like DM Battle,
   * so its map and viewport consume the assigned track instead. */
  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .battle-surface[data-battle-renderer="phaser"] .battle-map-panel,
  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="battle"] .battle-surface[data-battle-renderer="phaser"] .battle-board-viewport {
    height: 100%;
    min-height: 0;
    aspect-ratio: auto;
  }

  body.outpost-real-page-preview #encounter .encounter-workspace[data-encounter-workspace-kind="camp"] .encounter-live-content {
    min-height: 0;
  }

  /* Inventory owns three independent fit regions. The item list and dossier
   * scroll locally, so selecting a detailed item never pushes its primary
   * command below the Quick Bar. */
  body.outpost-real-page-preview #inventory .inventory-canvas {
    padding: var(--op-context-content-gap) 0 0;
    overflow: hidden !important;
  }

  body.outpost-real-page-preview #inventory .inventory-content-grid {
    height: 100%;
    min-height: 0 !important;
    max-height: 100%;
    overflow: hidden !important;
  }

  body.outpost-real-page-preview #inventory :is(
    .inventory-filter-rail,
    .inventory-main,
    .inventory-detail-panel
  ) {
    height: 100%;
    min-height: 0 !important;
    max-height: 100%;
    overflow: auto !important;
    overscroll-behavior: contain;
  }

  body.outpost-real-page-preview #inventory .unified-inventory-panel {
    height: auto;
    min-height: 0;
  }

  body.outpost-real-page-preview #inventory .inventory-detail-panel > * {
    order: 4;
  }

  body.outpost-real-page-preview #inventory .inventory-detail-kicker {
    order: 1;
    min-height: 38px;
  }

  body.outpost-real-page-preview #inventory .inventory-detail-hero {
    order: 2;
    grid-template-columns: 72px minmax(0, 1fr);
    min-height: 100px;
    padding: 13px 0;
  }

  body.outpost-real-page-preview #inventory .inventory-detail-hero .selected-item-art {
    width: 72px;
    height: 72px;
    min-height: 72px;
  }

  body.outpost-real-page-preview #inventory .selected-item-action-bar {
    position: sticky;
    top: 0;
    z-index: 5;
    order: 3;
    margin: 0;
    padding: 9px 0;
    border-bottom: 1px solid var(--op-line);
    background: var(--op-surface-soft);
  }

  body.outpost-real-page-preview #inventory .inventory-primary-action {
    min-height: 40px !important;
    border-radius: 0;
    transform: none !important;
  }

  body.outpost-real-page-preview #inventory .inventory-primary-action::before {
    display: none;
  }

  /* Easy and high-legibility modes own taller command planes. The shell uses
   * the same token rather than letting those variants cover page content. */
  body.outpost-real-page-preview[data-ui-mode="easy"] {
    --op-quick-bar-block-size: 148px;
  }

  body.outpost-real-page-preview[data-text-size="huge"]:not([data-ui-mode="easy"]) {
    --op-quick-bar-block-size: 118px;
  }

  body.outpost-real-page-preview[data-text-size="huge"]:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-header {
    min-height: 64px;
  }

  body.outpost-real-page-preview[data-text-size="huge"]:not(.dm-workspace-mode):not(.character-onboarding) :is(
    #profile,
    #character,
    #party,
    #inventory,
    #skillbook,
    #dice,
    #encounter,
    #options
  ) .op-page-header :is(h1, h2) {
    font-size: clamp(28px, 2.4vw, 35px);
  }
}

/* Height-aware compact rhythm preserves readable controls while recovering
 * vertical space on 16:9 laptops and 4:3 displays. */
@media (min-width: 821px) and (max-height: 820px) {
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) {
    --op-page-header-min-height: 82px;
    --op-page-header-padding: 0 0 13px;
    --op-page-header-title-size: clamp(28px, 2.7vw, 38px);
    --op-context-tab-height: 40px;
    --op-context-tab-control-height: 38px;
    --op-context-content-gap: 14px;
    --op-workspace-layout-gap: var(--op-context-content-gap);
    --op-workspace-region-padding: 18px;
    --op-workspace-region-padding-compact: 13px;
    --op-page-bottom-breathing-room: 12px;
  }

  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding) .app > main,
  body.outpost-real-page-preview:not(.dm-workspace-mode):not(.character-onboarding).profile-mode .app > main {
    padding-top: 18px;
  }

  body.outpost-real-page-preview .op-character-manage-layout {
    margin-top: var(--op-context-content-gap);
  }

  body.outpost-real-page-preview :is(.op-character-manage-nav, .op-character-manage-stage, .op-character-manage-review) {
    padding-block: 16px;
  }
}

/* Character Creation and mobile retain a document-flow surface. Their forms
 * may be longer than one screen and must never be clipped by the shell. */
body.outpost-real-page-preview.character-onboarding {
  min-height: 100dvh;
  overflow-y: auto;
}

@media (max-width: 820px) {
  html,
  body.outpost-real-page-preview {
    height: auto;
    min-height: 100%;
    overflow: visible;
  }
}
