/* ==========================================================================
   mobile.css — Chinar on a phone.
   Loaded AFTER the <style> blocks in walk.html, so plain id selectors win.

   Written 29.09.2026. Everything here was measured on an emulated 375x812
   and 812x375 viewport in Chromium. NOTHING here has been checked on a real
   iPhone — see the note on safe areas below.

   🔴 Every selector inside the media blocks is prefixed with `html `. That is
   not decoration: the <link> to this file sits on line 11 of walk.html, ABOVE
   its own <style> blocks (lines 12-227 and 303-340). With equal specificity
   the later rule wins, so without the prefix walk.html overrides this entire
   file and only the !important rules survive — measured: the dev row came
   back on top of both joysticks. The `html ` prefix lifts each selector one
   type-selector above walk.html's plain #id rules, so the file works from
   wherever it is linked. If the <link> is ever moved below line 340, the
   prefix becomes unnecessary but stays harmless.

   Three layouts:
     phone portrait  — (max-width: 520px)
     tablet          — (min-width: 521px) and (max-width: 900px) and (min-height: 501px)
     phone landscape — (max-height: 500px)   <- last, so it wins over the two above

   Landscape is keyed on HEIGHT, not width: an iPhone on its side is 812 points
   wide, so every width-based phone rule in walk.html silently switches off there
   and the desktop layout gets squeezed into 375 points of height.
   ========================================================================== */

:root{
  /* walk.html declares viewport-fit=cover (added 29.09), so on a real iPhone
     these carry the true insets. In desktop-browser emulation they still
     report 0px, which is why every rule below is written as
     calc(<base> + env(...)): the base alone holds the layout at zero, and
     the inset widens it on the device without anything else changing. */
  --sa-t: env(safe-area-inset-top, 0px);
  --sa-r: env(safe-area-inset-right, 0px);
  --sa-b: env(safe-area-inset-bottom, 0px);
  --sa-l: env(safe-area-inset-left, 0px);

  --tap: 44px;          /* smallest touchable height */
}

/* iOS inflates body text in landscape unless told not to. */
html{ -webkit-text-size-adjust: 100%; }


/* ==========================================================================
   1. PHONE, PORTRAIT
   ========================================================================== */
@media (max-width: 520px){

  /* --- top strip -------------------------------------------------------
     The five pills wrapped onto three rows (120px tall) and the third row
     ran underneath #card. Dropping the keyboard hint — which tells a phone
     player to use WASD and a mouse — takes the strip back to two rows. */
  html #p-help{ display: none !important; }

  html #hud{
    padding: calc(7px + var(--sa-t)) calc(10px + var(--sa-r)) 7px calc(10px + var(--sa-l));
    gap: 6px;
  }
  html #hud .pill{ font-size: 11px; padding: 4px 9px; }

  /* --- player card: clear of the pills, clear of the right column ------ */
  html #card{
    top: calc(82px + var(--sa-t));
    left: calc(10px + var(--sa-l));
    max-width: min(60vw, 210px);
    font-size: 11.5px;
    line-height: 1.5;
    padding: 8px 10px;
  }

  /* --- right column: minimap -> map view -> board buttons --------------
     They are stacked in this order and none of them may reach the right
     joystick. Heights below are what make that true. */
  html #minimap{
    width: 84px; height: 84px;
    top: calc(80px + var(--sa-t));
    right: calc(10px + var(--sa-r));
  }

  /* #back carries an inline style attribute, so it only moves with !important */
  html #back{
    top: calc(172px + var(--sa-t)) !important;
    right: calc(10px + var(--sa-r)) !important;
    padding: 9px 14px !important;
    font-size: 12px !important;
    line-height: 1.2 !important;
    display: inline-flex !important;
    align-items: center !important;
    min-height: var(--tap) !important;
  }

  html #board-open{
    top: calc(220px + var(--sa-t));
    right: calc(10px + var(--sa-r));
    /* Stops above the "talk to ..." prompt (#near, 484..528), which is the
       lowest thing that can share this band. The column scrolls, so a
       shorter column costs nothing. */
    bottom: calc(336px + var(--sa-b));
    max-width: 64vw;
    gap: 8px;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    justify-content: flex-start;
  }
  html #board-open::-webkit-scrollbar{ display: none; }
  html #board-open .bb{
    min-height: var(--tap);
    display: flex; align-items: center;
    padding: 10px 15px;
    font-size: 13px;
    flex: 0 0 auto;
  }

  /* --- incoming video: off the minimap, down the left side -------------
     #faces and #talkui are styled by the SECOND <style> block, which sits
     in the body — after the <link> in the head. !important, so this file
     wins wherever the link is put. */
  html #faces{
    top: calc(184px + var(--sa-t)) !important;
    left: calc(10px + var(--sa-l)) !important;
    right: auto !important;
  }
  html #faces video{ width: 104px !important; }
  html #faces.big video{ width: min(78vw, 300px) !important; }

  /* --- action row ------------------------------------------------------
     Sits above the joysticks, scrolls if there are more buttons than fit,
     and every button is a real 44pt target instead of 32. */
  html #acts{
    bottom: calc(168px + var(--sa-b));
    left: calc(6px + var(--sa-l));
    right: calc(6px + var(--sa-r));
    gap: 8px;
    max-height: 104px;
    padding: 0 4px;
    align-content: flex-end;
  }
  html #acts button{
    min-height: var(--tap);
    padding: 11px 16px;
    font-size: 13px;
  }

  /* --- second row: gone -------------------------------------------------
     MEASURED: elementFromPoint at the dead centre of BOTH joysticks
     (76,736) and (299,736) returned a #devbar button — "pause time" and
     "to the gates". Putting a thumb on the stick to walk pressed a dev
     button instead. The row is developer tooling; on a phone it costs the
     joysticks, so it goes.
     Escape hatch: add class="dev" to <body> and it comes back as a compact
     strip under the top pills, away from the sticks. */
  html #devbar{ display: none; }
  html body.dev #devbar{
    display: flex;
    bottom: auto;
    top: calc(80px + var(--sa-t));
    left: calc(120px + var(--sa-l));
    right: calc(104px + var(--sa-r));
    gap: 4px;
    opacity: .85;
    max-height: 76px;
    overflow-y: auto;
    scrollbar-width: none;
  }
  html body.dev #devbar::-webkit-scrollbar{ display: none; }
  html body.dev #devbar button{ min-height: 30px; font-size: 10px; padding: 4px 8px; }

  /* --- joysticks -------------------------------------------------------
     Lifted off the bottom edge so the home-indicator band is not part of
     the stick, and so the event log no longer covers their lower rim. */
  html #stick{
    left: calc(14px + var(--sa-l));
    bottom: calc(38px + var(--sa-b));
    width: 118px; height: 118px;
  }
  html #look{
    right: calc(14px + var(--sa-r));
    bottom: calc(38px + var(--sa-b));
    width: 118px; height: 118px;
  }
  html #knob, html #lknob{ left: 39px; top: 39px; }

  /* --- event log -------------------------------------------------------
     MEASURED: the log is painted after #stick, so it sat on top of the
     bottom 22px of the left joystick and swallowed that touch. It is read
     -only text and must never take a tap. */
  html #log{
    pointer-events: none;
    max-height: 22px;
    padding: 2px calc(12px + var(--sa-r)) calc(4px + var(--sa-b)) calc(12px + var(--sa-l));
    font-size: 11px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }

  /* --- the reload banner ------------------------------------------------
     #stale is built in walk.html with an inline style attribute
     (left:50%;top:14px;transform), so every property needs !important.
     At the top it covered the phase pill and, because it sits at z-60
     over the full-screen scenes, the scene title as well. Moved to the
     bottom strip: below both joysticks, over the ambient event log,
     which is the cheapest thing on this screen to hide for a moment. */
  html #stale{
    top: auto !important;
    bottom: calc(0px + var(--sa-b)) !important;
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    max-width: calc(100vw - 24px) !important;
    /* 36, not the usual 44: the strip between the bottom of the joysticks
       (774) and the screen edge (812) is 38 points, and the banner must not
       bite into the walk control the way the dev row used to. It is 188
       wide, so the target is still comfortable. */
    min-height: 36px !important;
    /* one line, or the text wraps to two and the box grows to 43px, which
       is 5px into the joysticks again */
    white-space: nowrap !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
    padding: 6px 15px !important;
    font-size: 12px !important;
    line-height: 1.2 !important;
  }

  /* --- the "enter / talk" prompt: above the action row ------------------ */
  html #near{
    bottom: calc(284px + var(--sa-b));
    min-height: var(--tap);
    display: none;              /* the script switches this to block */
    align-items: center;
    padding: 10px 16px;
    font-size: 13px;
    max-width: 88vw;
    text-align: center;
  }

  /* --- scenes: a page, not a window ------------------------------------
     MEASURED on the blur card: sheet scrollHeight 964 against clientHeight
     713, and on the assembly 1114 against 713 — the only action button
     ("Step into this life", "Say the name out loud") was 250-400px below
     the fold inside a 20px-inset box with a hairline scrollbar. Full
     screen, one scroll surface, and the sheet ends above the home bar. */
  html #scene,
  html #scene.blur{
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
    background: #0d0c0bf7;
  }
  html #scene .sheet,
  html #scene.blur .sheet{
    max-width: none;
    width: 100%;
    height: 100%;
    max-height: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: calc(18px + var(--sa-t)) calc(18px + var(--sa-r))
             calc(28px + var(--sa-b)) calc(18px + var(--sa-l));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  /* The board is the one scene you are meant to read while still walking
     (its container keeps pointer-events:none). Full screen would take the
     town away, so on a phone it becomes a bottom sheet: full width, above
     the action row, never over the pills, the card or the minimap. */
  html #scene.board{
    /* 284 = the action row's bottom offset (168) plus its height (104)
       plus a gap, so the board never lands on the buttons. */
    padding: 0 calc(10px + var(--sa-r)) calc(284px + var(--sa-b)) calc(10px + var(--sa-l));
    align-items: flex-end;
    justify-content: center;
    background: none;
  }
  html #scene.board .sheet{
    width: 100%;
    max-width: none;
    /* opaque: at 95% the street showed through the board text, and the
       sticky action bar's solid background did not match the sheet */
    background: #141210;
    height: auto;
    /* 470 = everything reserved above (card/minimap) and below (acts,
       sticks, log). Keeps the card and the pills uncovered at any height. */
    max-height: calc(100vh - 470px - var(--sa-t) - var(--sa-b));
    border-radius: 14px;
    padding: 16px 16px 18px;
    box-shadow: 0 10px 40px #000b;
  }

  /* 🔴 A board that asks you to PICK A PERSON is a decision screen, not
     something you read while walking. Saturday's bazaar is marked
     mode:"board" but carries 7 rows, up to 20 names and 3 actions —
     measured in the 342px bottom sheet: 409px hidden and all three
     buttons, "Give your voice" among them, at y 662..871, outside both
     the sheet and the screen. Those boards go full screen like any
     other decision. Boards with no name list stay the compact sheet. */
  html #scene.board:has(#sc-people button){
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
    background: #0d0c0bf7;
  }
  html #scene.board:has(#sc-people button) .sheet{
    height: 100%;
    max-height: none;
    border-radius: 0;
    box-shadow: none;
    padding: calc(18px + var(--sa-t)) calc(18px + var(--sa-r))
             calc(28px + var(--sa-b)) calc(18px + var(--sa-l));
  }
  /* long board: label over value again, like the full-screen scenes */
  html #scene.board:has(#sc-people button) #sc-rows .r{
    flex-direction: column; gap: 0; margin-bottom: 7px;
  }
  html #scene.board:has(#sc-people button) #sc-rows .k{ font-size: 11px; letter-spacing: .04em; }
  html #scene.board:has(#sc-people button) #sc-rows .v{ text-align: left; }

  html #scene h1{ font-size: 21px; letter-spacing: .1em; }
  html #scene .lead{ font-size: 13.5px; margin-bottom: 14px; }

  /* Label above value. Right-aligned values were wrapping into five ragged
     lines on the blur card ("How it works", "You are known as"). */
  html #sc-rows{ font-size: 13px; line-height: 1.5; padding: 10px 12px; }
  html #sc-rows .r{ flex-direction: column; gap: 0; margin-bottom: 7px; }
  html #sc-rows .r:last-child{ margin-bottom: 0; }
  html #sc-rows .k{ font-size: 11px; letter-spacing: .04em; }
  html #sc-rows .v{ text-align: left; }

  /* ...but a board's values are two or three characters ("day", "19") and
     its height is rationed, so there the label and value stay on one line. */
  html #scene.board #sc-rows .r{ flex-direction: row; gap: 10px; margin-bottom: 2px; }
  html #scene.board #sc-rows .k{ font-size: 13px; letter-spacing: normal; }
  html #scene.board #sc-rows .v{ text-align: right; }

  /* Names and blurs: thumb-sized, capped, scrolling inside themselves
     without dragging the page along. */
  html #sc-people{ gap: 8px; max-height: 44vh; overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    align-content: flex-start; }
  html #sc-people button{
    min-height: var(--tap);
    padding: 10px 14px;
    font-size: 14px;
  }
  html #sc-people button .n{ font-size: 11px; }

  html #sc-choices{ gap: 8px; max-height: 42vh;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    align-content: flex-start; }
  html #sc-choices button{
    min-height: var(--tap);
    padding: 10px 13px;
    font-size: 13.5px;
  }

  /* The decision stays in reach. On the assembly the sheet scrolls 560px
     past the fold, and "Say the name out loud" was the last thing on it —
     you had to scroll a list of twenty names to find the button you came
     for. Sticky to the bottom of the sheet instead. Not applied inside a
     board: a board is short and has no fold. */
  html #scene #sc-actions:not(:empty){
    position: sticky;
    bottom: 0;
    z-index: 2;
    padding: 12px 0 4px;
    background: linear-gradient(#14121000, #141210 18%, #141210);
    /* A sticky element is clamped to its container's CONTENT box, so it
       stops short of the sheet's bottom padding and the list showed
       through under the buttons. The shadow is a solid block that fills
       that strip and is clipped by the sheet's own overflow. */
    box-shadow: 0 calc(34px + var(--sa-b)) 0 0 #141210;
  }
  html #sc-actions{ gap: 9px; }
  html #sc-actions button{ min-height: 48px; font-size: 15px; padding: 12px; }
  /* 16px is not a taste call: below it iOS zooms the page in on focus. */
  html #sc-actions .ask input,
  html #sc-actions .ask textarea{ font-size: 16px; padding: 11px 13px; }
  html #scene .fine{ font-size: 11.5px; }

  /* --- talk panel: off the joysticks ----------------------------------- */
  html #talkui{
    bottom: calc(160px + var(--sa-b)) !important;
    top: auto !important;
    left: calc(8px + var(--sa-l)) !important;
    right: calc(8px + var(--sa-r)) !important;
    width: auto !important;
    max-height: calc(100vh - 330px - var(--sa-b) - var(--sa-t)) !important;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  html #talkui .vbtn{ min-height: 38px; }
  html #talkui .vbtn.big{ min-height: var(--tap); font-size: 14px; }

  /* --- the film ---------------------------------------------------------
     MEASURED: #fl-cap scrollHeight equalled clientHeight exactly (187/187)
     on a three-line caption — the next longer sentence clips silently, and
     the "who" line finished 26px from the bottom of the screen, i.e. inside
     the home-indicator band. Taller bar, bottom padding, bigger type. */
  html #film .bar.bot{ height: calc(33vh + var(--sa-b)); }
  html #film .cap{
    height: calc(33vh + var(--sa-b));
    padding: 14px calc(18px + var(--sa-r)) calc(16px + var(--sa-b))
                   calc(18px + var(--sa-l));
    gap: 6px;
    overflow: hidden;
  }
  html #film .line{ font-size: 18px; line-height: 1.34; }
  html #film .eyebrow{ font-size: 10.5px; letter-spacing: .16em; }
  html #film .cam{ font-size: 12px; }
  html #film .who{ font-size: 11.5px; }
  html #film .track{ bottom: calc(33vh + var(--sa-b)); }
  html #film .ctl{
    right: calc(14px + var(--sa-r));
    bottom: calc(33vh + var(--sa-b) + 12px);
    gap: 8px;
  }
  html #film .ctl button{ min-height: var(--tap); padding: 11px 16px; font-size: 14px; }
  html #film .count{
    right: calc(16px + var(--sa-r));
    top: calc(11vh + 12px + var(--sa-t));
    font-size: 11px;
  }
  html #film .bar.top{ height: calc(11vh + var(--sa-t)); }

  /* --- day card ---------------------------------------------------------
     No padding on #daycard itself: #dc-art is an absolutely positioned
     canvas on inset:0, and padding on the parent would shrink it and leave
     bars down the sides. The text is centred, so it never nears an edge. */
  html #dc-day{
    font-size: clamp(26px, 8.2vw, 34px);
    letter-spacing: .2em;
    margin-right: -.2em;
    max-width: 92vw;
    text-align: center;
    line-height: 1.15;
  }
  html #dc-sub{ font-size: 15.5px; max-width: 86vw; line-height: 1.45; }
  html #dc-bar{ width: min(220px, 62vw); }

  /* --- entry screen ------------------------------------------------------
     menu.js injects its stylesheet at runtime, after this file, so the
     .bsm-* rules need !important to land. */
  html #enter{
    padding: calc(20px + var(--sa-t)) calc(18px + var(--sa-r))
             calc(20px + var(--sa-b)) calc(18px + var(--sa-l));
    align-items: flex-start;
  }
  html #enter .sheet{
    max-width: none; width: 100%;
    max-height: 100%;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 20px 18px;
  }
  /* 🔴 Scoped to .sheet, as walk.html now is. Unscoped, `#enter h1` and
     `#enter button` also match the LIVE menu's .bsm-title / .bsm-enter —
     an id beats a class, so my rules were overriding menu.js: the title
     rendered at 22px where .bsm-title asks for clamp(32px,7.6vw,72px).
     Measured before this fix: 22px. My mistake, not theirs. */
  html #enter .sheet h1{ font-size: 22px; }
  html #enter .sheet button{ min-height: 48px; font-size: 15px; }
  html #enter .sheet li{ margin: 9px 0; }

  /* menu.js owns the look of this screen and is being reworked in parallel —
     only the two things that are about the phone, not the design, are set
     here: the tap target floor and the home-indicator clearance. */
  html .bsm-enter{ min-height: var(--tap) !important; }
  html .bsm-foot{
    bottom: calc(20px + var(--sa-b)) !important;
    padding: 0 16px !important;
  }
}


/* ==========================================================================
   2. TABLET  (min-height guard keeps a landscape phone out of this block)
   ========================================================================== */
@media (min-width: 521px) and (max-width: 900px) and (min-height: 501px){

  html #hud{ padding: calc(9px + var(--sa-t)) calc(12px + var(--sa-r)) 9px calc(12px + var(--sa-l)); }
  html #card{ top: calc(84px + var(--sa-t)); left: calc(12px + var(--sa-l)); }

  html #minimap{ top: calc(84px + var(--sa-t)); right: calc(12px + var(--sa-r)); }
  html #back{ top: calc(212px + var(--sa-t)) !important; right: calc(12px + var(--sa-r)) !important;
         min-height: var(--tap) !important; display: inline-flex !important;
         align-items: center !important; padding: 9px 14px !important; }

  html #board-open{
    top: calc(260px + var(--sa-t));
    right: calc(12px + var(--sa-r));
    bottom: calc(272px + var(--sa-b));
    max-width: 44vw;
    gap: 8px;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    justify-content: flex-start;
  }
  html #board-open .bb{ min-height: var(--tap); display: flex; align-items: center;
                   padding: 10px 16px; flex: 0 0 auto; }

  /* stack from the bottom edge up: log 40, sticks 46+116, devbar, acts */
  html #acts{ bottom: calc(216px + var(--sa-b)); gap: 8px; }
  html #acts button{ min-height: var(--tap); padding: 11px 17px; font-size: 13px; }

  html #devbar{ bottom: calc(172px + var(--sa-b)); gap: 6px; opacity: .6; }
  html #devbar button{ min-height: 34px; padding: 7px 13px; font-size: 11px; }

  html #stick{ left: calc(20px + var(--sa-l)); bottom: calc(48px + var(--sa-b)); }
  html #look{ right: calc(20px + var(--sa-r)); bottom: calc(48px + var(--sa-b)); }

  html #log{ pointer-events: none;
        padding: 6px calc(14px + var(--sa-r)) calc(6px + var(--sa-b)) calc(14px + var(--sa-l)); }

  html #near{ bottom: calc(272px + var(--sa-b)); min-height: var(--tap);
         align-items: center; padding: 10px 16px; }

  html #scene .sheet{
    max-height: calc(100vh - 40px - var(--sa-t) - var(--sa-b));
    padding: 22px 24px calc(24px + var(--sa-b));
  }
  html #sc-people button, html #sc-choices button{ min-height: var(--tap); padding: 10px 14px; }
  html #sc-actions button{ min-height: 48px; }
  html #sc-actions .ask input, html #sc-actions .ask textarea{ font-size: 16px; }
  html #board-open .bb, html #acts button{ font-size: 13px; }

  html #film .cap{ padding-bottom: calc(16px + var(--sa-b)); }
  html #film .ctl button{ min-height: var(--tap); }
}


/* ==========================================================================
   3. PHONE, LANDSCAPE — keyed on height, so it also catches an 812-wide
   iPhone on its side, where every max-width rule above has switched off.
   Declared last so it overrides both blocks above.
   ========================================================================== */
@media (max-height: 500px){

  /* one row of pills, and the keyboard hint still has no business here */
  html #p-help{ display: none !important; }
  html #hud{
    padding: calc(5px + var(--sa-t)) calc(10px + var(--sa-r)) 5px calc(10px + var(--sa-l));
    gap: 5px;
    flex-wrap: nowrap;
    overflow: hidden;
  }
  html #hud .pill{ font-size: 11px; padding: 3px 9px; white-space: nowrap; }

  html #card{
    top: calc(46px + var(--sa-t));
    left: calc(10px + var(--sa-l));
    max-width: min(38vw, 190px);
    max-height: 40vh;
    overflow: hidden;
    font-size: 10.5px;
    line-height: 1.45;
    padding: 7px 9px;
  }

  html #minimap{
    width: 70px; height: 70px;
    top: calc(42px + var(--sa-t));
    right: calc(10px + var(--sa-r));
  }
  html #back{
    top: calc(118px + var(--sa-t)) !important;
    right: calc(10px + var(--sa-r)) !important;
    min-height: 36px !important;
    padding: 8px 12px !important;
    font-size: 11px !important;
    display: inline-flex !important;
    align-items: center !important;
  }

  /* MEASURED at 812x375: the board column ran from y=240 to y=408 on a
     375-tall screen — the fourth button ("Your own week") was 33px past
     the bottom edge and could not be reached at all. Now it is boxed
     between the map-view link and the action row, and it scrolls. */
  html #board-open{
    top: calc(158px + var(--sa-t));
    right: calc(10px + var(--sa-r));
    bottom: calc(132px + var(--sa-b));
    max-width: 34vw;
    gap: 6px;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    justify-content: flex-start;
  }
  html #board-open::-webkit-scrollbar{ display: none; }
  html #board-open .bb{
    min-height: 40px;
    display: flex; align-items: center;
    padding: 9px 13px;
    font-size: 12px;
    flex: 0 0 auto;
  }

  html #faces{ top: calc(120px + var(--sa-t)) !important;
          left: calc(10px + var(--sa-l)) !important; right: auto !important; }
  html #faces video{ width: 92px !important; }

  /* Joysticks hug the short edges; the action row lives in the gap
     between them and never underneath. */
  html #stick{
    left: calc(14px + var(--sa-l));
    bottom: calc(24px + var(--sa-b));
    width: 100px; height: 100px;
  }
  html #look{
    right: calc(14px + var(--sa-r));
    bottom: calc(24px + var(--sa-b));
    width: 100px; height: 100px;
  }
  html #knob, html #lknob{ left: 30px; top: 30px; width: 40px; height: 40px; }

  html #acts{
    bottom: calc(28px + var(--sa-b));
    left: calc(132px + var(--sa-l));
    right: calc(132px + var(--sa-r));
    gap: 7px;
    max-height: 96px;
    align-content: flex-end;
    padding: 0;
  }
  html #acts button{ min-height: 40px; padding: 9px 14px; font-size: 12.5px; }

  html #devbar{ display: none; }
  html body.dev #devbar{
    display: flex;
    bottom: auto;
    top: calc(40px + var(--sa-t));
    left: calc(210px + var(--sa-l));
    right: calc(96px + var(--sa-r));
    gap: 4px;
    max-height: 60px;
    overflow-y: auto;
    opacity: .85;
    scrollbar-width: none;
  }
  html body.dev #devbar button{ min-height: 26px; font-size: 10px; padding: 3px 7px; }

  html #log{
    pointer-events: none;
    max-height: 20px;
    left: calc(132px + var(--sa-l));
    right: calc(132px + var(--sa-r));
    text-align: center;
    padding: 2px 0 calc(3px + var(--sa-b));
    font-size: 10.5px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    background: none;
  }

  /* In landscape the bottom belongs to the sticky action bar — measured on
     Saturday's bazaar, the banner sat across "Step out of the crowd". The
     top-right corner is the only place that is free both in the world (the
     pills end well short of it) and inside a scene (titles are left-aligned). */
  html #stale{
    top: calc(4px + var(--sa-t)) !important;
    bottom: auto !important;
    left: auto !important;
    right: calc(10px + var(--sa-r)) !important;
    transform: none !important;
    max-width: 46vw !important;
    min-height: 32px !important;
    white-space: nowrap !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 5px 13px !important;
    font-size: 11px !important;
  }

  html #near{
    bottom: calc(136px + var(--sa-b));
    min-height: 40px;
    align-items: center;
    padding: 9px 15px;
    font-size: 12.5px;
    max-width: 60vw;
    text-align: center;
  }

  /* A 375-point-tall sheet has no room for a margin: every scene goes
     edge to edge and scrolls, boards included. */
  html #scene,
  html #scene.blur,
  html #scene.board{
    padding: 0;
    align-items: stretch;
    justify-content: stretch;
    background: #0d0c0bf7;
  }
  html #scene .sheet,
  html #scene.blur .sheet,
  html #scene.board .sheet{
    max-width: none;
    width: 100%;
    height: 100%;
    max-height: none;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    padding: calc(14px + var(--sa-t)) calc(20px + var(--sa-r))
             calc(18px + var(--sa-b)) calc(20px + var(--sa-l));
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }
  html #scene h1{ font-size: 19px; margin-bottom: 4px; }
  html #scene .lead{ font-size: 13px; margin-bottom: 10px; }

  /* Wide and short: put the value back beside its label and let the lists
     run in columns, so the page is short enough to be worth scrolling. */
  html #sc-rows{ font-size: 12.5px; line-height: 1.45; padding: 8px 12px; margin-bottom: 10px; }
  html #sc-rows .r{ flex-direction: row; gap: 14px; }
  html #sc-rows .v{ text-align: right; }

  html #sc-people{ gap: 7px; max-height: 38vh; overflow-y: auto;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    align-content: flex-start; margin-bottom: 10px; }
  html #sc-people button{ min-height: 40px; padding: 9px 13px; font-size: 13px; }

  html #sc-choices{ gap: 7px; max-height: 38vh;
    overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
    align-content: flex-start; margin-bottom: 10px; }
  html #sc-choices button{ min-height: 40px; padding: 9px 12px; font-size: 12.5px; }

  html #scene #sc-actions:not(:empty){
    position: sticky;
    bottom: 0;
    z-index: 2;
    padding: 10px 0 4px;
    background: linear-gradient(#14121000, #141210 18%, #141210);
    box-shadow: 0 calc(24px + var(--sa-b)) 0 0 #141210;
  }
  /* ...unless the scene also asks for typed words. A two-row field plus
     two buttons is 150 of the 375 points this screen has, and the list of
     names behind it shrank to a single half-visible row. There the actions
     go back into the flow and you scroll to them. */
  html #scene #sc-actions:has(.ask){
    position: static;
    background: none;
    box-shadow: none;
    padding: 0;
  }
  html #sc-actions{ flex-direction: row; flex-wrap: wrap; gap: 8px; }
  html #sc-actions .ask{ flex: 1 1 100%; }
  html #sc-actions .ask input, html #sc-actions .ask textarea{ font-size: 16px; }
  html #sc-actions button{ flex: 1 1 200px; width: auto; min-height: 44px; font-size: 14px; padding: 10px; }

  html #talkui{
    top: calc(44px + var(--sa-t)) !important;
    bottom: auto !important;
    left: auto !important;
    right: calc(120px + var(--sa-r)) !important;
    width: min(46vw, 320px) !important;
    max-height: calc(100vh - 120px - var(--sa-t) - var(--sa-b)) !important;
    overflow-y: auto;
  }
  html #talkui .vbtn.big{ min-height: 40px; }

  /* 23vh of a 375-tall screen is 86px — the caption did not fit in it.
     Fixed pixel bars instead of viewport percentages. */
  html #film .bar.top{ height: calc(24px + var(--sa-t)); }
  html #film .bar.bot{ height: calc(126px + var(--sa-b)); }
  html #film .cap{
    height: calc(126px + var(--sa-b));
    padding: 10px calc(22px + var(--sa-r)) calc(12px + var(--sa-b))
                   calc(22px + var(--sa-l));
    gap: 3px;
    overflow: hidden;
  }
  html #film .line{ font-size: 16px; line-height: 1.3; max-width: none; }
  html #film .eyebrow{ font-size: 10px; }
  html #film .cam{ font-size: 11.5px; }
  html #film .who{ font-size: 11px; }
  html #film .track{ bottom: calc(126px + var(--sa-b)); }
  html #film .ctl{
    right: calc(16px + var(--sa-r));
    bottom: calc(126px + var(--sa-b) + 10px);
    gap: 7px;
  }
  html #film .ctl button{ min-height: 40px; padding: 10px 15px; font-size: 13px; }
  html #film .count{ right: calc(16px + var(--sa-r)); top: calc(30px + var(--sa-t)); }

  html #dc-day{ font-size: clamp(22px, 5.2vw, 34px); letter-spacing: .18em;
           margin-right: -.18em; max-width: 92vw; text-align: center; }
  html #dc-sub{ font-size: 13.5px; max-width: 70vw; }
  html #dc-bar{ width: min(200px, 40vw); }

  html #enter{
    padding: calc(14px + var(--sa-t)) calc(18px + var(--sa-r))
             calc(14px + var(--sa-b)) calc(18px + var(--sa-l));
    align-items: flex-start;
  }
  html #enter .sheet{ max-width: none; width: 100%; max-height: 100%;
                 overflow-y: auto; -webkit-overflow-scrolling: touch;
                 padding: 16px 18px; }
  html #enter .sheet h1{ font-size: 20px; margin-bottom: 4px; }
  html #enter .sheet ul{ margin: 10px 0; }
  html #enter .sheet li{ margin: 5px 0; font-size: 13px; }
  html #enter .sheet .lead{ font-size: 13px; margin-bottom: 10px; }
  html #enter .sheet button{ min-height: 44px; font-size: 14px; }

  /* Landscape is the one place the entry screen genuinely does not fit:
     9vh of top padding plus title, rule, sub and button on a 375-tall
     screen. Tightened, and the footer lifted off the indicator. */
  html .bsm-core{ padding-top: 5vh !important; }
  html .bsm-enter{ min-height: 42px !important; margin-top: 16px !important; }
  html .bsm-sub{ margin-top: 10px !important; }
  html .bsm-foot{ bottom: calc(8px + var(--sa-b)) !important; }
}


/* ==========================================================================
   4. Coarse pointer, any size — things that are about the finger, not the
   screen. A tap must not leave a grey flash box, and a long press on a
   joystick must not raise the iOS text-selection loupe.
   ========================================================================== */
@media (pointer: coarse){
  html button, html .pill, html #board-open .bb, html #near, html #back, html .vbtn{
    -webkit-tap-highlight-color: transparent;
  }
  html #stick, html #look, html #knob, html #lknob{
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
  }
}
