/* The phone shell the solve and cad pages share (anim-mobile.html,
   maker-mobile.html; behavior in js/shared/sheet-shell.js): the stage
   docked between a fixed topbar and a bottom tab bar, one bottom sheet
   the tabs open, the long-press help tip.  Shared control styles come
   from controls.css, colors from burr-theme.css.  Heights use 100dvh /
   env(safe-area-inset-*) so browser chrome and notches never hide UI. */

:root {
    /* Fixed bar heights: the stage, sheet, toast, and picker offset
       against these instead of measuring the DOM. */
    --topbar-h: calc(48px + env(safe-area-inset-top, 0px));
    --tabbar-h: calc(56px + env(safe-area-inset-bottom, 0px));
}

/* vh lines are fallbacks for engines without dvh (pre-2022 Safari). */
body { height: 100vh; height: 100dvh; }

/* ── The stage ──
   The page's views live in #stage and size from its box (its
   ResizeObserver re-fits them whenever it changes). The shell claims the
   bottom edge through --stage-bottom: the tab bar alone when no sheet
   is open, or the tab bar plus the open sheet's capped share — past
   the cap a tall sheet overlays the stage instead of squashing the
   canvas to a strip. */
#stage {
    position: fixed;
    top: var(--topbar-h);
    left: 0;
    right: 0;
    bottom: var(--stage-bottom, var(--tabbar-h));
}

/* Nothing on this page hovers; taps must not double-fire zoom either. */
button, select, input, textarea, a, summary { touch-action: manipulation; }

/* 16px is the threshold below which iOS auto-zooms a focused field —
   every editable control, including the drawer's dynamically created
   facet inputs and the piece-picker filter, must clear it. !important
   because query.css sets 11px at higher specificity. */
input, select, textarea { font-size: 16px !important; }

/* Touch hit areas: 44px minimum for standalone buttons. */
.btn { min-height: 44px; min-width: 44px; }

/* ── Topbar ── */
#mobile-topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 40;
    height: 48px;   /* content height; the safe areas ride in the padding
                       (sides too: landscape puts the notch left/right) */
    padding: env(safe-area-inset-top, 0px)
             calc(8px + env(safe-area-inset-right, 0px))
             0
             calc(8px + env(safe-area-inset-left, 0px));
    box-sizing: content-box;
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-accent);
    /* chrome borders use --panel-border, like the desktop topbar */
    border-bottom: 1px solid var(--panel-border);
}
#mobile-title {
    flex: 1;
    min-width: 0;
    height: 44px;
    padding: 0 6px;
    border: none;
    background: none;
    color: var(--text);
    font-family: inherit;
    font-size: 15px;
    font-weight: 600;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
#mobile-topbar .theme-toggle { width: 44px; height: 44px; }
/* At the one width where the topbar's actions squeeze the title
   hardest, trim chrome—not hit areas—to recover room. */
@media (max-width: 359px) {
    #mobile-topbar {
        gap: 4px;
        padding-right: calc(4px + env(safe-area-inset-right, 0px));
        padding-left: calc(4px + env(safe-area-inset-left, 0px));
    }
    #mobile-title { padding: 0 2px; }
}

/* ── Tab bar ── */
#mobile-tabbar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    height: 56px;   /* content height; safe areas ride in the padding */
    padding: 0 env(safe-area-inset-right, 0px)
             env(safe-area-inset-bottom, 0px)
             env(safe-area-inset-left, 0px);
    box-sizing: content-box;
    display: flex;
    background: var(--bg-accent);
    border-top: 1px solid var(--panel-border);
}
#mobile-tabbar [role="tab"] {
    flex: 1;
    min-height: 44px;
    border: none;
    background: none;
    color: var(--muted);
    font-family: inherit;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 1px;
    cursor: pointer;
}
#mobile-tabbar [role="tab"][aria-selected="true"] {
    color: var(--accent-text);
    box-shadow: inset 0 2px 0 var(--accent);
}
#mobile-tabbar [role="tab"]:disabled { opacity: 0.35; cursor: default; }

/* ── Bottom sheet ── */
#mobile-sheet {
    position: fixed;
    left: 0;
    right: 0;
    bottom: var(--tabbar-h);
    z-index: 30;
    height: 55vh;       /* pre-shell default; the shell sets inline px */
    height: 55dvh;
    /* No CSS min-height: the shell's 160px floor yields to the
       between-the-bars cap on short viewports (keyboard up, tiny
       landscape); a CSS minimum would win over max-height and shove
       the sheet under the topbar. */
    /* Never taller than the space between the bars: an 85%-of-viewport
       sheet would slide under the fixed topbar on notched phones and
       swallow its own drag handle. The shell enforces the same cap in
       px (sheet-shell.js maxSheetPx). */
    max-height: calc(100vh - var(--topbar-h) - var(--tabbar-h));
    max-height: calc(100dvh - var(--topbar-h) - var(--tabbar-h));
    display: flex;
    flex-direction: column;
    background: var(--panel-strong);
    backdrop-filter: blur(10px);
    border-top: 1px solid var(--panel-border);
    box-shadow: var(--shadow);
}
/* Explicit display on the sheet and its panels (including the
   id-selector rules below) beats the UA's [hidden] rule — restore it at
   above-id specificity. */
#mobile-sheet[hidden] { display: none; }
#mobile-sheet .sheet-panel[hidden] { display: none; }

/* The chrome row: the drag handle, 44px tall for the finger, and the
   close button beside it.  The handle's grabber is drawn 20px down so
   it sits centered in the row. */
#sheet-chrome {
    flex: none;
    display: flex;
    align-items: center;
}
#sheet-handle {
    flex: 1;
    position: relative;
    height: 44px;
    border: none;
    background: none;
    cursor: grab;
    touch-action: none;     /* pointer drags resize; never scroll */
}
#sheet-handle::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 20px;
    transform: translateX(-50%);
    width: 44px;
    height: 4px;
    border-radius: 2px;
    background: var(--faint);
}
#sheet-close {
    flex: none;
    width: 44px;
    height: 44px;
    margin-right: 4px;
    padding: 12px;
    border: none;
    border-radius: 50%;
    background: none;
    color: var(--muted);
    cursor: pointer;
}
#sheet-close:active { background: var(--field-strong); }
#sheet-close svg {
    display: block;
    width: 20px;
    height: 20px;
    fill: none;
    stroke: currentColor;
    stroke-linecap: round;
    stroke-width: 1.8;
}
/* A snap eases the sheet to its detent, and the stage edge and the
   pill along with it; the shell holds the class for the transition's
   length only (sheet-shell.js SNAP_MS), so drags and refits stay
   immediate. */
body.sheet-snapping #mobile-sheet { transition: height 180ms ease-out; }
body.sheet-snapping #stage { transition: bottom 180ms ease-out; }
@media (prefers-reduced-motion: reduce) {
    body.sheet-snapping #mobile-sheet,
    body.sheet-snapping #stage { transition: none; }
}

.sheet-panel {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
}


/* Short landscape is a split workspace, not a squashed portrait sheet:
   the stage owns the left half while the active panel uses the right,
   top to bottom.  Inline sheet heights still record the portrait
   detent, but do not constrain this orientation: the handle, with
   nothing to size, is hidden and the close button keeps the chrome
   row, and the shell skips a drag's height write under the same
   condition (sheet-shell.js splitLayout) should a drag straddle the
   rotation. */
@media (orientation: landscape) and (max-height: 500px) {
    body.sheet-open #stage {
        right: 50%;
        bottom: var(--tabbar-h);
    }
    #mobile-sheet {
        top: var(--topbar-h);
        left: 50%;
        bottom: var(--tabbar-h);
        height: auto !important;
        max-height: none;
        border-top: none;
        border-left: 1px solid var(--panel-border);
        box-shadow: var(--shadow-soft);
    }
    #sheet-handle { display: none; }
    #sheet-chrome { justify-content: flex-end; }
}

/* ── Long-press help (sheet-shell.js touch tip) ──
   The hover-title layer, on touch: holding a titled control shows its
   title here.  Long-pressable text must not fight the hold with the
   platform's selection UI. */
#touch-tip {
    position: fixed;
    left: calc(8px + env(safe-area-inset-left, 0px));
    right: calc(8px + env(safe-area-inset-right, 0px));
    bottom: calc(var(--tabbar-h) + 8px);
    z-index: 60;
    padding: 10px 14px;
    background: var(--panel-solid);
    border: 1px solid var(--panel-border);
    border-radius: 8px;
    box-shadow: var(--shadow);
    color: var(--text);
    font-size: 13px;
    line-height: 1.5;
    max-height: 40vh;
    max-height: 40dvh;
    overflow-y: auto;
}
#touch-tip[hidden] { display: none; }

/* The cross-shell link sits at the foot of a sheet panel as one
   full-width tap row. */
.sheet-panel #ui-switch-link {
    display: block;
    margin-top: 14px;
    padding: 10px 0;
    font-size: 12px;
    text-align: center;
}
