/* ============================================================
   Responsive layer — phone and tablet adaptations.

   Layout tiers come from body classes set by DeviceProfile (`device-phone`,
   `device-tablet`, `device-desktop`) rather than from media queries alone.
   JavaScript needs to know the same answer — whether to mount the touch
   controls, how far to allow zooming — and two independent definitions of
   "this is a phone" would eventually disagree. The media queries that remain
   are a pre-JavaScript fallback so the first paint is never desktop-sized on a
   phone.
   ============================================================ */

/* ---------- App shell ---------- */

/*
 * 100vh is wrong on mobile browsers: it means the viewport *without* the URL
 * bar, so the bottom of the layout sits under browser chrome until the user
 * scrolls. --app-height is the live visual viewport, published by
 * ViewportManager; dvh is the native equivalent and wins where supported.
 */
.game-app {
    height: 100vh;
    height: var(--app-height, 100vh);
    max-height: var(--app-height, 100vh);
    overflow: hidden;
}

@supports (height: 100dvh) {
    .game-app {
        height: 100dvh;
        max-height: 100dvh;
    }
}

body {
    overscroll-behavior: none;
}

/* Pixel art plus a finger means no text selection and no long-press callouts
   on the world itself. */
#workshop-canvas {
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    touch-action: none;
}

/* ---------- Touch ergonomics ---------- */

/*
 * 44px is the smallest control most people can hit reliably with a thumb. The
 * desktop styling stays as it is — a mouse does not need the extra bulk, and
 * inflating every button there would waste vertical space in the panels.
 */
.input-touch button,
.input-touch .btn {
    min-height: 44px;
    padding: 10px 16px;
    -webkit-tap-highlight-color: transparent;
}

.input-touch .btn-small {
    min-height: 38px;
    padding: 8px 12px;
}

.input-touch .hud-btn {
    width: 42px;
    height: 42px;
    min-height: 42px;
    padding: 0;
}

.input-touch .btn-row,
.input-touch .btn-row-wrap {
    flex-wrap: wrap;
}

/* Panels are read with a finger: give lists momentum and stop the rubber-band
   from dragging the page behind them. */
.input-touch .modal-body,
.input-touch .panel-content {
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    touch-action: pan-y;
}

/* ---------- HUD ---------- */

.device-tablet .hud {
    padding-top: var(--safe-top, 0px);
    gap: var(--sp-2);
}

.device-tablet .hud-logo {
    display: none;
}

.device-tablet .hud-stat {
    padding: 5px 8px;
}

/*
 * Phone HUD keeps only the four numbers a player steers by: cash, offers,
 * level and the clock. Reputation and the power readout have dedicated screens
 * and lose to the 390px-wide reality of a phone in portrait.
 */
.device-phone .hud {
    height: auto;
    min-height: 44px;
    padding: calc(4px + var(--safe-top, 0px)) 8px 4px;
    gap: 5px;
    justify-content: flex-start;
}

.device-phone .hud-left,
.device-phone .hud-center,
.device-phone .hud-right {
    gap: 5px;
}

.device-phone .hud-logo,
.device-phone .hud-stat--rep,
.device-phone .hud-stat--power,
.device-phone .hud-xp-track,
.device-phone .hud-xp-label {
    display: none;
}

.device-phone .hud-stat {
    padding: 4px 7px;
    gap: 5px;
    border-radius: var(--radius);
}

.device-phone .hud-stat-value {
    font-size: 11.5px;
}

.device-phone .hud-ic .bx-icon {
    width: 15px;
    height: 15px;
}

/* The nav owns these actions on small screens. */
.mobile-nav-on .hud-right #btn-home,
.mobile-nav-on .hud-right #btn-save,
.mobile-nav-on .hud-right #btn-settings {
    display: none;
}

.device-phone .hud-center {
    margin-left: auto;
}

/* ---------- Status bar ---------- */

.device-tablet .status-bar {
    font-size: 11px;
}

.device-tablet .status-item {
    padding: 0 var(--sp-2);
}

/* No room, and the toast already carries the only line that changes. */
.device-phone .status-bar {
    display: none;
}

/* ---------- Modals as sheets ---------- */

/*
 * A centred 540px dialog on a 390px screen is a box with 8px margins and a
 * scrollbar. On phones the modal becomes a bottom sheet instead: full width,
 * anchored to the thumb, with a header that stays put while the body scrolls.
 */
.device-phone .modal-root {
    padding: 0;
    align-items: flex-end;
}

.device-phone .modal {
    width: 100%;
    max-width: 100%;
    max-height: 92dvh;
    max-height: calc(var(--app-height, 100vh) - 24px);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    border-left: none;
    border-right: none;
    border-bottom: none;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/*
 * The grabber. It is not draggable — it is the one glyph that tells a phone
 * player this panel came up from the bottom edge and goes back down there,
 * which a plain sticky header does not.
 */
.device-phone .modal-header::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 50%;
    transform: translateX(-50%);
    width: 34px;
    height: 4px;
    border-radius: 999px;
    background: var(--line-strong);
}

.device-phone .modal-header {
    position: sticky;
    top: 0;
    z-index: 2;
    flex: none;
    background: var(--bg-1);
    padding: calc(var(--sp-3) + 8px) var(--sp-4) var(--sp-3);
}

.device-phone .modal-header h2 {
    font-size: 17px;
}

.device-phone .modal-body {
    flex: 1;
    overflow-y: auto;
    padding: var(--sp-3);
    padding-bottom: calc(var(--sp-5) + var(--safe-bottom, 0px));
}

.device-phone .modal-footer {
    flex: none;
    padding-bottom: calc(var(--sp-3) + var(--safe-bottom, 0px));
}

.device-tablet .modal {
    max-width: 620px;
    max-height: 88dvh;
}

/* A sheet that scales up from the middle reads as a dialog; one that rises
   from the bottom edge reads as a sheet. Same duration, different origin. */
.device-phone .modal-root.modal-entering .modal {
    animation: sheetIn 0.24s cubic-bezier(0.22, 0.61, 0.36, 1);
}

@keyframes sheetIn {
    from { opacity: 0.6; transform: translateY(18px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .device-phone .modal-root.modal-entering .modal {
        animation: none;
    }
}

/* Grids inside panels collapse to a single column before they get too narrow
   to read. */
.device-phone .modal .card {
    padding: var(--sp-3) var(--sp-3);
}

.device-phone .slot-row {
    flex-wrap: wrap;
    gap: var(--sp-2);
}

.device-phone .slot-actions {
    width: 100%;
    justify-content: flex-end;
}

/* ---------- Panel contents on a narrow screen ---------- */

/*
 * Three or four equal columns of numbers is a desktop shape. Below roughly
 * 420px each cell is under 90px, which is narrower than the labels above them,
 * so the text wraps to three lines and the row stops being scannable. Two
 * columns keeps every figure on one line.
 */
.device-phone .storage-summary,
.device-phone .property-current,
.device-phone .property-metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/*
 * The settings mixer: label, slider, readout and switch on one line needs
 * ~330px before the slider is too short to aim at. On a phone the label takes
 * the first row on its own and the controls get the full width underneath.
 */
.device-phone .setting-row {
    grid-template-columns: minmax(0, 1fr) 44px auto;
    row-gap: 4px;
}

.device-phone .setting-row .setting-label {
    grid-column: 1 / -1;
    white-space: normal;
}

/* A footer of buttons wraps rather than shrinking each one below a thumb. */
.device-phone .modal-footer {
    flex-wrap: wrap;
}

.device-phone .modal-footer .btn {
    flex: 1 1 auto;
    justify-content: center;
}

/* Long unbroken strings — brand names, order ids, filenames — must not force
   the whole sheet to scroll sideways. */
.device-phone .modal-body {
    overflow-wrap: anywhere;
}

/* Tables are the one thing that legitimately needs horizontal room; give them
   their own scroller instead of widening the page. */
.device-phone .modal-body table {
    display: block;
    max-width: 100%;
    overflow-x: auto;
}

/* ---------- Tablet ---------- */

/*
 * A tablet has the width for the desktop layout but is held at arm's length
 * and driven with a finger, so the density is the desktop's and the targets
 * are the phone's. Panels get a little more room than a phone sheet, which is
 * the whole reason the tier exists.
 */
.device-tablet .modal-body {
    padding: var(--sp-4);
}

.device-tablet .modal-footer {
    padding-bottom: calc(var(--sp-3) + var(--safe-bottom, 0px));
}

/* Portrait on a tablet is 768px wide: two columns read better than three. */
.device-tablet.orient-portrait .storage-summary,
.device-tablet.orient-portrait .property-metrics {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* ============================================================
   The studio computer
   ------------------------------------------------------------
   These live here rather than next to the rest of the computer's styling in
   polish.css for a cascade reason: `.device-phone .computer-modal` and
   `.device-phone .modal` have identical specificity, so whichever stylesheet
   comes last wins — and this one does. Kept beside polish.css they were
   silently overridden by the bottom-sheet rules above.
   ============================================================ */

/* ---------- Tablet ---------- */
/* Room enough to keep the monitor, not enough for its desktop margins. */
.device-tablet .computer-modal { width: 96vw; }
.device-tablet .computer-bezel { padding: 10px 10px 7px; border-radius: 9px; }
.device-tablet .computer-screen { height: min(84dvh, 900px); }
.device-tablet .desktop-app-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.device-tablet .computer-desktop { padding: clamp(18px, 3vw, 32px); gap: 18px; }

/* ---------- Phone ---------- */
/*
 * The monitor goes away entirely.
 *
 * A bezel, a brand plate and a 1080px screen make sense as a picture of a
 * machine sitting on a desk. Scaled down to 390px they are a border eating
 * eleven percent of the width, a taskbar with its labels hidden and a
 * three-column grid folded into one — the drawing of a computer with none of
 * the things that made it read as one. What survives is what the metaphor was
 * for: it is a place you go to, with a title bar and a way back out. So on a
 * phone StudioOS is simply a full-screen app, and the chrome is dropped rather
 * than shrunk.
 */
.device-phone .computer-modal {
    width: 100%;
    max-width: 100%;
    /* .device-phone .modal above turns modals into bottom sheets; the computer
       is the one screen that wants the whole viewport instead. */
    height: 100%;
    max-height: 100%;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    overflow: hidden;
}

/* ModalHost stamps the open modal's id here, which is what lets the container
   itself change shape for one modal without a selector that depends on its
   contents. */
.device-phone .modal-root[data-owner="computer"] {
    padding: 0;
    align-items: stretch;
}

.device-phone .computer-bezel {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.device-phone .computer-screen {
    flex: 1;
    min-height: 0;
    height: auto;
    grid-template-rows: auto minmax(0, 1fr) auto;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding-top: var(--safe-top, 0px);
}

/* The plastic label under the monitor. There is no monitor now. */
.device-phone .computer-brand {
    display: none;
}

.device-phone .computer-topbar {
    min-height: 48px;
    gap: 8px;
    padding: 6px 10px;
}

/* The clock is in the HUD one row above; repeating it here costs a third of
   the bar on a 360px screen. */
.device-phone .computer-topbar-actions > span {
    display: none;
}

.device-phone .computer-topbar-actions button,
.device-phone .computer-home {
    min-width: 44px;
    min-height: 40px;
    justify-content: center;
}

/* "StudioOS" next to the cube is decoration once the window has a title. */
.device-phone .computer-home span {
    display: none;
}

.device-phone .computer-topbar-center {
    font-size: 12px;
    letter-spacing: .06em;
    /* A long app name must not push the close button off the edge. */
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.device-phone .computer-taskbar {
    min-height: 44px;
    padding: 4px 10px calc(4px + var(--safe-bottom, 0px));
    font-size: 10px;
}

/* Cash and reputation are already in the HUD; the taskbar keeps the two things
   that are only here — the brand mark and "move desk". */
.device-phone .computer-taskbar > span:not(.computer-start) {
    display: none;
}

.device-phone .computer-taskbar button {
    min-height: 36px;
}

.device-phone .computer-desktop {
    align-content: start;
    gap: 16px;
    padding: 18px 14px calc(18px + var(--safe-bottom, 0px));
}

.device-phone .desktop-welcome h2 { font-size: 24px; }
.device-phone .desktop-welcome p { font-size: 13px; line-height: 1.5; }

/* One column, and every tile a comfortable thumb target rather than a two-line
   card squeezed to fit three across. */
.device-phone .desktop-app-grid {
    grid-template-columns: 1fr;
    gap: 8px;
}

.device-phone .desktop-app {
    grid-template-columns: 42px 1fr;
    min-height: 64px;
    padding: 11px 12px;
    gap: 1px 11px;
}

.device-phone .desktop-app-icon { width: 40px; height: 40px; }
.device-phone .desktop-app strong { font-size: 15px; }
.device-phone .desktop-app small { font-size: 10px; line-height: 1.3; }

/* No hover on a finger, and a lift under the thumb reads as a glitch. */
.device-phone .desktop-app:hover,
.device-phone .desktop-app:active {
    transform: none;
}

.device-phone .desktop-widget-row {
    grid-template-columns: repeat(2, 1fr);
}

.device-phone .desktop-widget-row > div { padding: 9px 11px; }
.device-phone .desktop-widget-row strong { font-size: 14px; }

.device-phone .computer-app-titlebar {
    padding: 8px 12px;
    gap: 8px;
}

.device-phone .computer-app-titlebar strong { font-size: 15px; }
/* The subtitle repeats what the icon and the name already say. */
.device-phone .computer-app-titlebar small { display: none; }
.device-phone .computer-app-titlebar > div { grid-template-columns: 30px auto; }
.device-phone .computer-app-logo { width: 28px; height: 28px; grid-row: auto; }
.device-phone .computer-app-titlebar button { min-height: 38px; white-space: nowrap; }

.device-phone .computer-app-content {
    padding: 12px 12px calc(16px + var(--safe-bottom, 0px));
}

/* Landscape on a phone leaves ~350px of height: the welcome block would push
   the apps themselves below the fold. */
.device-phone.orient-landscape .desktop-welcome {
    display: none;
}

.device-phone.orient-landscape .desktop-app-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.device-phone.orient-landscape .computer-topbar { min-height: 40px; }
.device-phone.orient-landscape .computer-taskbar { min-height: 38px; }

/* ---------- Pre-JavaScript fallback ----------
   Mirrors the phone rules so the very first paint is not desktop-shaped on a
   narrow screen. Once DeviceProfile runs, the body classes above take over. */

@media (max-width: 700px) {
    .hud-logo {
        display: none;
    }

    .status-bar {
        display: none;
    }

    .modal {
        max-width: 100%;
        max-height: 92vh;
    }
}

/* Short landscape phones: the HUD and the world both need every pixel. */
@media (max-height: 460px) and (orientation: landscape) {
    .device-phone .hud {
        min-height: 38px;
    }

    .device-phone .hud-stat {
        padding: 2px 6px;
    }
}
