/* touch.css — the phone layout, and it is honestly worse.
 *
 * The homepage card says so and so does the menu. What this file does is make
 * a phone PLAYABLE rather than pretend it is equivalent to a mouse:
 *
 *   * the top bar folds into two short rows plus a 4 px domination strip,
 *     because eight cells on a 390 px screen is eight unreadable cells;
 *   * the selection panel collapses to a 44 px strip of portraits, a name and
 *     a health bar — the four stats are a desktop luxury and the map is what
 *     the screen is for;
 *   * the command card becomes ONE horizontally scrolling row of 72×48
 *     buttons in the same order as the desktop grid read left-to-right, so a
 *     player who learns one learns the other;
 *   * the hotkey badges go, since there is no keyboard to press;
 *   * the mode pill appears, because one finger cannot both drag a selection
 *     box and pan the camera, so a player has to say which they mean.
 *
 * Two media queries, deliberately different:
 *   - the LAYOUT block fires below 1100 px wide OR on a coarse pointer, so a
 *     narrow desktop window gets a layout that fits rather than panels that
 *     overlap (02 §1.3). 1100 and not 1000: at 1000–1100 the desktop bar
 *     clipped seven cells mid-word and the selection panel's middle column
 *     computed to nothing, and the two-row bar fits that width cleanly;
 *   - the TOUCH block fires only on `hover: none` AND `pointer: coarse`,
 *     because either test alone catches a laptop with a touchscreen and takes
 *     its mouse away.
 */

/* ==================================================================== */
/* Layout: narrow screens, whatever is pointing at them                 */
/* ==================================================================== */
@media (max-width: 1100px), (hover: none) and (pointer: coarse) {

  :root { --mm: 120px; }

  /* ---- top bar: 40 + 4 + 24 = 68 ---------------------------------- */
  #topbar {
    height: 68px;
    flex-wrap: wrap;
    align-content: flex-start;
    padding-top: env(safe-area-inset-top);
  }
  .cell {
    min-width: 0;
    flex: 1 1 0;
    padding: 2px 7px;
    column-gap: 4px;
  }
  /* The desktop widths clamp the flex base size, and the base size is what
     decides where a wrapping bar breaks: materiel and magazine alone claimed
     294 px of a 390 px row and pushed the strip onto a line of its own. The
     id-level widths need an id-plus-class selector to beat them. */
  #topbar .cell { min-width: 0; }
  /* The clock face is the only clock anyone reads on a phone. */
  #cellClock > label { display: none; }
  .cell > label { font-size: 8.5px; line-height: 1; letter-spacing: 0.06em; }
  .cell > b { font-size: 14px; line-height: 1.1; }
  .cell > i { font-size: 9.5px; padding-bottom: 1px; }
  .cell .bar { width: 100%; margin-top: 1px; }
  #magBar { width: 100%; }
  #cellClock > i { font-size: 8.5px; }
  #cellSat > b { font-size: 12px; }

  /* Row 1: the two resources and the clock, then the strip.
     Row 2: the two ceilings, the chain and the satellite.
     Order, not markup — index.html is a contract and the desktop reading
     order is the right one there. */
  #cellMat  { order: 1; height: 40px; flex: 1 1 0; }
  #cellMag  { order: 2; height: 40px; flex: 1.4 1 0; }
  #cellClock { order: 3; height: 40px; flex: 0 0 auto; }
  /* The sudden-death line is 92 px of a 390 px row and the clock face says
     the same thing once the match is past 18:00. The two income rates go for
     the same reason and buy the strip its 44 px thumb targets: a rate clipped
     to "+34 /n" is not a rate, and the bars beside them still show the level. */
  #cellClock > i, #matRate, #magRate { display: none; }
  #topbar .strip { order: 4; height: 40px; margin-left: auto; padding: 0 2px; }
  #cellDom  { order: 5; flex: 0 0 100%; min-width: 0; height: 4px; padding: 0; border-right: 0; }
  #cellSup  { order: 6; height: 24px; flex: 1 1 0; }
  #cellCtl  { order: 7; height: 24px; flex: 1 1 0; }
  /* style.css drops this cell below 1320 px because "the selection panel
     prints the same number" — which is not true here, where touch.css hides
     .sel-stats. Chain latency is the difficulty knob; re-assert it. */
  #cellChain { order: 8; height: 24px; flex: 1 1 0; display: grid; }
  #cellSat  { order: 9; height: 24px; flex: 1.2 1 0; }
  #topbar .link { order: 10; height: 24px; margin-left: auto; padding-right: 7px; }
  #topbar .spacer { display: none; }

  /* Row 2 is one line of value, no label: the label is a word the player
     already knows by the time they are on a phone. */
  #cellSup > label, #cellCtl > label, #cellChain > label, #cellSat > label { display: none; }
  #cellSup > b, #cellCtl > b, #cellChain > b, #cellSat > b { font-size: 12px; font-weight: 600; }
  #cellSup .bar, #cellCtl .bar { display: none; }

  /* Domination: a bar, with the copy behind a tap. */
  #cellDom > b { display: none; }
  #cellDom { flex: 0 0 100%; }
  #cellDom .bar { width: 100%; max-width: none; height: 4px; border: 0; border-radius: 0; margin: 0; }

  /* The strip keeps the two game actions and the menu. Overlays, sound and
     hotkeys all live in the Esc menu, and a hotkey sheet on a device with no
     keys is a dead button. */
  /* `#topbar .strip button` is an id, a class and a type, so a bare id
     selector here would lose to it and the three buttons would stay. */
  #topbar .strip #btnOverlays,
  #topbar .strip #btnSound,
  #topbar .strip #btnKeys { display: none; }
  /* 44×40, not 30×36: ≡ is a phone's only route to settings and leaving,
     and deep strike is a one-shot ability with a costly misfire. Row 1 is
     40 px tall and the strip was 99 px wide, so the room was there. */
  #topbar .strip button { width: 44px; height: 40px; }
  #topbar .strip #btnStrike { width: 52px; }

  /* The account pill has nowhere to go in a 390 px bar, and where its own CSS
     puts it — fixed bottom-left, z 9000 — is on top of the first button of the
     command card. So while a match is on screen it goes away; the menu it
     comes back to has its own Account buttons in the About section. */
  body.in-match .sga-floating { display: none; }

  /* ---- left column ------------------------------------------------- */
  /* One card of notifications takes the top-centre; the mission list goes
     under it rather than beside it, because 390 px has no beside. */
  #mission { top: 124px; left: 6px; width: 200px; max-height: 120px; font-size: 11px; }
  #mission:not([hidden]) ~ #feed { top: 124px; }
  /* The feed clears the taller two-row bar. It stays on a narrow DESKTOP
     window — that window has a mouse to hover it with and 340 px to read it
     in, and it is the only place the full text of a long notification can be
     read. The notification stack is centred, so at 1000 px its left edge is
     at 350 and the two sit side by side. */
  #feed { top: 74px; }

  #notify {
    top: 74px;
    width: min(300px, calc(100vw - 24px));
  }

  /* ---- minimap, tray, mode pill ------------------------------------ */
  #minimap { left: 6px; bottom: 100px; }
  /* 300 px is as much strategic picture as a phone has room for. */
  #minimap.big {
    width: min(300px, calc(100vw - 24px));
    height: min(300px, calc(100vw - 24px));
  }
  #tray {
    left: 6px;
    right: 6px;
    bottom: calc(100px + var(--mm) + 4px);
    width: auto;
    max-height: 28px;
    flex-direction: row;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    gap: 4px;
  }
  #tray::-webkit-scrollbar { display: none; }
  /* The chips carry the panel look; the strip behind them does not, or one
     chip on a 768 px tablet paints a black band across the screen. */
  #tray { background: none; border: 0; padding: 0; box-shadow: none; }
  #tray > .chip { flex: 0 0 auto; width: 168px; background: var(--panel-solid); }

  /* ---- selection strip, 390×44 ------------------------------------- */
  #selpanel {
    left: 0;
    right: 0;
    bottom: 56px;
    height: 44px;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 8px;
    border-radius: 0;
    border-width: 1px 0;
  }
  .sel-portrait { flex: 0 0 auto; flex-direction: row; }
  #selPortrait { width: 32px; height: 32px; border-width: 1px; }
  #selRole, #selBlurb, #selList, #selQueue, #selRally, #groups, .sel-stats { display: none; }
  .sel-main { flex-direction: row; align-items: center; gap: 8px; overflow: hidden; }
  .sel-head { min-width: 84px; flex: 1 1 auto; }
  #selState { flex: 0 1 auto; min-width: 0; }
  #selName { font-size: 12.5px; }
  #selLink { display: none; }
  #selHealth { width: 78px; height: 6px; flex: none; }
  .sel-health { flex: none; }
  #selHp { font-size: 10.5px; white-space: nowrap; }
  #selState { flex-wrap: nowrap; overflow: hidden; }
  #selState > .badge { font-size: 9.5px; padding: 1px 4px; }
  /* The one line here is the only instruction on a phone's screen, and it has
     to give up width before it pushes itself off the right edge. */
  #selHint { flex: 1 1 auto; min-width: 0; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  #selRow { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  #selRow::-webkit-scrollbar { display: none; }
  #selRow > .pchip { width: 32px; height: 32px; flex: 0 0 auto; }
  #selRow > .pchip > canvas { width: 28px; height: 28px; }

  /* ---- command card: one scrolling row, 390×56 --------------------- */
  #card {
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: 56px;
    padding: 4px 6px;
    padding-bottom: max(4px, env(safe-area-inset-bottom));
    border-radius: 0;
    border-width: 1px 0 0;
    gap: 0;
  }
  #cardHead { display: none; }
  #card .grid {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 5px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  #card .grid::-webkit-scrollbar { display: none; }
  .slot { flex: 0 0 72px; width: 72px; height: 48px; }
  /* No keyboard, no keycap — and the label takes the space back. Glyph over
     label rather than beside it: 72 px minus a glyph leaves 46 px of text,
     and stacked the same word gets the whole button. */
  .slot > kbd { display: none; }
  .slot > .glyph {
    left: 0;
    right: 0;
    top: 4px;
    margin: 0 auto;
    transform: none;
    width: 18px;
    height: 18px;
  }
  .slot > .glyph > svg { width: 18px; height: 18px; }
  .slot > .glyph > canvas { width: 22px; height: 22px; }
  .slot > .label {
    left: 2px;
    right: 2px;
    top: 24px;
    bottom: 3px;
    justify-content: center;
    text-align: center;
    font-size: 10px;
    line-height: 1.05;
  }
  .slot:has(.sub:not(:empty)) > .label { bottom: 11px; }
  .slot > .sub { left: 0; right: 0; text-align: center; font-size: 9px; }
  /* An empty rectangle is furniture on a desktop grid and an obstacle in a
     scrolling row. */
  .slot.empty { display: none; }

  /* ---- floating layers --------------------------------------------- */
  /* Above the minimap, not merely above the order bar: at 390 px a full-width
     tip on the line above the card lands squarely on the minimap. */
  #tip {
    left: 6px;
    right: 6px;
    bottom: calc(104px + var(--mm) + 40px);
    max-width: none;
    transform: none;
    font-size: 12px;
  }
  /* A width, not a max-width: with only a ceiling the box shrink-wrapped into
     whatever space was left of the viewport edge — 70 px of seven two-word
     lines — so hud.js's right-edge nudge had nothing to nudge. */
  #toasts > .toast { width: min(300px, calc(100vw - 24px)); max-width: none; }
  #toasts > .toast.centre { bottom: 152px; }
  #overlays { top: 74px; right: 6px; }
  #tooltip { max-width: 260px; }
  #matchover { top: 74px; }

  #doctrineDrawer { width: 96vw; max-height: 72vh; padding: 11px 12px 13px; }
  #doctrine { grid-template-columns: 1fr; }
  /* The overlay's own 24 px padding is the frame; the sheet fills what is
     left rather than setting a width the frame cannot hold. */
  #keys { padding: 8px; }
  #keys > .sheet { width: 100%; padding: 14px; }
  #keys .cols { grid-template-columns: 1fr; gap: 14px; }
  #escmenu > .sheet, #confirm > .sheet { width: min(360px, 100%); }
  #end > .sheet, #brief > .sheet, #done > .sheet { width: 100%; padding: 16px; }
  #endTitle { font-size: 27px; }
  #endStats { grid-template-columns: 1fr; }

  /* The coach is the mission panel during the tutorial, so it gets the width
     it needs and the meter collapses to its number (01 §4.7). */
  #coach {
    top: 74px;
    left: 6px;
    right: 6px;
    width: auto;
    max-width: none;
    transform: none;
    padding: 8px 10px 9px;
  }
  #coach.enter { animation: none; }
  #coachBody { font-size: 12px; }
  #coachMeter { height: 13px; }
  #coachFill { display: none; }
  /* Measured, not guessed: tutorial.js publishes the card's real height as
     --coach-h, and a fixed 176 px landed inside step 5's four-line card. */
  #hud:has(#coach:not([hidden])) #notify { top: calc(74px + var(--coach-h, 100px) + 8px); }
  /* And the card itself may not grow past the stack it is being pushed away
     from: the body scrolls before the layout breaks. */
  #coach { max-height: 46vh; overflow-y: auto; }

  /* ---- menu -------------------------------------------------------- */
  .menu-inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 22px;
    padding: 22px 14px 48px;
  }
  .hero { padding-top: 0; min-height: 180px; display: flex; flex-direction: column; justify-content: center; }
  #menu h1 { font-size: 40px; }
  .tagline { font-size: 13.5px; }
  section.play { grid-column: 1; padding: 13px; }
  section.campaign, section.about { grid-column: 1; }
  #factionRow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Two-up cards are wider and taller than the four-up ones, so the fixed
     height becomes a clip; the line clamps still keep them even. */
  .faction { height: auto; min-height: 130px; }
  section.play .row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  #campaignList { grid-template-columns: 1fr; }
  .mission { height: auto; min-height: 80px; }
  section.about ul { columns: 1; }
  .loader-box h1 { font-size: 32px; }
}

/* ==================================================================== */
/* Touch: only where there is genuinely no mouse                        */
/* ==================================================================== */
@media (hover: none) and (pointer: coarse) {

  /* The one honest touch control: a finger has to say whether a drag is a
     selection or a pan, because it cannot mean both. */
  #touchMode {
    display: block;
    position: fixed;
    right: 8px;
    bottom: 108px;
    z-index: 24;
    width: 120px;
    height: 36px;
    padding: 0;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.08em;
    background: var(--panel-solid);
    border: 2px solid var(--accent);
    border-radius: 18px;
  }
  #touchMode.order { border-color: var(--warn); color: var(--warn); }

  /* 44 px is the smallest thing a thumb hits reliably. Everything pressed
     mid-match gets it; the command card's 48 px row already has it. */
  #escmenu button, #confirm button, #end button, #done button, #brief button,
  #tutorialBtn, #playBtn, .mission, .faction, #tipClose, #doctrineClose,
  #selList > .prow > button.add, #selQueue > .qchip > button.x,
  #nameInput, #modeSel, #diffSel, #roomInput { min-height: 44px; }
  #selList > .prow > button.add, #selQueue > .qchip > button.x { min-width: 32px; }
  #topbar .strip button { min-width: 44px; min-height: 40px; }
  #tray > .chip { height: 34px; }
  #tray { max-height: 34px; bottom: calc(100px + var(--mm) + 6px); }

  /* One card, and only one. A 44 px window over a 120 px stack showed the top
     three pixels of the next card as a stray coloured strip; hiding the rest
     outright leaves nothing to peek. Two lines, because #feed — which carried
     the full sentence — is display:none on a phone. A narrow desktop window
     keeps the desktop stack: it has the height and it has the feed. */
  #notify > .note:not(:first-child) { display: none; }
  #notify > .note > .txt { -webkit-line-clamp: 2; }

  /* No mouse, no hover, no freeze — and no width. Notifications carry the
     same lines on a phone. */
  #feed { display: none; }

  /* Hover tooltips need a hover. On a phone the same copy arrives as a tap
     sheet, which hud.js builds; the hover card would only ever flicker. */
  #tooltip { display: none; }

  /* Respect the notch: without this the command card sits under the home
     indicator on an iPhone and its bottom row is unpressable. */
  #minimap { left: max(6px, env(safe-area-inset-left)); }
  #tray { left: max(6px, env(safe-area-inset-left)); right: max(6px, env(safe-area-inset-right)); }
  #touchMode { right: max(8px, env(safe-area-inset-right)); }
  #card { padding-left: max(6px, env(safe-area-inset-left)); padding-right: max(6px, env(safe-area-inset-right)); }
}

/* ==================================================================== */
/* Landscape phone: almost no vertical room at all                      */
/* ==================================================================== */
@media (hover: none) and (pointer: coarse) and (orientation: landscape) {
  :root { --mm: 96px; }

  /* One 36 px bar: materiel, magazine, clock, menu. Everything else is
     readable from the map or lives one tap away in the Esc menu. */
  #topbar { height: 36px; flex-wrap: nowrap; }
  #cellMat, #cellMag, #cellClock { height: 36px; }
  #cellSup, #cellCtl, #cellChain, #cellSat, #cellDom, #topbar .link { display: none; }
  #topbar .strip #btnDoctrine, #topbar .strip #btnStrike { display: none; }
  #topbar .strip { height: 36px; }

  #mission { top: 42px; max-height: 96px; }
  #notify { top: 42px; }
  #coach { top: 42px; max-height: 52vh; }
  /* The bar is 36 px here, not 68, so the measured offset starts from 42. */
  #hud:has(#coach:not([hidden])) #notify { top: calc(42px + var(--coach-h, 100px) + 6px); }
  #overlays { top: 42px; }
  #matchover { top: 42px; }
  #minimap { bottom: 92px; }
  #tray { display: none; }
  #selpanel { height: 38px; bottom: 52px; }
  #card { height: 52px; }
  .slot { height: 44px; }
  #touchMode { bottom: 98px; height: 34px; }
  #tip { bottom: 98px; }
}
