/*
 * Landscape Mobile Overrides
 *
 * Every rule in this file is wrapped in a single media query that only
 * matches phones held in landscape orientation. Edits here cannot leak
 * into desktop, tablet, or portrait-mobile layouts.
 *
 * Match conditions:
 *   - orientation: landscape   -> wider than tall
 *   - max-height: 500px        -> short viewport (excludes tablets/desktops)
 *
 * NOTE: the `pointer: coarse` (touch-only) gate was removed so that short
 * landscape DESKTOP windows (e.g. a laptop browser at ~830x490) get this same
 * fits-on-screen layout instead of scrollbars — the positioning works the same
 * with a mouse as with touch. It still only triggers under ~500px tall, which
 * normal desktop windows never hit.
 *
 * Loaded LAST in layout.jsx so these rules win the cascade at equal specificity.
 * If an existing rule still wins, prefer raising specificity over !important.
 */

@media (orientation: landscape) and (max-height: 500px) {

  /* ---------------------------------------------------------------------
   * Home hero: banner left, small logo top-right, Play Now buttons under it.
   *
   * The three targets live under different DOM ancestors, so we use
   * `display: contents` to dissolve the intermediate wrappers and make
   * banner / .hero-text / .get-started-section all become direct grid
   * items of .hero-overlay. No JSX changes, no position:fixed.
   * ------------------------------------------------------------------- */

  .hero-overlay {
    display: grid;
    grid-template-columns: minmax(140px, 240px) 1fr 1fr;
    grid-template-areas:
      "banner logo academy"
      "banner play campaign";
    grid-auto-flow: row;
    align-items: start;
    justify-items: stretch;
    gap: 8px 12px;
    padding: 8px 16px;
  }

  /* Dissolve the wrappers so their children become hero-overlay's grid items.
     We also dissolve the get-started section's own wrappers so Play Now,
     Academy and Campaign each become direct grid items. */
  .hero-heading,
  .home-wrap,
  .home-content,
  .menu-sections,
  .menu-section.get-started-section,
  .get-started-section .menu-section-content,
  .get-started-section .menu-grid,
  .get-started-section .menu-button-split {
    display: contents;
  }

  /* Banner: pinned to the left, spans both top rows. */
  .cg-banner-slot.cg-banner-hero,
  .banner-on-home {
    grid-area: banner;
    align-self: stretch;
    justify-self: stretch;
    width: 100%;
    max-width: 100%;
    margin: 0;
  }

  /* Logo block: top-right cell. Centered and stretched so the logo
     fills the empty space above Play Now instead of hugging the corner. */
  .hero-text {
    grid-area: logo;
    align-items: center;
    justify-content: center;
    text-align: center;
    width: 100%;
    align-self: stretch;
    padding: 4px 0;
  }

  .game-logo-img {
    width: 100%;
    max-width: 100%;
    max-height: 100%;
    height: auto;
    object-fit: contain;
  }

  .hero h1 {
    font-size: 1.1rem;
    margin: 0 0 4px;
  }

  .hero-subtitle,
  .hero p {
    display: none;
  }

  /* The Get Started header is hidden — buttons become direct grid items. */
  .get-started-section .section-header {
    display: none;
  }

  /* Play Now: under the logo (column 2, row 2). */
  .get-started-section .play-now-button {
    grid-area: play;
  }

  /* Academy: top-right (column 3, row 1). Campaign: bottom-right (column 3, row 2).
     Targeted by hx-get since the buttons share .split-button. */
  .get-started-section [hx-get="/academy"] {
    grid-area: academy;
  }

  .get-started-section [hx-get="/map/campaign"] {
    grid-area: campaign;
  }

  /* Any remaining menu sections (Explore, etc.) flow into rows below,
     spanning the full width so they don't squeeze into one column. */
  .menu-section:not(.get-started-section) {
    grid-column: 1 / -1;
  }

  /* Tighter buttons so they fit at landscape phone height.
     Split buttons (Academy/Campaign) default to row layout — force column
     so icon stacks over text and nothing gets clipped by the gui-corners frame.
     align-self: stretch makes them fill their grid cell so Academy/Campaign
     match Play Now's height instead of looking short. */
  .get-started-section .menu-button {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    align-self: stretch;
    min-height: 56px;
    height: auto;
    padding: 8px 12px;
    gap: 4px;
  }

  .get-started-section .menu-button > i {
    font-size: 1.15rem;
  }

  .get-started-section .button-title {
    font-size: 0.8rem;
  }

  .get-started-section .button-subtitle {
    font-size: 0.65rem;
  }

  /* ---------------------------------------------------------------------
   * Navbar: spread icons across the full width.
   * Mobile defaults to justify-content: flex-start with overflow-x: auto,
   * which clumps everything left when the row fits (i.e. landscape phone).
   * ------------------------------------------------------------------- */
  .navbar-inner {
    justify-content: space-between;
    padding-left: 0;
    padding-right: 0;
    /* Keep the icon row INSIDE the navbar — scroll it horizontally rather than
       letting it overflow the viewport and widen the whole document (which
       shifts/clips the game and adds scrollbars). The mobile navbar does this by
       default ≤768px, but this layout now also runs on wider desktop windows
       (e.g. 830x490) where that clamp isn't active. Scrollbar hidden (it scrolls
       via wheel/touch and click-drag — see initNavbarDragScroll in main.js). */
    overflow-x: auto;
    max-width: 100%;
    scrollbar-width: none; /* Firefox */
    cursor: grab;
  }
  .navbar-inner::-webkit-scrollbar {
    display: none; /* Chrome/Safari */
  }
  .navbar-inner.nav-dragging {
    cursor: grabbing;
    scroll-behavior: auto;
    user-select: none;
  }

  /* Phantom flex spacers act as left/right padding. Unlike real padding,
     these stay visible when the navbar overflows and the user scrolls —
     so icons never butt against the bracket frame, fitting or scrolling. */
  .navbar-inner::before,
  .navbar-inner::after {
    content: "";
    flex: 0 0 24px;
  }

  /* Sticky with a negative top: when the user scrolls down, the navbar
     pins to the top with most of itself hidden above the viewport,
     leaving roughly its bottom 20% poking out as a hint that it's there.
     Scrolling back to the top reveals it fully. */
  .navbar {
    position: sticky;
    top: -40px;
  }

  /* ---------------------------------------------------------------------
   * Theme toggle: mobile.css shrinks --toggle-height to 20px but leaves
   * --toggle-width at 60px and the emoji at 18px, so the sun overflows
   * the track. At this size the white slider crowds the emoji against
   * the track edge — hide the slider and let the emoji itself swap from
   * sun (light, left) to moon (dark, right).
   * ------------------------------------------------------------------- */
  :root {
    --toggle-width: 40px;
    --toggle-height: 22px;
  }

  .toggle-label .slider {
    display: none;
  }

  .toggle-label .tgl-icon {
    font-size: 13px;
  }

  /* ---------------------------------------------------------------------
   * Tutorial / academy speech bubble: lay out card and text side-by-side.
   * Default stacks card-thumbnail above text, which makes the bubble tall
   * enough to spill off the top of a landscape phone. With flex + order,
   * the card sits on the left and text wraps to its right; tutorial
   * buttons drop to a new row via flex-basis: 100%.
   * ------------------------------------------------------------------- */
  .bubble.speech {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 10px;
    align-items: flex-start;
  }

  .speech-cards-row {
    order: 1;
    flex: 0 0 auto;
    margin: 0;
  }

  /* Hide card name, cost, and effect rows below the card art to save
     vertical space — only the card image remains. */
  .speech-card-thumb > span {
    display: none;
  }

  .speech-text {
    order: 2;
    flex: 1 1 200px;
    min-width: 0;
  }

  .speech-color-buttons,
  .speech-tutorial-buttons {
    order: 3;
    flex-basis: 100%;
  }

  /* ---------------------------------------------------------------------
   * In-game: shrink castle, wall, and last-played card so the hand of
   * cards has more room on short landscape viewports.
   * ------------------------------------------------------------------- */
  .image-container {
    max-height: 100px;
    max-width: 120px;
  }

  .texture-container {
    max-height: 100px;
    max-width: 22px;
  }

  .last-played-card {
    width: 70px;
    height: 140px;
    top: auto;
    bottom: 0;
    left: 50vw;
    transform: translateX(-50%);
  }

  /* Shrink hand cards too — 100×200 → 70×140, 30% smaller. */
  .card {
    width: 70px;
    height: 140px;
  }

  /* ---------------------------------------------------------------------
   * World map header: keep the stats block above the map in landscape,
   * with a 2-column / 3-row stats grid on the left and tax actions on
   * the right so the header stays compact on short screens.
   * ------------------------------------------------------------------- */
  .worldmap-header {
    padding: 10px 12px;
    gap: 8px;
  }

  .worldmap-title {
    width: 100%;
    font-size: 1.05rem;
  }

  .worldmap-header-actions {
    width: 100%;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: start;
    gap: 8px 10px;
  }

  .worldmap-stats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
    width: 100%;
  }

  .worldmap-stat {
    font-size: 0.78rem;
    padding: 4px 7px;
    justify-content: flex-start;
    min-width: 0;
  }

  .worldmap-tax-actions {
    width: auto;
    align-items: stretch;
    justify-self: end;
    align-self: stretch;
  }

  .worldmap-claim-taxes-btn {
    justify-content: center;
    min-height: 100%;
    padding-inline: 12px;
  }

  .worldmap-tax-note {
    max-width: 150px;
    text-align: center;
    font-size: 0.68rem;
    line-height: 1.2;
  }

  .card-container:last-child {
    width: 70px;
  }

  .hand {
    padding: 6px;
  }

  /* Match the desktop compact-hand rule (cards.css) — keep small hands
     centered with the landscape card width (70px) instead of 100px. */
  .hand:not(.hand-fan):has(.card-container:nth-child(-n+4):last-child) .card-container {
    width: 70px;
  }

  /* Cards are tiny in landscape for the whole hand to fit. To read them,
     scale up on hover / focus (1.8x — the "preview" state). Selected
     state stays smaller (1.5x) since the player has already committed
     and an oversized selected card would crowd the screen. */
  .hand:not(.hand-fan) .card-container.card-hovered {
    transform: translateY(-40px) scale(1.8) !important;
    animation: none;
    z-index: 10;
  }

  .hand:not(.hand-fan) .card-container.long-press {
    transform: translateY(-35px) scale(1.5);
    z-index: 10;
  }

  .hand-fan .card-container:hover,
  .hand-fan .card-container:focus {
    transform: translateY(-55px) scale(1.8) rotate(0deg) !important;
    animation: none;
    z-index: 10;
  }

  .hand-fan .card-container.long-press {
    transform: translateY(-45px) scale(1.5) rotate(0deg) !important;
    z-index: 10;
  }

  .academy-demo-selected {
    transform: translateY(-30px) scale(1.5);
    z-index: 9;
  }

  /* Card name pinned to the very bottom edge, tiny font, flush. */
  .card-name {
    bottom: 0;
    font-size: 9px;
    max-width: 100%;
    padding: 1px 2px;
    border-radius: 0;
  }

  /* Corner icons pushed onto the card border, no padding gap. */
  .card-top-left {
    top: 0;
    left: 0;
    padding: 1px 2px;
    border-radius: 0;
    gap: 2px;
  }

  .card-top-right {
    top: 0;
    right: 0;
    padding: 1px 2px;
    border-radius: 0;
    gap: 2px;
  }

  /* Card-cost + card-action icons and numbers: bumped up from the tiny default
     so they stay readable on the small (70px) landscape cards. */
  .card-icon {
    width: 15px;
    height: 15px;
  }

  /* Cost block flush to the left edge. */
  .card-costs {
    left: 0;
    gap: 2px;
  }

  .card-cost {
    padding: 1px 2px;
    border-radius: 0;
    gap: 2px;
  }

  .card-value {
    font-size: 14px;
  }

  .cost-icon {
    width: 15px;
    height: 15px;
  }

  /* Tone down the playable (yellow) and long-press (teal) glows so they
     stay proportional to the shrunk cards. */
  .your-turn .card-container.playable .card {
    box-shadow:
      -3px 0 6px #000c,
      0 0 8px rgba(255, 215, 0, 0.55),
      0 0 14px rgba(255, 215, 0, 0.35);
  }

  .long-press .card,
  .academy-demo-selected .card {
    box-shadow:
      -3px 0 6px #000c,
      0 0 8px rgba(46, 196, 182, 0.7),
      0 0 14px rgba(46, 196, 182, 0.45);
  }

  /* Tutorial / academy "tap me" highlight: the default rule applies the
     yellow ring to .card-container, which is wider than the 70px card
     and leaves a visible yellow gap. Move the ring + animation onto the
     .card element itself so it hugs the actual card edge. */
  .card-container.tutorial-highlight {
    box-shadow: none;
    animation: none;
  }

  .card-container.tutorial-highlight .card {
    animation: landscapeTutorialPulse 1.1s ease-in-out infinite;
  }

  @keyframes landscapeTutorialPulse {
    0%, 100% {
      box-shadow:
        -3px 0 6px #000c,
        0 0 0 2px rgba(255, 230, 80, 0.85),
        0 0 8px rgba(255, 215, 0, 0.65),
        0 0 14px rgba(255, 215, 0, 0.4);
    }
    50% {
      box-shadow:
        -3px 0 6px #000c,
        0 0 0 2px rgba(255, 230, 80, 1),
        0 0 12px rgba(255, 215, 0, 0.95),
        0 0 22px rgba(255, 215, 0, 0.7);
    }
  }

  /* ---------------------------------------------------------------------
   * Academy victory screen: drop "Episode Complete" and "What You Learned"
   * rows so only "Academy Progress" remains. Also hide the finishing-card
   * showcase to free up vertical space.
   *
   * Rows are targeted via :has() on their FA icon since they share the
   * same class. The :has() on .fa-graduation-cap on the section ensures
   * we don't strip rows from the campaign-mode star list.
   * ------------------------------------------------------------------- */
  .campaign-stars-section:has(.fa-graduation-cap) .campaign-star-row:has(.fa-graduation-cap),
  .campaign-stars-section:has(.fa-graduation-cap) .campaign-star-row:has(.fa-bolt) {
    display: none;
  }

  .finishing-card-section {
    display: none;
  }

  /* ---------------------------------------------------------------------
   * Victory screen tabs + Match Stats (landscape phones).
   * Tab buttons keep their icon + text label here (unlike portrait), but the
   * short viewport means even the Result content overflows the panel — so pin
   * the header + tab bar and let the active panel scroll internally.
   * ------------------------------------------------------------------- */
  .game-over-content {
    max-height: 92vh;
    max-height: 92dvh;
  }

  .go-tab-panel {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }

  /* ---------------------------------------------------------------------
   * Footer + page width: links don't wrap until <480px width, so on
   * 600–900px landscape phones they stay in one row and force horizontal
   * scroll. Wrap them and clamp body width to prevent any sideways scroll.
   * ------------------------------------------------------------------- */
  body {
    overflow-x: hidden;
  }

  .footer-links {
    flex-wrap: wrap;
    gap: 6px 12px;
  }

  .footer-link {
    font-size: 0.75rem;
  }

  /* Add landscape-mobile-only rules below this line. */

  /* ---------------------------------------------------------------------
   * Pregame color choice: put color selection and online players side by
   * side while choosing a color and while waiting after a color is picked.
   * ------------------------------------------------------------------- */
  .pregame-wrapper.pregame-color-choice-layout {
    display: grid;
    grid-template-columns: minmax(190px, 36%) minmax(0, 1fr);
    grid-template-areas:
      "color players"
      "timer players"
      "name players"
      "actions players"
      "help players";
    align-items: start;
    gap: 8px 10px;
    width: 100%;
    max-width: 900px;
    padding: 8px;
  }

  .pregame-wrapper.pregame-color-choice-layout.pregame-color-picked-layout {
    grid-template-areas:
      "color timer"
      "color players"
      "actions players"
      "help players"
      "name players";
  }

  .pregame-color-choice-layout .color-picker-container {
    grid-area: color;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 14px 16px;
  }

  .pregame-color-choice-layout .color-picker-status {
    gap: 7px;
    margin-bottom: 10px;
    font-size: 0.95rem;
  }

  .pregame-color-choice-layout .color-picker-status i {
    font-size: 1rem;
  }

  .pregame-color-choice-layout .color-picker-buttons {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
    gap: 8px;
    width: 100%;
  }

  .pregame-color-choice-layout .color-button {
    width: 100%;
    min-width: 0;
    padding: 11px 10px;
    gap: 5px;
    font-size: 0.75rem;
    letter-spacing: 0.8px;
  }

  .pregame-color-choice-layout .color-button i {
    font-size: 1.2rem;
  }

  .pregame-color-choice-layout .color-picker-label,
  .pregame-color-choice-layout .color-picker-taken,
  .pregame-color-choice-layout .color-picker-spectate {
    min-width: 0;
    justify-content: center;
    font-size: 0.8rem;
  }

  .pregame-color-choice-layout .color-picker-taken,
  .pregame-color-choice-layout .color-picker-spectate {
    padding: 8px 10px;
  }

  .pregame-color-choice-layout .pregame-timer-panel {
    grid-area: timer;
    width: 100%;
    padding: 8px 10px;
  }

  .pregame-color-choice-layout .quick-name-prompt {
    grid-area: name;
    width: 100%;
    padding: 8px 10px;
  }

  .pregame-color-choice-layout .pregame-actions {
    grid-area: actions;
    width: 100%;
    padding: 0;
    gap: 6px;
  }

  .pregame-color-choice-layout .pregame-action-btn {
    width: 100%;
    min-width: 0;
    padding: 9px 10px;
    font-size: 0.78rem;
  }

  .pregame-color-choice-layout .invite-details,
  .pregame-color-choice-layout .invite-dropdown {
    width: 100%;
  }

  .pregame-color-choice-layout .pregame-help,
  .pregame-color-choice-layout .pregame-deck-selector {
    grid-area: help;
    width: 100%;
    max-width: none;
    margin: 0;
  }

  .pregame-color-choice-layout .online-users-panel {
    grid-area: players;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 14px 16px;
    max-height: calc(100vh - 72px);
    max-height: calc(100dvh - 72px);
    overflow-y: auto;
    overscroll-behavior: contain;
  }

  .pregame-color-choice-layout.pregame-color-picked-layout .online-users-panel {
    max-height: calc(100vh - 190px);
    max-height: calc(100dvh - 190px);
  }

  .pregame-color-choice-layout.pregame-color-picked-layout .pregame-timer-panel {
    padding: 10px 12px;
  }

  .pregame-color-choice-layout.pregame-color-picked-layout .timer-actions {
    gap: 10px;
  }

  .pregame-color-choice-layout.pregame-color-picked-layout .timer-actions .timer-btn {
    min-height: 48px;
    justify-content: center;
    padding: 10px 12px;
    font-size: 0.86rem;
  }

  .pregame-color-choice-layout .online-users-header {
    margin-bottom: 7px;
    font-size: 12px;
  }

  .pregame-color-choice-layout .online-users-list {
    gap: 7px;
  }

  .pregame-color-choice-layout .online-user-row {
    padding: 5px 6px;
    font-size: 12px;
  }

  .pregame-color-choice-layout .online-section-label {
    padding-bottom: 3px;
    font-size: 10px;
  }

  /* ---------------------------------------------------------------------
   * In-game layout: resources hug the top-left/right corners. Castles are
   * pinned to the BOTTOM-left/right corners of the viewport — the tower
   * grows upward (allowed to render behind the resource panel) and the
   * wall sits inward beside the tower (allowed to render behind the hand
   * cards). Z-index keeps resources and hand cards visually on top.
   * ------------------------------------------------------------------- */
  .castle-row {
    width: 100%;
    justify-content: space-between !important;
    align-items: flex-start !important;
  }

  #red-castle,
  #blue-castle {
    width: auto !important;
    flex: 0 0 auto !important;
  }

  .castle-and-resources {
    flex-direction: column !important;
    flex-wrap: nowrap !important;
    align-items: center !important;
    gap: 4px;
    position: static !important;
  }

  /* Default for BOTH renderers: cancel mobile.css's short-height rule that
     absolutely hides the castle behind the resources. Castle sits in flow,
     below the resource panel in the column. */
  .castle-visual-group {
    position: static !important;
    z-index: auto !important;
    order: 1 !important;
  }

  /* Pin the NEW (stacked) castle to the bottom corner of the viewport. The
     tower's natural height carries it up behind the resource panel; the
     wall, offset to the inward side via its absolute positioning, drops in
     beside the tower behind the hand cards. */
  .castle-visual-group:has(.castle-and-wall-stacked) {
    position: fixed !important;
    bottom: 10px;
    z-index: 1 !important;
    width: auto !important;
    margin: 0 !important;
    pointer-events: none;
    /* Cancel mobile.css's overflow:hidden so the wall (absolutely positioned
       past the castle column's edge) isn't clipped by the wrapper. */
    overflow: visible !important;
  }
  #red-castle-visual-group:has(.castle-and-wall-stacked) {
    left: 50px;
  }
  #blue-castle-visual-group:has(.castle-and-wall-stacked) {
    right: 50px;
  }
  /* Re-enable interaction on the castle/wall shells themselves (the wrapper
     above disables pointer events so the empty area around the tower doesn't
     block taps on cards/resources). */
  .castle-visual-group .stacked-castle-shell,
  .castle-visual-group .stacked-wall-shell {
    pointer-events: auto;
  }

  /* Cancel the mobile.css width caps that were squashing the wall to
     invisibility once the wrapper was repositioned. Wall keeps its natural
     140px width from style.css. */
  .castle-and-wall-stacked > .stacked-wall-shell {
    max-width: none !important;
    flex: none !important;
  }

  /* Red new castle: anchor the wall column 24px in from the castle's left
     edge so it sits alongside the tower instead of being clipped by the
     screen edge. */
  .castle-and-wall-stacked-red .stacked-wall-shell {
    left: 24px !important;
  }

  /* Wall HP label: position inside the wall area rather than floating above
     it, so it stays visible alongside the wall column. */
  .wall-image-hp.stacked-wall-hp {
    top: 70px !important;
    left: 20px !important;
    right: auto !important;
    bottom: auto !important;
    transform: none !important;
  }

  /* In this landscape flex layout the castle shell has flex-basis 0 and its
     segments are absolutely positioned, so .stacked-castle-frame collapses to
     ~0 width. A %-based shield width then renders invisibly small (and top:%
     resolves against the collapsed box). Pin an explicit pixel size + offset
     so the shield lands on the visible lower tower (below the resource panel).
     left:50% + the base translate(-50%,-50%) still center it on the tower,
     which is also anchored at the frame's 50% line. */
  .stacked-shield-glow,
  .stacked-shield-core {
    top: 160px !important;
    width: 56px !important;
    height: auto !important;
  }

  /* Resources sit in the top-left/right corners on top of the castle. */
  .main-resources-group {
    order: 0;
    position: relative;
    z-index: 3;
  }

  /* Info bar: split the score banners so red sits at the left edge and blue at
     the right, with HP bars on the inside and turn indicator in the middle.
     display:contents dissolves the .score and .score-banners wrappers so each
     banner becomes a direct grid child of .info-bar-above-game. */
  /* Keep the info-bar's default flex layout for HP bars and turn indicator.
     Score banners are pulled out and absolutely positioned right next to the
     last-played card in the center. */
  .info-bar-above-game {
    position: relative;
  }

  .score:not(.tournament-match-info),
  .score-banners {
    display: contents;
  }

  /* Each in-game banner absolutely positioned just outside the 44px last-played
     card. Exclude .final-score-banner — those are the larger victory-screen
     banners and need their default sizing. */
  .score-banner:not(.final-score-banner) {
    position: absolute;
    top: 8px;
    z-index: 4;
  }
  .score-banner:not(.final-score-banner):nth-child(1) {
    /* Red banner: right edge sits 26px left of viewport center */
    right: calc(50% + 26px);
  }
  .score-banner:not(.final-score-banner):nth-child(2) {
    /* Blue banner: left edge sits 52px right of viewport center */
    left: calc(50% + 52px);
  }

  /* Shrink banner so it fits the short info-bar without dominating */
  .score-banner:not(.final-score-banner) .score-banner-img {
    width: 20px;
    max-height: 32px;
    object-fit: contain;
  }
  .score-banner:not(.final-score-banner) .score-banner-val {
    font-size: 0.55rem;
  }

  /* HP bars: shorter — roughly the width of the resource stats (a bit wider) —
     so they hug the corners instead of stretching across the top. Tune the
     max-width to match the resource panel on your device. */
  .player-hpbar-wrap {
    max-width: 120px;
    min-width: 0;
  }

  /* Last-played card: absolute relative to #state so it lives at the top of
     the game area (just below the navbar) instead of inside .castle-container.
     #state becomes its positioning context. */
  #state {
    position: relative;
  }
  .castle-container {
    position: static;
  }
  /* Last-played card: sits left-of-centre — far enough right to clear the red
     player stats (HP bar + resources) in the top-left corner, with the turn box
     + help spreading to its right. Tune `left` to clear the stats. */
  .last-played-card {
    position: absolute;
    top: 4px;
    bottom: auto;
    left: 170px;
    transform: none;
    width: 44px;
    height: 88px;
    z-index: 5;
  }

  /* Turn-action / hint: to the RIGHT of the last-played card, filling the whole
     central gap up to the opponent's (blue) resources so the text spreads across
     it instead of wrapping into a tall narrow column. `left` clears the card,
     `right` clears the blue HP bar + resource panel in the top-right corner. */
  #current-turn-wrap,
  .current-turn {
    position: absolute;
    top: 4px;
    left: 226px;
    right: 180px;
    transform: none;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 2px 6px;
    z-index: 5;
    text-align: center;
  }

  /* Hand sits below the turn hint, in the middle horizontal gap between castles */
  .hands {
    position: absolute;
    top: 140px;
    left: 50%;
    transform: translateX(-50%);
    width: 100%;
    max-width: calc(100vw - 280px);
    margin: 0;
    padding: 0;
    justify-content: center;
    z-index: 5;
  }

  .hand-container {
    flex: 0 0 auto;
    max-width: none;
  }

  .hand {
    width: max-content;
    max-width: 100%;
    margin: 0 auto;
    justify-content: center;
    gap: 2px;
    padding: 4px;
  }

  .hand:not(.hand-fan) .card-container {
    flex-grow: 0;
    width: 70px;
  }

  /* Hide the help panel by default — it's unreadable behind the cards, so
     there's no point showing it unless the player is actually inspecting a card.
     !important is needed because main.js sets element.style.display = "block"
     directly when help text loads. */
  .card-help-container {
    display: none !important;
  }

  /* While a card is hovered/focused, float the help panel in the top strip
     between the turn box (on the left, ends ~268px) and the opponent's (blue)
     resources in the top-right corner. left/right both set so it stretches to
     fill that gap. Tune `left` to clear the turn box and `right` to clear the
     blue resource stats. */
  #state:has(.card-container:hover) .card-help-container,
  #state:has(.card-container.card-hovered) .card-help-container,
  #state:has(.card-container.long-press) .card-help-container {
    display: block !important;
    position: absolute;
    top: 4px;
    left: 226px;
    right: 180px;
    transform: none;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 0;
    z-index: 9500; /* overlays the turn-action text while inspecting a card */
  }

  /* Post-onboarding victory screen: drop the "Basics Complete!" summary box in
     landscape — vertical space is tight and the next-step tiles are what matter. */
  .onboarding-stars-section {
    display: none;
  }

}

/* Taller short-landscape windows (≈451–500px, e.g. a desktop browser window at
   830x490) have more vertical room than the ~390px-tall phones the layout above
   targets, so the turn text can drop below the score banners. The hand, however,
   should stay tucked up just under the top stats rather than floating in the
   middle of the board: pushing it down (it used to sit at 240px) left a big empty
   band between the resource panels and the cards, with the open field below the
   cards reading as the scenic battleground. Phones (<451px) keep the tighter
   top:140 from the block above. */
@media (orientation: landscape) and (min-height: 451px) and (max-height: 500px) {
  #current-turn-wrap,
  .current-turn {
    top: 44px;
  }
  .hands {
    top: 150px;
  }
}
