/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Phase 3 — shared mobile baseline (consolidation of prior
   per-app passes + the five Phase 3 spec guarantees below).

   The five contracts every shell + bundle must honour on
   phone-sized viewports:
     (a) no horizontal scroll anywhere
     (b) tap targets ≥ 44 × 44 (WCAG 2.5.5)
     (c) primary CTA reachable without scroll
     (d) no font-size < 14 px on touch (16 on inputs)
     (e) no console errors fired by touchstart / pointer events

   This file loads LAST (via index.html + standalone pages)
   so equal-specificity !important rules here win cleanly.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

/* (a) — no horizontal scroll: hard guard on root containers.
   Apps that overflow get clipped (not scrolled) so a stray
   wide table can't break the whole layout into a sideways
   gesture trap. Per-app rules below handle the wide-content
   cases explicitly (FlashBook preview grid, leads filters). */
@media (max-width: 640px) {
  html, body { overflow-x: hidden; max-width: 100vw; }
  /* Common app shells — defensive width caps so nested grids
     can't blow out the viewport. */
  .ap-canvas, .fb-canvas, .settings-canvas, .sites-canvas,
  .cs-canvas, .cb-canvas, .records-canvas, .staxbox-canvas,
  .forms-canvas {
    max-width: 100vw;
    overflow-x: auto;     /* horizontal scroll allowed INSIDE the canvas only */
  }
  /* Inputs/selects must never exceed the canvas width — common
     overflow source on per-app forms. */
  input, select, textarea {
    max-width: 100%;
    box-sizing: border-box;
  }
}

/* (b) tap-target floor (44×44, WCAG 2.5.5) — applied below in
   the existing (pointer: coarse) block. Phase 3 confirms the
   contract; no new rules needed. */

/* (c) primary CTA reachability — make sure the dock or the
   bottom-most action button stays above the soft-keyboard /
   safe-area inset. The existing dock + window chrome rules
   handle the standard case; this catches inline buttons that
   would otherwise be hidden under the home indicator. */
@media (max-width: 640px) {
  .primary-cta, .cta-primary,
  .ap-cta, .cs-cta, .cb-cta,
  button.primary, button[type="submit"] {
    margin-bottom: max(12px, env(safe-area-inset-bottom, 0));
  }
}

/* (d) — minimum readable font size on phones. Per-app default
   text was as low as 11.5 px in admin chat; bump the floor to
   13 px on touch viewports (16 px on inputs is enforced in
   the per-app rules + iOS zoom-guard sections below). */
@media (max-width: 640px) {
  body, .text-sm, .text-xs, .cs-ch-meta, .cb-meta {
    font-size: max(13px, 1em);
  }
}

/* (e) — touch handlers: kill the 300 ms tap delay + scroll-
   chain glitches that have produced "ghost click" console
   errors on Galaxy Fold + iPhone SE. `touch-action: manipulation`
   keeps tap + pan working but disables double-tap zoom. */
@media (pointer: coarse) {
  button, .btn, [role="button"], a.button, a.btn {
    touch-action: manipulation;
  }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Mobile-first polish — Phase F.8
   Targets the 4 apps that previously had zero responsive
   rules (artist-profile, flashbook, settings, sites) plus
   global tap-target + side-card adjustments.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

/* ── Tap-target minimum: WCAG 2.5.5 (44×44) ─────────────── */
@media (pointer: coarse) {
  /* Every visible button & input gets a 44px floor on touch
     devices. Desktop pointer users keep the existing sizing. */
  button, .btn, [role="button"],
  input[type="button"], input[type="submit"], input[type="reset"],
  input[type="checkbox"], input[type="radio"],
  select {
    min-height: 44px;
  }
  /* Pills and chips inside side cards keep their height but
     get more vertical padding so the tap area is ≥44px. */
  .cs-pv-pill, .cb-pill, .fb-pill, .ap-pill,
  .chip, .tag, .pill {
    min-height: 44px;
    padding-top: 10px;
    padding-bottom: 10px;
  }
  /* Strip-card icons (the 56px side strip) are already 44px+
     but make sure their hit area extends to the full row. */
  .sc-strip-btn, .ap-strip-btn {
    min-height: 56px;
  }
}

/* ── Generic phone breakpoint (≤640) ──────────────────── */
@media (max-width: 640px) {
  /* All app side-cards become full-width slide-overs on
     mobile, so they don't fight the canvas for space. The
     window manager already maximizes app windows; this
     completes the pattern for the 4 apps that didn't have
     responsive rules. */
  .ap-card, .settings-card, .sites-card {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    height: 100%;
  }
  /* When a side-card is hidden on mobile, the canvas takes
     the whole viewport. */
  .ap-canvas, .fb-canvas, .settings-canvas, .sites-canvas {
    padding: 16px;
  }

  /* Strip-card layouts: collapse the 56px side strip to icons-
     only on mobile and let the card slide over the canvas. */
  .ap-strip, .settings-strip, .sites-strip {
    width: 52px;
  }

  /* Form fields breathe more on phones (less padding waste). */
  .form-group, .field {
    margin-bottom: 12px;
  }
  .form-group input, .form-group textarea, .form-group select,
  .field input, .field textarea, .field select,
  input[type="text"], input[type="email"], input[type="url"],
  input[type="number"], input[type="tel"], textarea {
    font-size: 16px;  /* 16px prevents iOS Safari zoom-on-focus */
    padding: 12px;
  }

  /* New tab-action chip rows in CS Leads/Inbox: wrap to 2 rows
     instead of overflowing under 380px. */
  .cs-leads-filters, .cs-pv-suggest {
    flex-wrap: wrap;
  }

  /* Logic Deck swipe surface needs the full viewport on mobile,
     not a centered card. */
  .cb-swipe-deck, .cs-swipe-deck {
    width: 100%;
    max-width: 100%;
  }

  /* Toast notifications stack from the bottom on mobile so they
     don't fight the strip card overlay. */
  #staxos-toasts {
    bottom: 80px !important;
    top: auto !important;
    left: 16px;
    right: 16px;
    width: auto !important;
  }
}

/* ── Narrow phone (≤380) — Galaxy Fold inner, iPhone SE 1 ── */
@media (max-width: 380px) {
  /* Drop side strip entirely on the smallest screens; user
     navigates via the dock instead. */
  .ap-strip, .settings-strip {
    display: none;
  }
  /* Cards become flush with viewport edge. */
  .ap-card, .settings-card {
    border-radius: 0;
    border-left: none;
    border-right: none;
  }
  /* Profile section headings shrink a notch. */
  h1, .ap-h1 { font-size: 20px; }
  h2, .ap-h2 { font-size: 16px; }
}

/* ── Public-facing pages (CS widget embed, profile_onboard,
       /p/:slug landing) ─────────────────────────────────── */
@media (max-width: 640px) {
  /* The public CS chat widget should pin to the bottom-right
     and grow to fill the viewport when expanded. */
  .cs-widget-fab { right: 16px !important; bottom: 16px !important; }
  .cs-widget-panel {
    inset: 0 !important;
    border-radius: 0 !important;
    width: 100vw !important;
    height: 100dvh !important;
  }

  /* Profile onboarding form (profile_onboard.html) — single
     column, larger hit targets. */
  .card { padding: 20px !important; max-width: 100% !important; border-radius: 0; }
  .photo-grid { grid-template-columns: repeat(3, 1fr) !important; }
  .photo-slot { min-height: 88px !important; }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Maximized-window offset on mobile — Field fix 2026-05-20 (pt 2)

   Pre-existing cascade bug in window.css:
     • Lines 41-45 (inside @media max-width:768px):
         .os-window.maximized { top: 28px !important; }
     • Lines 59-66 (unconditional, after the @media block):
         .os-window.maximized { top: 0 !important; }
   Same specificity, both !important, later-in-source wins. So on
   mobile the maximized window snaps to top:0 and hides under the
   fixed #menubar (z-index 9000), eating the titlebar's top 28px —
   including the close X.

   Why it surfaced now: my prior fix made the X actually render at
   touch size. The window-occlusion bug was already there; it was
   masked because the X was a 13×13 invisible dot.

   mobile.css loads last, so equal-specificity !important rules
   here win cleanly. Scoped to mobile/touch — desktop untouched.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
@media (max-width: 768px), (pointer: coarse) {
  .os-window.maximized {
    top: var(--os-menubar-h, 28px) !important;
    height: calc(100dvh - var(--os-menubar-h, 28px)) !important;
  }
  /* Non-maximized mobile windows (rare — wm.js auto-maximizes on
     open, but a future tap might toggle) keep the same offset. */
  .os-window {
    top: var(--os-menubar-h, 28px) !important;
  }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Window chrome on touch — Field fix 2026-05-20

   Bug: `window.css` declares `.os-tl-btn { width: 13px; height: 13px }`
   unconditionally and is loaded AFTER `desktop.css`. The mobile
   close-button rules in `desktop.css` (inside `@media (max-width:
   768px)`) lose the cascade to `window.css` and the X never renders
   at touch size. The dock is hidden when a window is open, so on
   mobile the X is the ONLY way out — and it was invisible.

   Fix: replicate the touch-sized close button rules here. `mobile.css`
   is the last stylesheet loaded, so equal-specificity rules here win.
   Scoped to `(max-width: 768px)` AND `(pointer: coarse)` so touch
   tablets in landscape (>768px wide) also get the big tap target.

   Desktop pointer users keep the macOS traffic-light styling
   defined in `window.css`. Untouched.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
@media (max-width: 768px), (pointer: coarse) {
  /* Hide minimize + maximize on touch — windows are fullscreen on
     mobile already, so those controls have no useful action and
     they steal tap space from the close button. */
  .os-tl-minimize,
  .os-tl-maximize { display: none !important; }

  /* Bigger, taller titlebar to fit the WCAG 44px tap target. */
  .os-titlebar {
    height: 48px;
    padding: 0 8px 0 6px;
    padding-top: env(safe-area-inset-top, 0);
  }
  .os-traffic-lights {
    gap: 0;
    margin-right: 6px;
  }

  /* The close button is the only reliable mobile exit (dock is
     hidden when a window is open). Make it 44×44 and ALWAYS
     show the X icon — touch devices have no hover. */
  .os-tl-close {
    width: 44px;
    height: 44px;
    border-radius: 10px;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    flex-shrink: 0;
  }
  .os-tl-close::after {
    content: '';
    position: absolute;
    inset: 4px;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.06);
    pointer-events: none;
    transition: background 120ms ease;
  }
  .os-tl-close:active::after {
    background: rgba(255, 255, 255, 0.14);
  }
  .os-tl-close svg {
    position: static;
    transform: none;
    opacity: 1 !important;
    width: 20px;
    height: 20px;
    stroke: var(--os-text, #e8e4dc);
    stroke-width: 2.2;
    stroke-linecap: round;
    fill: none;
  }
  /* Unfocused window still shows the X — on touch you may not
     have a "focused" indicator and you still need the exit. */
  .os-window:not(.focused) .os-tl-close { background: transparent; }
  .os-window:not(.focused) .os-tl-close svg {
    stroke: var(--os-text-muted, #8a8a8a);
    opacity: 1 !important;
  }

  /* Title text — balance the close button on the left side so the
     centred text doesn't get nudged off-centre. */
  .os-titlebar-text {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.01em;
    padding-right: 44px;
  }

  /* Mobile resize handles are useless on touch — windows are full-
     screen and we never want a 4px-wide edge to be a tap target. */
  .os-resize-handle { display: none !important; }
}

/* ── Native `<select>` zoom guard for iOS Safari ───────────
   The existing 16px font rule covered <input> and <textarea> but
   not <select>; on iOS Safari any form control under 16px font-size
   triggers a zoom-on-focus that scrolls the page sideways and
   doesn't reset cleanly. This adds <select> + datalist parity. */
@media (max-width: 640px) {
  select, input[type="date"], input[type="datetime-local"],
  input[type="time"], input[type="month"], input[type="week"] {
    font-size: 16px;
    padding: 12px;
  }
}

/* ── Accessibility: focus rings on keyboard nav ─────────── */
*:focus-visible {
  outline: 2px solid var(--stax-focus, #c8a44a);
  outline-offset: 2px;
}
button:focus:not(:focus-visible),
input:focus:not(:focus-visible) {
  outline: none;
}

/* ── Prefers-reduced-motion: kill the swipe transforms ──── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Phase 7 — Mobile Deep Pass (per-app zoom-trap + tap-target fixes)

   Each per-app file owns its own input styling and ships at
   12-15px font-size for desktop density. On iOS Safari any
   <input>/<textarea>/<select> rendered below 16px font-size
   triggers a zoom-on-focus that scrolls the page sideways and
   doesn't reset cleanly. mobile.css loads LAST so equal-
   specificity rules here win the cascade.

   No per-app CSS files were modified for these fixes —
   everything stays scoped to mobile breakpoints in this file.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */

@media (max-width: 640px) {
  /* Records app — det-input + rw-input lived at 13px. */
  .det-input, .rw-input {
    font-size: 16px !important;
    padding: 12px !important;
  }

  /* FlashBook — fb-input (12px) and fb-input-sm (12px) both
     trigger the iOS zoom trap. fb-pr-min-input was 15px, still
     under the 16px floor. */
  .fb-input, .fb-input-sm, .fb-pr-min-input {
    font-size: 16px !important;
    padding: 12px !important;
  }

  /* FlashBook modal close button was 28×28 — under WCAG 2.5.5
     (44×44 minimum). The modal opens on touch from "Add Design"
     and is the only exit. */
  .fb-modal-close {
    width: 44px !important;
    height: 44px !important;
    font-size: 22px !important;
    border-radius: 10px !important;
  }

  /* FlashBook preview grid: 3 thumbnails fit at ≥420px but get
     uncomfortably small at 375. Drop to 2 columns on narrow
     phones; the 3-up returns at the next breakpoint. */
  .fb-preview-grid-6 {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}

/* ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   Phase 7.3 — Side-card overlay GPU compositing.

   The off-state for .sc-card collapses via width:0 + opacity:0
   (defined in strip-card.css). On Pixel-class hardware the
   width animation is non-composited and stutters when the
   strip-card swap fires on a tap. Switching to transform-based
   compositing on mobile keeps the same visual but renders on
   the GPU instead of triggering a layout pass.

   Desktop pointer users keep the original width-collapse so
   the canvas reflows immediately when the card closes.
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ */
@media (max-width: 768px) {
  .sc-card {
    /* Will-change hint so the compositor allocates a layer
       upfront. transform-origin keeps the slide pivoting from
       the left edge (where the strip sits). */
    will-change: transform, opacity;
    transform: translate3d(0, 0, 0);
    transition: transform 180ms cubic-bezier(.16,.84,.36,1),
                opacity 140ms ease;
  }
  .sc-card--off {
    /* width:0 stays so the canvas reflows once the slide
       finishes, but the visible motion is the translate. */
    transform: translate3d(-100%, 0, 0) !important;
    opacity: 0;
  }
}
