/* ==========================================================================
   Mobile shell — platform layer, phone-OS presentation of the desktop site.

   CONTRACT: everything below the fold line lives inside
   `@media (max-width: 767px)`. The only rules allowed outside it are the two
   directly below, and both are provably inert on desktop:
     - `.m-only`      hidden by default (mobile-only markup: the dock home
                       button, the topbar hamburger) — the mobile block
                       re-shows it.
     - `.dock-scroll` `display: contents` on desktop, so the wrapper div
                       added around the dock buttons (index.html) is
                       layout-transparent there — the buttons stay direct
                       flex items of `.dock`, exactly as before this file
                       existed. The mobile block turns it into the real
                       horizontal scroller.

   Loaded LAST in <head> (after every component stylesheet) so equal-
   specificity rules here win on source order alone — this is how slack's
   `@media (max-width:900px)` sidebar-hide, and the browser/pllm
   `@container` narrow-window collapses, get overridden for phones without
   touching their own component files' cascade order.

   js/main.js is NOT edited for any of this. Dragging, raise/z-order, the
   genie open/close animation, and the dock's open/reopen/put-away logic
   all keep running unmodified — mobile works by making their *visual*
   effect (the --x/--y/--w custom props, absolute positioning) inert via
   this CSS, not by disabling the JS itself.
   ========================================================================== */

.m-only { display: none; }
.dock-scroll { display: contents; }

@media (max-width: 767px) {

  :root {
    --m-status-h: calc(48px + env(safe-area-inset-top));
    /* The dock no longer peeks and pops — it is permanently, fully visible,
       so these describe its real footprint rather than a sliver of it.
       --m-dock-h is the pill's own height: icon + .dock-scroll's 14px
       padding top and bottom. */
    --m-dock-icon: 36px;
    --m-dock-h: calc(var(--m-dock-icon) + 28px);
    /* Where an app window's bottom edge sits: clear of the dock's whole
       band (pill + its 10px offset) plus a 10px gap, so the wallpaper shows
       through around and behind the dock instead of the app running under
       it. */
    --m-app-bottom: calc(var(--m-dock-h) + 20px + env(safe-area-inset-bottom));
    /* Padding INSIDE an app. It used to have to clear the dock itself; now
       that the window stops above the dock, that job belongs to
       --m-app-bottom and this is just breathing room. Left as a variable
       because eight component stylesheets consume it. */
    --m-bottom-inset: 16px;
    /* Gap between dock icons. .dock-item's flex-basis is derived from it so
       exactly 4.5 icons fill the pill — change one and the other follows. */
    --m-dock-gap: 8px;
  }

  /* ---------- Plum header ----------
     Not a phone status bar (clock/wifi/battery were dropped per user
     feedback): the wordmark on the left with a hairline, a hamburger on
     the right that opens the marketing nav as an accordion sheet. The
     clock keeps ticking into its display:none element — harmless. */
  .topbar {
    height: var(--m-status-h);
    padding: env(safe-area-inset-top) 4px 0 0;
    align-items: center;
    background: var(--os-chrome);
    border-bottom: 1px solid var(--os-line);
    box-sizing: border-box;
    pointer-events: auto; /* the strip is real chrome on a phone */
  }
  .topbar-chip.topbar-icon,
  .topbar-weather,
  .topbar-clock,
  .topbar-nav {
    display: none;
  }
  .topbar-brand {
    display: flex;
    height: 100%;
    padding: 0 16px;
    margin: 0;
    background: transparent;
    border: 0;
    border-right: 1px solid var(--os-line);
    border-radius: 0;
  }
  .topbar-chip.topbar-brand svg { width: 58px; height: auto; }

  /* "Talk to an expert" — the phone-only CTA that fills the gap the hidden
     status cluster leaves. margin-left:auto pushes it (and the hamburger
     after it) to the right, so the wordmark keeps the left edge. The
     hamburger gets the hairline that used to sit at the strip's end, which
     is what separates the two. */
  .topbar-cta {
    display: flex; /* wins over the .m-only base hide by source order */
    align-items: center;
    height: 100%;
    margin-left: auto;
    padding: 0 14px;
    background: none;
    border: 0;
    border-radius: 9px;
    font: inherit;
    font-size: 14px;
    color: #1E1E1E;
    white-space: nowrap;
    pointer-events: auto;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  /* Pressed state: the label picks up a soft chip behind it. Inset so the
     chip floats inside the strip rather than butting the hairlines. */
  .topbar-cta:active {
    background: rgba(0, 0, 0, .07);
    margin-block: 5px;
    height: calc(100% - 10px);
  }

  .topbar-hamburger {
    display: flex; /* wins over the .m-only base hide by source order */
    align-items: center;
    justify-content: center;
    width: 44px;   /* 44px tap target around the 24px glyph */
    height: 100%;
    padding: 0;
    background: none;
    border: 0;
    border-left: 1px solid var(--os-line);
    pointer-events: auto;
    cursor: pointer;
  }
  .topbar-hamburger svg { width: 24px; height: 24px; display: block; }

  /* ---------- Nav sheet (hamburger menu) ----------
     The DESKTOP mega-menu markup (.topbar-nav > .topbar-mm) reused as an
     accordion: js/main.js's existing class-toggling wiring (trigger
     .is-open, Product cats/linksets .is-active, outside-click + Escape)
     keeps working untouched — these rules only re-shape the boxes.
     .topbar.m-nav-open is toggled by js/mobile.js's hamburger handler. */
  .topbar.m-nav-open .topbar-nav {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: var(--m-status-h);
    left: 0;
    right: 0;
    height: auto;
    max-height: calc(100dvh - var(--m-status-h));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    margin: 0;
    padding: 4px 0 12px;
    gap: 0;
    background: var(--os-chrome);
    border: 0;
    border-bottom: 1px solid var(--os-line);
    border-radius: 0 0 14px 14px;
    pointer-events: auto;
    /* DOM-free scrim: a shadow offset a viewport-height down with a
       viewport-sized spread paints from the sheet's bottom edge over the
       whole screen; taps on it fall through to the page and trigger the
       outside-tap close in js/mobile.js. */
    box-shadow: 0 100vmax 0 100vmax rgba(0, 0, 0, .25);
  }

  .topbar.m-nav-open .topbar-mm {
    width: 100%;
    position: relative;
  }
  .topbar.m-nav-open .topbar-mm-trigger {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    font-size: 16px;
    text-align: left;
  }

  /* Panels: floating desktop dropdown -> in-flow accordion body. The
     (0,3,0) specificity here beats the fixed 257.6px/690px widths in
     style.css; style.css's `.topbar-mm.is-open .topbar-mm-panel--*`
     display rules keep driving visibility untouched. */
  .topbar.m-nav-open .topbar-mm-panel {
    position: static;
    width: auto;
    padding: 4px 16px 14px;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  .topbar.m-nav-open .topbar-mm-cols {
    flex-direction: column;
    gap: 10px;
  }
  .topbar.m-nav-open .topbar-mm-cats { width: auto; }

  /* ---------- Home screen ----------
     The topbar, every .window and the dock are all fixed/absolute — the
     .desktop-icon elements are the ONLY in-flow children of .desktop, so
     turning it into a grid is enough to make them a phone-style app grid.
     Their existing tap-vs-drag handler (the 4px guard in js/main.js's
     `.desktop-icon[data-window]` loop) keeps working untouched; `position:
     static` just makes dragging visually inert (the handler still writes
     --x/--y, nothing consumes them any more). */
  .desktop {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    align-content: start;
    gap: 26px 8px;
    padding: calc(var(--m-status-h) + 24px) 16px 120px;
  }
  .desktop-icon {
    position: static !important;
    width: auto !important;
    touch-action: manipulation;
  }
  .desktop-icon svg,
  .desktop-icon img {
    width: auto;
    height: 52px;
    margin: 0 auto;
  }
  .desktop-icon-label { max-width: 100%; }

  /* ---------- Dock ----------
     Two rounded boxes side by side (per the user's mockup): `.dock-home`
     (mobile-only home button, shown only while an app is open) and
     `.dock-scroll` (the horizontally scrolling apps pill). `.dock` itself
     is a TRANSPARENT flex rail carrying only position + the slide
     transform — the chrome lives on the two children. While an app is
     open the whole rail rests as a ~16px peeking sliver at the bottom
     edge; tapping it raises it (js/mobile.js dock controller). Order is
     CSS `order` only — DOM order, and every `.dock-item[data-window]`
     selector main.js/talk.js/pllm.js rely on, stays untouched. */
  .dock {
    position: fixed;
    left: 10px;
    right: 10px;
    bottom: calc(10px + env(safe-area-inset-bottom));
    transform: none;
    height: auto;
    padding: 0;
    align-items: stretch; /* home box matches the pill's height */
    /* No flex gap: the home button's own margin-right supplies the 8px, so
       it can animate to 0 alongside the width and collapse completely. A
       flex gap would survive at width 0 and leave an 8px notch on the home
       screen. */
    gap: 0;
    background: none;     /* chrome moves to the children */
    border: 0;
    border-radius: 0;
    overflow: visible;    /* clipping is .dock-scroll's job */
    transition: transform .25s ease;
  }

  /* Home button. It used to flip display:none <-> flex, so it popped into
     existence and the apps pill snapped to its new width in the same frame.
     Now it stays in the layout at zero width and animates: sliding out from
     under the pill as an app opens, and collapsing back on the way home
     while the pill grows into the space it vacates (the pill is flex:1, so
     that half comes free). visibility is transitioned discretely — held
     until the collapse finishes on the way out, dropped immediately on the
     way in — so a zero-width button is never focusable or hit-testable.
     `overflow: hidden` keeps the icon from spilling out mid-collapse. */
  .dock-home {
    display: flex;        /* laid out always; width carries the state */
    flex: 0 0 auto;
    width: 0;
    margin-right: 0;
    align-items: center;
    justify-content: center;
    padding: 0;
    overflow: hidden;
    opacity: 0;
    visibility: hidden;
    transform: translateX(-8px);
    background: var(--os-chrome);
    border: 1px solid var(--os-line);
    border-width: 0;      /* animates in with the width; see below */
    border-radius: var(--os-radius);
    cursor: pointer;
    transition: width .28s ease, margin-right .28s ease, opacity .18s ease,
                transform .28s ease, visibility 0s linear .28s;
  }
  body.m-app-open .dock-home {
    width: 62px;
    margin-right: 8px;
    opacity: 1;
    visibility: visible;
    transform: none;
    border-width: 1px;
    transition: width .28s ease, margin-right .28s ease, opacity .22s ease .06s,
                transform .28s ease, visibility 0s linear 0s;
  }
  /* Height-driven, width auto: the new house mark is 30x38 (was 26x28), so a
     fixed width/height pair would squash it. */
  .dock-home svg { height: 30px; width: auto; display: block; flex: none; }

  .dock-scroll {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    /* Tightened from 14px so a fifth icon gets far enough into the pill to
       read as half-visible rather than a sliver. .dock-item's flex-basis is
       derived from this, so the two can't drift. */
    gap: var(--m-dock-gap);
    padding: 14px 16px;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    background: var(--os-chrome);
    border: 1px solid var(--os-line);
    border-radius: var(--os-radius);
  }
  .dock-scroll::-webkit-scrollbar { display: none; }

  /* Fades the trailing (5th) icon toward the pill's own background instead
     of clipping it outright — the readable signal that the dock scrolls.
     Two constraints shape this rule: (1) an opaque-to-transparent overlay
     rather than `mask-image`, because this environment's headless renderer
     paints a masked element fully transparent instead of applying the
     gradient; (2) it lives on `.dock`, NOT `.dock-scroll` — an absolutely
     positioned pseudo inside an overflow-x scroller participates in the
     scrollable overflow and would scroll away with the icons. `.dock` has
     no padding, so right:1px sits exactly inside the pill's 1px border;
     the matching inner radius keeps the gradient inside the rounded
     corner. */
  .dock::after {
    content: "";
    position: absolute;
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 46px;
    border-radius: 0 calc(var(--os-radius) - 1px) calc(var(--os-radius) - 1px) 0;
    background: linear-gradient(to right, rgba(245, 244, 240, 0), var(--os-chrome) 80%);
    pointer-events: none;
  }

  /* Exactly four icons and half of the fifth, whatever the pill is wide.
     4.5 items + 4 gaps == 100% by construction, so this holds both on the
     home screen (full-width pill) and with an app open (the home button
     takes 70px off it) — a fixed percentage basis could only ever be right
     for one of those two widths. The half-icon is the scroll affordance;
     .dock::after's gradient fades it at the mask edge. */
  .dock-item {
    flex: 0 0 calc((100% - 4 * var(--m-dock-gap)) / 4.5);
    display: flex;
    justify-content: center;
    align-items: flex-end;
  }
  .dock-item svg { height: var(--m-dock-icon); }
  .dock-item .dock-label { display: none; }
  .dock-item .dot { bottom: -6px; }

  /* Mobile order: Doc, pLLM, Talk fully visible plus Poster; Video is the
     half-icon at the mask edge; Slack/Browser/Folder reachable by scrolling.
     (The Email icon was removed entirely — the asset isn't ready.) */
  .dock-item[data-window="win-doc"]     { order: 1; }
  .dock-item[data-window="win-pllm"]    { order: 2; }
  .dock-item[data-window="win-talk"]    { order: 3; }
  .dock-item[data-window="win-flyer"]   { order: 4; }
  .dock-item[data-window="win-video"]   { order: 5; }
  .dock-item[data-window="win-slack"]   { order: 6; }
  .dock-item[data-window="win-browser"] { order: 7; }
  .dock-item[data-window="win-folder"]  { order: 8; }

  /* The dock is fixed: no lowered/raised states at all. It used to translate
     down to a --m-dock-peek sliver while an app was open and pop back up on
     tap; that is gone, along with the controller in js/mobile.js. The only
     thing m-app-open still changes down here is whether the home button is
     in the row. */

  /* ---------- Full-screen app windows ----------
     `!important` is required: several components size their window on the
     ID (`#win-video{min-width:640px}`, `#win-doc{height:min(80vh,...)}`),
     which outranks any class-level override on specificity alone. */
  .window {
    position: fixed !important;
    top: var(--m-status-h) !important;
    left: 0 !important;
    right: 0 !important;
    bottom: var(--m-app-bottom) !important;
    width: auto !important;
    height: auto !important;
    min-width: 0 !important;
    max-width: none !important;
    min-height: 0 !important;
    max-height: none !important;
    touch-action: auto !important; /* app content must scroll under a finger */
    cursor: default !important;
    border-radius: 0 !important;
  }

  /* Talk is the one modal, not a full-screen app — presented as a bottom
     sheet instead. `centerWindow()` (talk.js) keeps writing px --x/--y;
     they simply have no consumer left once `left/top` are overridden here.
     The sheet floats ABOVE the dock's peeking band (user feedback), so it
     gets full rounding rather than sheet-style top-only corners. */
  #win-talk {
    top: auto !important;
    bottom: var(--m-app-bottom) !important;
    left: 10px !important;
    right: 10px !important;
    height: auto !important;
    max-height: calc(100dvh - var(--m-status-h) - var(--m-app-bottom) - 24px) !important;
    min-height: 0 !important;
  }
  #win-talk .talk-chrome {
    border-radius: 16px;
    height: 100%;
  }

  /* Traffic lights: hidden, per the user ("no use" on a phone), but left
     programmatically clickable — `goHome()` below closes apps by calling
     `.click()` on these same (now invisible) clusters, reusing the
     platform's existing close path with zero js/main.js changes.
     .talk-lights is the one exception (below): the Talk form is a floating
     sheet rather than a full-screen app, so it reads as a dialog that wants
     a visible way out. */
  .pllm-lights, .flyer-lights, .ct-lights, .folder-lights, .vv-lights,
  .br-lights, .win-lights, .doc-dismiss {
    display: none !important;
  }

  /* Phone-only: the Talk sheet keeps its cluster. main.js already wires the
     whole cluster as one close control, so this needs no JS. */
  #win-talk .talk-lights { display: flex !important; }

  /* ---------- Boot entrance ----------
     Overrides the desktop fade in css/style.css: on a phone the app arriving
     from the bottom edge is the native idiom, and the window is full-bleed
     so there is room for the travel to read. */
  @keyframes boot-slide-up {
    from { transform: translateY(14%); opacity: 0; }
    to   { transform: translateY(0);   opacity: 1; }
  }
  .window.is-booting {
    animation: boot-slide-up .38s cubic-bezier(0.22, 0.61, 0.36, 1) both;
    will-change: transform, opacity;
  }
  @media (prefers-reduced-motion: reduce) {
    .window.is-booting { animation: none; }
  }

  /* ---------- Shared off-canvas drawer (consumed by every app with a
     left sidebar: doc tabs, pLLM chat list, Browser bookmarks, Slack DMs)
     via window.MobileShell.createDrawer — see js/mobile.js. Each app's own
     CSS only sets its panel's inline width (set by the utility) and theme;
     everything about how it slides/scrims/handles lives here once. ---------- */
  .m-drawer {
    position: absolute !important;
    top: 0;
    bottom: 0;
    left: 0;
    z-index: 40;
    transform: translateX(-100%);
    transition: transform .25s ease;
    box-shadow: 12px 0 32px rgba(0, 0, 0, .18);
    touch-action: pan-y;
    will-change: transform;
  }
  .m-drawer.m-drawer-right {
    left: auto;
    right: 0;
    transform: translateX(100%);
  }
  .m-drawer.m-drawer-open { transform: translateX(0); }

  .m-drawer-scrim {
    position: absolute;
    inset: 0;
    z-index: 35;
    background: rgba(0, 0, 0, .28);
    opacity: 0;
    pointer-events: none;
    transition: opacity .2s ease;
  }
  .m-drawer-scrim.is-visible {
    opacity: 1;
    pointer-events: auto;
  }

  /* The pull handle is appended to the drawer's CONTAINER, not the panel:
     two panels (.br-rail, .slack-sidebar) are their own scroll boxes
     (overflow-y:auto), and a scroll box clips children positioned outside
     its padding box — a panel-attached handle at left:100% simply never
     painted there. Container-attached, it sits at the container's left
     edge (same resting look) and no panel overflow can touch it. It hides
     while the drawer is open (.is-open, toggled by the utility) — the
     scrim/swipe close instead. */
  .m-drawer-handle {
    position: absolute;
    top: 50%;
    left: 0;
    transform: translateY(-50%);
    width: 20px;
    height: 64px;
    border-radius: 0 10px 10px 0;
    background: var(--os-chrome);
    border: 1px solid var(--os-line);
    border-left: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 41;
    transition: opacity .2s ease;
  }
  .m-drawer-handle.is-open {
    opacity: 0;
    pointer-events: none;
  }
  .m-drawer-handle::before {
    content: "";
    width: 4px;
    height: 28px;
    border-radius: 2px;
    background: rgba(0, 0, 0, .3);
  }

  @media (prefers-reduced-motion: reduce) {
    .dock, .dock-home, .m-drawer, .m-drawer-scrim { transition: none !important; }
  }
}
