/* 60-apps.css — see 00-contract.css for the rules this file obeys.
   Every rule below is inside a max-width or pointer:coarse media query.

   Covers the pages that are not the note editor/shell, the sequence
   viewer or the image annotator: the dashboard, the notebook desk,
   projects, tasks, samples, references, calendars, cell lines, reagents,
   planner, evidence, accounts, discussions, the auth/2FA screens, and the
   misc status pages. Most of that surface turned out to already reflow
   correctly (flex-wrap and generic .sheet/.data-table handling already
   do the work) — the rules here are the specific spots that didn't. */

/* ---------------------------------------------------------------------
   Dashboard (projects/dashboard.html, styled in app.css ~line 745).
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* app.css already folds the 7-column week to an auto-fill wrap below
     60rem (minmax(9rem,1fr)) so nothing scrolls sideways — but on a phone
     that wrap lands on 2 columns (2*9rem fits in ~23rem, 3 doesn't), which
     turns a Mon-Sun week into a broken 2-4-1 grid that no longer reads
     left-to-right as a week. One column, full-width day rows, keeps the
     chronological order a "current week" view exists for; there's enough
     vertical room on a phone since dash-week__day only holds 1-2 chips. */
  .dash-week {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 900px) {
  /* .starred-list__title, .dash-tasks__title, .dash-card__item-title and
     .record-list__title (projects/detail.html, accounts/team_detail.html)
     all pair text-overflow:ellipsis + white-space:nowrap with a plain flex
     child that has no explicit flex-basis. A flex item's minimum width
     defaults to its content size, and nowrap makes that content size equal
     the whole unwrapped title — so a long note/team/member title never
     actually ellipsizes, it pushes the row (and the page) wider instead.
     Harmless at desktop widths, where a 60-72rem sheet rarely runs out of
     room, but a real horizontal-scroll trigger on a 375-600px screen.
     min-width: 0 is what lets the flex item shrink to the ellipsis
     instead. */
  .starred-list__title,
  .dash-tasks__title,
  .dash-card__item-title,
  .record-list__title {
    min-width: 0;
    flex: 1 1 auto;
  }
}

@media (max-width: 600px) {
  /* accounts/team_detail.html's Roster row is the one .record-list__row
     with real width pressure: avatar + name + role chip + a two-button
     .record-list__action (button text, not icons — "Demote to member",
     "Promote to leader"). min-width: 0 above lets .record-list__title
     shrink all the way to nothing rather than wrap, so at 375px the
     member's name was disappearing entirely instead of ellipsizing —
     there just isn't room left for it once the buttons claim their own
     text width. Wrapping the action group onto its own, right-aligned
     line (rather than fighting the name for the same line) gives the
     name its space back; .record-list__action is already `display:flex;
     justify-content:flex-end` (app.css), so flex-basis: 100% is enough
     to make that alignment hold on the wrapped line too.

     Scoped with :has() to rows that actually carry a .btn-row action
     group (the roster only) rather than every .record-list__row: the
     two-item rows (projects/detail.html's Notes/Members/Teams — a
     title plus quiet meta or a single Remove button) already fit a
     375px line with the title ellipsizing, and turning on flex-wrap
     there unconditionally made the flex algorithm prefer breaking to a
     second line over shrinking the title, which is the wrong trade —
     it costs them height for no reason since they were never the
     rows that overflowed. Note the compound selector below, no space:
     team_detail.html puts both classes on the same <div> (`class=
     "btn-row record-list__action"`), it's not a descendant. */
  .record-list__row:has(.record-list__action.btn-row) {
    flex-wrap: wrap;
  }
  .record-list__row:has(.record-list__action.btn-row) .record-list__action {
    flex-basis: 100%;
    margin-left: 0;
  }
}

/* ---------------------------------------------------------------------
   The notebook desk (/n/ with nothing open) — notes/shell.html renders
   it, but the .desk/.binder/.page-card rules live in app.css, not the
   excluded shell.html template, so this is fair game. app.css already
   narrows .page-card to 12.5rem at 640px; nothing here fights that.
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* .binder__rack already scrolls (overflow-x:auto) and notes_desk.js
     already hides the arrow buttons once a rack has nothing left to
     scroll — a touch user swipes the rack directly and never needs them,
     but they cost nothing extra to leave in place for a stylus/trackpad.
     The one real gain on a phone is glimpsing more of the next card as a
     "there's more here" affordance, which a tighter side gutter buys back
     without touching card width. */
  .binder__spine,
  .binder__rack {
    padding-left: var(--gutter-compact);
    padding-right: var(--gutter-compact);
  }
}

/* ---------------------------------------------------------------------
   Samples — storage tree (samples/storage.html, styled in samples.css).
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* .storage-box-row reuses app.css's plain .row (display:flex, no wrap)
     for box name + box type + team + an Edit button. That's four items
     with no give between them; on a phone the row has nowhere near enough
     width and previously ran the box name/team text off the right edge of
     the sheet. Wrapping the name onto its own line first, then letting the
     type/team/Edit trio wrap underneath, keeps every field readable
     without scrolling the page sideways. */
  .storage-box-row {
    flex-wrap: wrap;
    row-gap: 0.3rem;
  }
  .storage-box-row__name {
    flex: 1 1 100%;
  }
}
@media (max-width: 600px) {
  /* Three levels of nested <details> (location > rack > box) each add
     their own left padding/indent on top of the sheet's own gutter —
     by the third level that eats a third of a 375px screen before any
     content starts. Halving each level's indent on a phone keeps the
     "nested inside" cue (still a visible step per level) while giving
     the row content the width back. */
  .storage-loc__body {
    padding-left: 0.9rem;
  }
  .storage-rack {
    padding-left: 0.5rem;
  }
  .storage-rack__body {
    padding-left: 0.3rem;
  }
}

/* ---------------------------------------------------------------------
   Cell lines — the lineage tree (cellines/library.html, detail.html,
   _tree_node.html; styled in cellines.css).
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* Same shape of problem as the storage tree above: .cl-tree__children
     indents 0.65rem margin + 1.1rem padding per generation, plus a
     0.85rem horizontal tick each level draws off that padding. A lineage
     four or five subclones deep is a real, named scenario here (fixes2.md
     "Cell line 3" already discusses grandparent history) — halving the
     per-level indent on a phone buys back that width without losing the
     "descends from" cue the connecting rule provides. */
  .cl-tree__children {
    margin-left: 0.35rem;
    padding-left: 0.6rem;
  }
  .cl-tree__children > .cl-tree__item::before {
    left: -0.6rem;
    width: 0.45rem;
  }
}

/* ---------------------------------------------------------------------
   Planner (planner/detail.html, styled in planner.css). The Gantt chart
   itself needs nothing here: frappe-gantt's own .gantt-container already
   scrolls internally (overflow: auto in the vendored CSS), and
   #planner-gantt-chart's own overflow:hidden only clips its rounded
   corners — the page was never at risk of scrolling for the chart's sake.
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* The "add a dependency" form pairs two <select> elements ("this task" /
     "depends on") in app.css's plain .row (flex, no wrap, no gap-shrink).
     Task titles run long, so two such selects side by side is the one
     spot in this page that doesn't already fit a phone's width. */
  .planner-panel .row {
    flex-wrap: wrap;
  }
}

/* ---------------------------------------------------------------------
   Discussions — the inline thread (discussions/_thread.html, styled in
   discussions.css). Everything in the thread already wraps; the only gap
   was the card's own fixed desktop padding.
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* .thread hard-codes 1.6rem/2rem padding to match .page's frame — fine
     at desktop widths, but 4rem of combined horizontal padding is a third
     of a 375px screen gone before any comment text starts. The compact
     gutter token keeps it visually aligned with every other surface on a
     phone instead. */
  .thread {
    padding: 1.1rem var(--gutter-compact) 1.3rem;
  }
}

/* ---------------------------------------------------------------------
   Citations — the inline bibliography under a signed/read entry
   (rendered by notes/shell.html + frontend/src/editor.js, styled in
   citations.css, which we own even though the template doesn't).
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* Same drift as .thread just above — .bibliography copies .page's
     desktop padding verbatim. */
  .bibliography {
    padding: 1.1rem var(--gutter-compact) 1.3rem;
  }
}

/* ---------------------------------------------------------------------
   Accounts — auth/2FA screens (two_factor/_base.html, _base_focus.html,
   registration/*, accounts/passkey_login.html) and the staff user list
   (accounts/admin_user_list.html).
   --------------------------------------------------------------------- */
@media (max-width: 600px) {
  /* .auth/.auth__sheet (app.css) are the chrome for every login/2FA/
     password-reset screen — the first thing anyone sees on a phone, and
     explicitly called out for a look. They already cap width at 100%, so
     nothing overflows, but the desktop padding (2rem outer + 2.1rem sheet)
     is over 4rem of combined horizontal padding — more than half of a
     375px screen — squeezing the actual form into a narrow column for no
     reason. The compact gutter buys that width back for the QR code,
     the OTP field, and the backup-token grid. */
  .auth {
    padding: 1.2rem var(--gutter-compact) 2.5rem;
  }
  .auth__sheet {
    padding: 1.3rem var(--gutter-compact) 1.6rem;
  }
}
@media (max-width: 900px) {
  /* .user-table__who pairs a fixed-size avatar with a name/email stack
     that has no wrap protection. A name is short and safe, but an email
     address has no spaces for the browser's default line-breaking to use
     — a long one (uzh addresses run long) sits as one unbreakable token
     and can push the row past the sheet's edge. overflow-wrap: anywhere
     only kicks in once a token doesn't otherwise fit, so a short address
     still reads as plain unbroken text. */
  .user-table__who > div {
    overflow-wrap: anywhere;
  }
}

/* ---------------------------------------------------------------------
   Accounts — calendar export feed URLs (accounts/calendar_export.html).
   The .feed-url class is added directly on the two <code> elements that
   hold a live .ics URL — see the template; every other <code> usage in
   the app (mattermostbot/status.html's env-var name) is short enough to
   never need this.
   --------------------------------------------------------------------- */
@media (max-width: 900px) {
  /* An .ics subscribe URL is 60-100+ characters with no spaces or
     hyphens, so the browser's default line-breaking has nowhere to break
     it — inside a <p class="tabular"><code> with no wrap rule of its own,
     a long one runs straight off the right edge of the sheet and takes
     the whole page's horizontal scroll with it. Truncating would make the
     URL unreadable/uncopyable, which defeats the page's whole purpose, so
     this wraps mid-token instead of shortening it. */
  .feed-url {
    overflow-wrap: anywhere;
  }
}
