/* ─────────────────────────────────────────────────────────────────────
   Mobile hardening.

   Loaded last so it can correct platform behaviour that the layout
   sheets do not own: iOS focus zoom, notch insets, tap flashes, scroll
   chaining, and touch target sizes. Everything here is scoped to touch
   pointers or small viewports, so the desktop layout is untouched.
   ───────────────────────────────────────────────────────────────────── */

/* ── Never zoom on focus ──────────────────────────────────────────────
   Mobile Safari zooms the viewport whenever a focused control's
   font-size computes below 16px, and it does not zoom back out. The
   layout sheets set 13–15px on most fields, which is what makes the
   page jump while typing.

   The fix is 16px on every text-entry control on touch devices. We do
   NOT use maximum-scale/user-scalable in the viewport meta: that would
   also kill deliberate pinch zoom, which people rely on. Control
   heights and padding are left alone, so nothing reflows — only the
   text inside the field grows those few pixels. */
@media (pointer: coarse) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="hidden"]),
  select,
  textarea,
  [contenteditable="true"],
  .compose-body,
  /* class-scoped rules that would otherwise win on specificity */
  .compose-panel select,
  .module-panel select {
    font-size: 16px;
  }

  /* The verification code is already larger and deliberately tracked. */
  .auth-view .input-wrap input.totp-input {
    font-size: 22px;
  }
}

/* ── Tap feedback ─────────────────────────────────────────────────────
   Without this, iOS and Android paint a grey box over every tapped
   button and link. The app has its own :active states. */
html {
  -webkit-tap-highlight-color: transparent;
}

/* ── Scroll containment ───────────────────────────────────────────────
   Stops a flick inside the list, the drawer or a modal from chaining
   into the page behind it and rubber-banding the whole shell. */
.message-list,
.message-list-panel,
.reader-scroll,
.sidebar,
.modal,
.modal-panel,
.compose-panel,
.module-panel {
  overscroll-behavior: contain;
}

/* ── Message rows ─────────────────────────────────────────────────────
   .message-content is a grid whose implicit column sizes to max-content,
   so a long preview grew wider than its own 224px cell and ran under —
   and past — the star button in column 4. Constraining the column makes
   the ellipsis land inside the cell where it belongs. */
.message-content {
  grid-template-columns: minmax(0, 1fr);
}

.message-sender,
.message-subject,
.message-preview {
  min-width: 0;
}

/* Constraining the cell correctly also means the subject truncates
   sooner, so narrow phones buy the width back from the gutters: the
   avatar column matches the 30px avatar it holds, and the gaps and side
   padding each give up a couple of pixels. */
@media (max-width: 420px) {
  .message-row {
    grid-template-columns: 16px 30px minmax(0, 1fr) 22px;
    gap: 7px;
    padding-left: 10px;
    padding-right: 10px;
  }
}

/* Star: 22×28 is well under the 44px touch minimum. Grow the hit area
   without growing the glyph, so the row layout is unchanged. */
@media (pointer: coarse) {
  .message-star {
    position: relative;
  }

  .message-star::after {
    content: "";
    position: absolute;
    inset: -8px -11px;
  }

  /* The select checkbox sits in a 16px column, so it can only grow
     vertically without stealing width from the subject line. */
  .message-bulk-check {
    position: relative;
    height: 44px;
    display: grid;
    place-items: center;
  }

  .message-bulk-check input {
    width: 20px;
    height: 20px;
  }
}

/* ── Drawer ───────────────────────────────────────────────────────────
   app.css gives .folder-list and .sidebar-extras `min-height: 0`, and on
   phones `overflow: visible`, so the flex column squeezed the folder list
   to 183px while its folders needed 348px. The overflow spilled out and
   the Views section was laid out on top of Archive, Spam and Trash. Let
   both lists keep their real height; the drawer itself scrolls. */
@media (max-width: 760px) {
  .sidebar .folder-list,
  .sidebar .sidebar-extras {
    flex: none;
    min-height: auto;
  }

  .sidebar .sidebar-section {
    margin-top: 6px;
  }
}

/* ── Safe areas ───────────────────────────────────────────────────────
   These only do anything once the viewport meta carries
   viewport-fit=cover, which it now does. Without them the bottom nav
   and full-screen modals sit under the iPhone home indicator. */
@media (max-width: 760px) {
  .compose-panel,
  .modal-panel {
    padding-bottom: max(16px, env(safe-area-inset-bottom));
  }

}

/* ─────────────────────────────────────────────────────────────────────
   Mobile structure
   Below 760px the shell is one column with a bottom nav, so the pieces
   that assume a sidebar or a wide toolbar need their own arrangement.
   ───────────────────────────────────────────────────────────────────── */

/* ── Compose: a reachable action ──────────────────────────────────────
   The sidebar Compose button is off-canvas on a phone. This sits clear
   of the 64px bottom nav and the home indicator. */
.compose-fab {
  display: none;
}

@media (max-width: 760px) {
  .app-shell[data-view="mail"][data-module="mail"] .compose-fab {
    display: inline-flex;
    position: fixed;
    right: 16px;
    bottom: calc(64px + 16px + env(safe-area-inset-bottom));
    z-index: 30;
    align-items: center;
    gap: 8px;
    height: 52px;
    padding: 0 20px;
    border-radius: 26px;
    background: linear-gradient(160deg, #2d40a8, #1b2a72);
    color: #fff;
    font-size: 14px;
    font-weight: 650;
    box-shadow: 0 10px 26px rgba(8, 18, 54, 0.34);
  }

  .compose-fab svg {
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.4;
    stroke-linecap: round;
  }

  .compose-fab:active {
    transform: translateY(1px);
  }

  /* Modals must sit above it. */
  .compose-modal,
  .modal {
    z-index: 40;
  }

  /* The drawer's backdrop lives in #mail-view's stacking context, below
     this fixed button, so it cannot cover it — hide it while it is open. */
  .app-shell:has(#mail-view.navigation-open) .compose-fab {
    display: none;
  }

  /* Reading a message is not the moment for a Write button. */
  .app-shell:has(.suite-grid.reader-open) .compose-fab {
    display: none;
  }
}

/* ── Reader: give the message the screen ──────────────────────────────
   The search field, the folder subtitle and the secondary actions were
   costing roughly two thirds of the first screen before a single line of
   the message appeared. */
.reader-more-toggle {
  display: none;
}

@media (max-width: 760px) {
  /* The whole 112px header row goes while reading: the reader carries its
     own "Back to messages", and the search field does not apply to an open
     message anyway. Hiding the field alone saved nothing, because it sits
     inside a fixed-height grid row — the row itself has to go.

     The workspace children are auto-placed, so taking the header out with
     display:none removes a grid item and pulls the mail module up into row
     one — the row being collapsed to zero. That blanked the reader. Pin the
     rows explicitly so removing the header cannot reshuffle anything.
     (.dashboard-strip is display:none !important on mobile, so it is never
     a grid item here.) */
  .workspace > .app-header {
    grid-row: 1;
  }

  .workspace > .suite-grid,
  .workspace > .module-panel {
    grid-row: 2;
  }

  .workspace:has(.suite-grid.reader-open) {
    grid-template-rows: 0 minmax(0, 1fr);
  }

  .workspace:has(.suite-grid.reader-open) .app-header {
    display: none;
  }

  .reader-more-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
  }

  .reader-more-toggle[aria-expanded="true"] {
    background: var(--blue-soft);
    border-color: var(--blue);
    color: var(--blue);
  }

  /* Folded away until More is tapped. `.hidden` still wins over this, so
     buttons the app hides for this folder stay hidden either way. */
  .message-reader:not(.actions-open) .reader-btn--more,
  .message-reader:not(.actions-open) .reader-btn-group--star {
    display: none;
  }

  .reader-actions {
    gap: 6px;
  }

  .reader-back {
    margin-bottom: 6px;
  }
}

/* ── Compose: progressive disclosure ──────────────────────────────── */
.compose-more-toggle {
  display: none;
}

@media (max-width: 760px) {
  .compose-more-toggle {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    align-self: flex-start;
    padding: 7px 2px;
    background: none;
    color: var(--blue, #2451d6);
    font-size: 13px;
    font-weight: 600;
    min-height: 40px;
  }

  .compose-more-caret {
    display: inline-block;
    transition: transform 160ms ease;
  }

  .compose-form.show-extra .compose-more-caret,
  #compose-form.show-extra .compose-more-caret {
    transform: rotate(180deg);
  }

  #compose-form:not(.show-extra) .compose-extra {
    display: none;
  }

  /* From is fixed for the session: state it, do not spend a field on it. */
  #compose-form > label:has(input[name="from"]) {
    flex-direction: row;
    align-items: baseline;
    gap: 8px;
    font-size: 12px;
    color: var(--muted);
  }

  #compose-form input[name="from"] {
    border: 0;
    background: none;
    padding: 0;
    width: auto;
    font-weight: 600;
    color: var(--ink);
  }

  /* Send should never be below the fold. */
  .compose-actions {
    position: sticky;
    bottom: 0;
    z-index: 2;
    margin: 0 -16px -16px;
    padding: 10px 16px max(10px, env(safe-area-inset-bottom));
    background: var(--panel, #fff);
    border-top: 1px solid var(--line);
  }

  .compose-actions button[type="submit"] {
    min-height: 46px;
    padding-inline: 26px;
    font-size: 15px;
  }
}

/* ── Selection mode ───────────────────────────────────────────────────
   On touch the checkboxes stay out of the way until a long press opens
   selection mode, so the subject line keeps its width. */
@media (pointer: coarse) {
  .message-list:not(.select-mode) .message-bulk-check {
    display: none;
  }

  .message-list:not(.select-mode) .message-row {
    grid-template-columns: 0 36px minmax(0, 1fr) 22px;
  }

  .message-list.select-mode .message-row {
    grid-template-columns: 20px 36px minmax(0, 1fr) 22px;
  }

  .message-list.select-mode .message-bulk-check {
    opacity: 1;
  }

  .message-list.select-mode .message-row {
    user-select: none;
  }

  .bulk-done {
    margin-left: auto;
    font-weight: 650;
  }
}

@media (max-width: 760px) {
  .bulk-toolbar {
    position: sticky;
    top: 0;
    z-index: 3;
    flex-wrap: wrap;
    gap: 6px;
  }
}

/* ── Login ─────────────────────────────────────────────────────────────
   Phones show the sign-in form only. The delivery-loop stage stays
   desktop-only (login.css hides .auth-stage below 1024px), and
   login-stage.js already picks its status face instead of the loop when
   the split layout is off, so nothing animates behind a hidden stage. */


/* ── Bulk: template gallery ───────────────────────────────────────────
   .template-card is a grid whose implicit column sizes to max-content, so
   a long word in the name or description made the column wider than the
   card and the text ran out over the neighbouring card. Same defect the
   message rows had. Unconditional: it misreads at any narrow column. */
.template-card {
  grid-template-columns: minmax(0, 1fr);
}

.template-meta > span:not(.template-icon) {
  min-width: 0;
}

.template-meta strong,
.template-meta small,
.template-desc {
  overflow-wrap: anywhere;
}

/* Two 137px columns on a phone left no room for either the preview or the
   name. One column per row gives the thumbnail enough width to actually be
   a preview. */
@media (max-width: 600px) {
  .template-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
  }

  .template-thumb {
    height: 210px;
  }

  .template-meta strong {
    font-size: 15px;
  }

  .template-desc {
    font-size: 13px;
  }
}

/* The thumbnail renders a real 640px-wide email and scales it down, so the
   scale has to track the card, not the viewport — a fixed value either
   overflows the narrow phones or leaves the wide ones half empty (the fit
   ranges from 0.33 at 320px to 0.75 at 600px). Container queries measure
   the thumb itself, which also keeps the two-column tablet layout right.
   Each step is its own width / 640, rounded down, so it can never overflow. */
.template-thumb {
  container-type: inline-size;
}

.template-thumb iframe { transform: translateX(-50%) scale(0.21); }
@container (min-width: 170px) { .template-thumb iframe { transform: translateX(-50%) scale(0.26); } }
@container (min-width: 200px) { .template-thumb iframe { transform: translateX(-50%) scale(0.31); } }
@container (min-width: 230px) { .template-thumb iframe { transform: translateX(-50%) scale(0.35); } }
@container (min-width: 260px) { .template-thumb iframe { transform: translateX(-50%) scale(0.40); } }
@container (min-width: 290px) { .template-thumb iframe { transform: translateX(-50%) scale(0.45); } }
@container (min-width: 320px) { .template-thumb iframe { transform: translateX(-50%) scale(0.49); } }
@container (min-width: 380px) { .template-thumb iframe { transform: translateX(-50%) scale(0.59); } }
@container (min-width: 440px) { .template-thumb iframe { transform: translateX(-50%) scale(0.68); } }


/* ─────────────────────────────────────────────────────────────────────
   Phone shell (≤760px)
   The desktop layout squeezed down was a card inside a card inside a
   canvas, with three bands of chrome above the first message. This is the
   pattern phone mail apps settled on: one search bar as the header, the
   list edge to edge, and everything else a tap away in the drawer.

   Selectors are prefixed (.workspace > .app-header, .message-list …) so
   they reach 0,2,0 and, coming last, also beat the older
   [data-theme="dark"] colour rules without needing !important.
   ───────────────────────────────────────────────────────────────────── */
.header-avatar,
.list-folder,
.drawer-quick {
  display: none;
}

@media (max-width: 760px) {
  :root {
    --phone-page: #ffffff;
    --phone-pill: #edf0f7;
    --phone-divider: #eceff5;
    --phone-chip-line: #d6dceb;
  }

  /* Dark: three clearly separated steps instead of two near-identical
     navies — page, raised bar/chips, and a divider you can actually see. */
  [data-theme="dark"] {
    --phone-page: #0c1323;
    --phone-pill: #1a2439;
    --phone-divider: #1f2a43;
    --phone-chip-line: #34405d;
  }

  .workspace {
    grid-template-rows: 64px minmax(0, 1fr);
    padding: 0;
    background: var(--phone-page);
  }

  /* ── The header is one search bar ─────────────────────────────────── */
  .workspace > .app-header {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) 44px;
    grid-template-rows: 48px;
    align-items: center;
    gap: 2px;
    height: 48px;
    min-height: 0;
    margin: 8px max(12px, env(safe-area-inset-right)) 8px max(12px, env(safe-area-inset-left));
    padding: 0 4px;
    border: 0;
    border-radius: 24px;
    background: var(--phone-pill);
    box-shadow: none;
  }

  .workspace > .app-header .title-block,
  .workspace > .app-header .header-actions {
    display: none;
  }

  .workspace > .app-header #mobile-menu {
    grid-column: 1;
    grid-row: 1;
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: 22px;
    background: transparent;
    color: var(--ink-soft);
  }

  .workspace > .app-header .search-box {
    grid-column: 2;
    grid-row: 1;
    min-width: 0;
    margin: 0;
  }

  .workspace > .app-header .search-box input {
    height: 44px;
    min-height: 0;
    padding: 0 6px;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
    color: var(--ink);
    font-size: 16px;
  }

  .workspace > .app-header .search-box input:focus {
    border: 0;
    box-shadow: none;
  }

  .workspace > .app-header .search-box input::placeholder {
    color: var(--muted);
  }

  .workspace > .app-header .header-avatar {
    display: grid;
    grid-column: 3;
    grid-row: 1;
    place-items: center;
    justify-self: center;
    position: relative;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: linear-gradient(160deg, #3a51bd, #22348a);
    color: #fff;
    font-size: 14px;
    font-weight: 700;
  }

  /* Live status rides on the account button as a presence dot. */
  .header-avatar::after {
    content: "";
    position: absolute;
    right: -2px;
    bottom: -2px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid var(--phone-pill);
    background: #94a3b8;
  }

  .header-avatar[data-live="live"]::after { background: #16a34a; }
  .header-avatar[data-live="polling"]::after { background: #d97706; }

  /* ── Modules keep their card, just with the inset the page lost ───── */
  .workspace > .module-panel {
    margin: 0 max(12px, env(safe-area-inset-right)) 10px max(12px, env(safe-area-inset-left));
  }

  /* ── List: edge to edge ───────────────────────────────────────────── */
  .workspace > .suite-grid {
    gap: 0;
    margin: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
  }

  .suite-grid > .message-list-panel {
    border: 0;
    border-radius: 0;
    background: transparent;
  }

  .suite-grid .list-toolbar {
    display: grid;
    gap: 10px;
    min-height: 0;
    padding: 4px max(16px, env(safe-area-inset-right)) 10px max(16px, env(safe-area-inset-left));
    background: transparent;
    border: 0;
  }

  .list-toolbar .list-heading {
    display: flex;
    align-items: baseline;
    justify-content: flex-start;
    gap: 10px;
  }

  .list-toolbar .list-folder {
    display: inline;
    color: var(--ink);
    font-size: 21px;
    font-weight: 750;
    letter-spacing: -0.015em;
  }

  .list-toolbar #message-count {
    color: var(--muted);
    font-size: 12.5px;
    font-weight: 600;
  }

  /* "No selection" means nothing on a phone. */
  .list-toolbar #selection-status {
    display: none;
  }

  /* One row of filters you swipe, instead of a wrapping block. */
  .list-toolbar .filter-chips {
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 8px;
    margin: 0 calc(-1 * max(16px, env(safe-area-inset-right))) 0 calc(-1 * max(16px, env(safe-area-inset-left)));
    padding: 1px max(16px, env(safe-area-inset-right)) 1px max(16px, env(safe-area-inset-left));
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }

  .list-toolbar .filter-chips::-webkit-scrollbar {
    display: none;
  }

  .list-toolbar .filter-chips button {
    flex: none;
    min-height: 34px;
    padding: 0 15px;
    border: 1px solid var(--phone-chip-line);
    border-radius: 17px;
    background: transparent;
    color: var(--ink-soft);
    font-size: 13px;
    font-weight: 600;
  }

  .list-toolbar .filter-chips button.active {
    border-color: var(--blue);
    background: var(--blue-soft);
    color: var(--blue);
  }

  /* Rows run the full width with hairline dividers, and the list keeps
     room at the bottom so the Write button never sits on the last one. */
  .suite-grid .message-list {
    padding: 0 0 calc(96px + env(safe-area-inset-bottom));
    background: transparent;
  }

  .message-list .message-row {
    min-height: 76px;
    margin: 0;
    padding: 12px max(16px, env(safe-area-inset-right)) 12px max(9px, env(safe-area-inset-left));
    border: 0;
    border-bottom: 1px solid var(--phone-divider);
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }

  .message-list .message-row.unread {
    background: transparent;
  }

  .message-list .message-row.active {
    background: var(--blue-soft);
  }

  /* The desktop unread marker is a bar on the row's left edge; edge to
     edge it sits on the screen bezel and reads as a glitch. Unread is
     already carried by the bold sender and the blue time. */
  .message-list .message-row::before {
    display: none;
  }

  /* A filled star is enough — the tinted box behind it turned into a
     brown square in dark mode. */
  .message-list .message-star.active {
    background: transparent;
  }

  .message-list .message-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    font-size: 14px;
  }

  .message-list .message-sender {
    font-size: 15px;
  }

  .message-list .message-subject {
    font-size: 14px;
  }

  .message-list .message-preview {
    font-size: 13px;
  }

  /* ── Drawer ───────────────────────────────────────────────────────── */
  /* The Write button is the compose entry on phones; the drawer does not
     need a second one, and it frees a row for the folders. */
  .sidebar .compose-primary {
    display: none;
  }

  .drawer-quick {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
    margin: 6px 0 12px;
  }

  .drawer-quick button {
    display: grid;
    justify-items: center;
    gap: 5px;
    min-height: 62px;
    padding: 10px 4px;
    border: 1px solid var(--line);
    border-radius: 12px;
    background: var(--panel-soft);
    color: var(--ink-soft);
    font-size: 11.5px;
    font-weight: 600;
  }

  .drawer-quick svg {
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
  }
}
