/* ═══════════════════════════════════════════════════════════════════════════
   RESPONSIVE OVERRIDES
   ───────────────────────────────────────────────────────────────────────────
   Loaded last (see index.html) so it wins over styles.css / tools.css /
   new-ui.css without needing !important or id-selector escalation.

   Why this file exists: the portal was built desktop-first and had 8 media
   queries across ~8,100 lines of shared CSS. The individual tool pages mostly
   carry their own breakpoints in their inline <style> blocks and are fine —
   what was missing was the *shared* layer: the shell chrome, the tool-card
   grid used by All Tools and Pinned Favorites, the home widget grid, and the
   two slide-in side panels. Page-specific gaps that were genuinely absent are
   at the bottom, each labelled with the page it belongs to.

   Breakpoints, and why these numbers:
     900px — the shared "not a desktop" line. Matches the two existing
             @media (max-width: 900px) blocks in styles.css and the
             widgetModeTooNarrow query in script.js. Below this, the fixed
             6 × 200px widget canvas cannot fit and the side panels'
             380px column stops leaving usable content width.
     720px — phone. Matches new-ui.css's existing header breakpoint, so the
             nav chrome and the content below it change over together.
     360px — narrow phone (320px-class hardware). Only used to drop the tool
             grid from two columns to a single full-width row per tool.

   Nothing here touches layout above 900px.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ───────────────────────────────────────────────────────────────────────────
   1. SHELL — applies to every page
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {

    /* Page gutters were 1rem on .main-content *plus* 1rem on .tools-area, so
       every page lost 64px of a 393px viewport to padding it didn't need. The
       vertical padding is kept — it's the horizontal doubling that hurt. */
    .main-content {
        padding: 0.75rem 0.6rem;
    }

    .tools-area {
        padding: 0.5rem 0;
    }

    /* The Chat/Notes tab rail is NOT moved at this width — it keeps its vertical
       mid-right position, which is the design on anything desktop-shaped. It only
       becomes a bottom row on a real phone; see the 600px block below. */

    /* ── Classic-UI header ────────────────────────────────────────────────
       h1 is absolutely positioned across the full header width and centred at
       2rem. The existing 900px block lets the header wrap but leaves h1
       absolute, so the greeting sits on top of the logo. Put it back in flow.
       (The New UI hides `header` entirely, so this only affects classic.) */
    header h1 {
        position: static;
        transform: none;
        flex: 1 1 100%;
        font-size: 1.15rem;
        text-align: left;
        padding: 0.25rem 0;
    }

    header {
        min-height: 0;
        padding: 0.5rem 0.75rem;
        gap: 0.5rem;
    }

    .header-logo-group {
        position: static;
        transform: none;
    }

    .header-logo--classic {
        height: 40px;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   1b. SIDE PANELS (Chat, Notes, Reference) — phone only, 600px
   ───────────────────────────────────────────────────────────────────────────
   These shift the page over by a fixed 380px and sit in a shared right-hand
   column: chat takes the top 50vh and notes the bottom 50vh when both are open
   (styles.css, "Both panels open — split height"). That is a good design and it
   works on anything with room for the column plus usable content.

   This is deliberately 600px and not the 900px used elsewhere in this file. A
   900px cap catches a portrait desktop monitor — a ~750px-wide viewport with a
   mouse — where making the panel full-screen destroys the whole point of a side
   panel: you can no longer see the page you're taking notes about, and the two
   panels can no longer be stacked. Width alone does not tell you a viewport is a
   phone, and this is the one place in this file where getting that wrong removes
   function rather than just reflowing it.

   So: at 600px and below, where a 380px column would leave ~13px of content, the
   panel covers the page and the body stops shifting. Above that, the original
   behaviour stands untouched. Heights and `top` are left alone throughout, so
   chat-over-notes stacking keeps working in both modes.
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 600px) {

    /* ── Tab rail → bottom row ─────────────────────────────────────────────
       The vertical rail is pinned mid-right and sits over the content — it's what
       clips the right edge of the cards in the original phone screenshots. A short
       horizontal row at the bottom-right keeps it clear of the reading column and
       out of the thumb's scroll path.

       Phone only, deliberately. On a desktop-shaped viewport — including a portrait
       monitor at ~750px — the vertical rail is the established design and reads
       correctly, so nothing above 600px is touched. */
    .side-panel-btns {
        top: auto;
        bottom: 12px;
        right: 8px;
        transform: none;
        flex-direction: row;
        gap: 6px;
    }

    .chat-panel-btn,
    .onenote-panel-btn,
    .ref-panel-btn,
    .todo-panel-btn {
        border-radius: 8px;
        padding: 9px 11px;
        box-shadow: 0 2px 12px rgba(0, 0, 0, 0.22);
    }

    /* The labels are writing-mode: vertical-rl for the rail; a horizontal row
       wants horizontal text. */
    .chat-panel-btn-label,
    .onenote-btn-label,
    .ref-panel-btn-label {
        writing-mode: horizontal-tb;
        transform: none;
    }

    body.chat-panel-open,
    body.notes-panel-open {
        padding-right: 0;
    }

    .chat-side-panel,
    .onenote-panel {
        width: 100%;
        max-width: 100%;
    }

    /* The panel now covers the page, so the rail would float on top of it. Each
       panel has its own close button, so nothing becomes unreachable. */
    body.chat-panel-open .side-panel-btns,
    body.notes-panel-open .side-panel-btns {
        display: none;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   2. HOME — widget grid
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {

    /* Widget mode itself is switched off in JS at this width (see
       widgetModeTooNarrow in script.js) because its grid is a fixed
       6 × 200px canvas positioned by mouse-only drag events. These rules
       cover the *stacked* layout that phones therefore always get, which had
       its own problem: it's a two-column grid, and four of the widgets are
       pinned to a named column. Collapse it to one column and release them. */
    .widget-grid:not(.widget-active) {
        grid-template-columns: 1fr;
    }

    .widget-grid:not(.widget-active) #widget-world-clock,
    .widget-grid:not(.widget-active) #widget-tz-tracker,
    .widget-grid:not(.widget-active) #widget-todo,
    .widget-grid:not(.widget-active) #widget-recent-tools {
        grid-column: 1 / -1;
    }

    /* Belt-and-braces: if widget mode is ever active at this width (a stale
       class from a resize that raced the JS, say), the canvas must still not
       force the page 1272px wide — html/body are overflow-x: hidden, so an
       overflow here is silently *clipped*, not scrollable. */
    .widget-grid.widget-active {
        grid-template-columns: 1fr;
        grid-auto-rows: auto;
        width: 100%;
    }

    .widget-grid.widget-active .widget {
        grid-column: 1 / -1 !important;
        grid-row: auto !important;
        height: auto;
    }

    .widget-grid.widget-active .widget .widget-body {
        overflow: visible;
    }

    .widget-cell {
        display: none;
    }

    /* The Add/Edit Widgets buttons only mean something on the fixed canvas. */
    #add-widget-btn,
    #edit-widgets-btn {
        display: none;
    }

    /* Only Customize survives here, so the bar's flex-end alignment has nothing
       left to align — the button just takes the row. */
    .home-widget-bar {
        padding: 4px 0 10px;
    }

    #customize-home-btn {
        width: 100%;
        justify-content: center;
    }
}

/* Profile → Settings: hide the Widget Mode switch where it can't take effect. */
@media (max-width: 900px) {
    #widget-mode-toggle-row {
        display: none;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   3. TOOL CARD GRID — All Tools page + Pinned Favorites
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {

    /* The reported All Tools bug. Two rules combine badly on a phone:
         grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))  → 1 column
         aspect-ratio: 1 / 1                                          → square
       One ~310px column forced every card to be ~310px tall with a 72px logo
       floating in the middle of it, so a single tool filled most of the screen.
       Dropping the track minimum from 200px to 150px keeps the square tile
       language — which is the point of the design — at a size that reads as a
       tile: two up on any current phone (160px at 375px wide, 188px at 430px),
       and four up on a tablet in portrait, rather than a hardcoded two columns
       that would blow back up to ~345px tiles on an iPad mini.

       This is All Tools only — Pinned Favorites becomes a horizontal strip
       instead, see section 3b. */
    #all-tools-list .shortcut-list {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 0.6rem;
    }

    /* .shortcut-item's base min-height is 215px, which would override the
       aspect ratio and re-introduce tall cards at half the width. Drag-to-reorder
       is mouse-only here too, so `cursor: grab` is a promise the page can't keep
       on a phone. */
    #favorites-list .shortcut-item,
    #all-tools-list .shortcut-item {
        min-height: 0;
        padding: 0.85rem 0.6rem;
        cursor: pointer;
    }

    /* .shortcut-primary is `min-height: 100%` + `justify-content: flex-start`, so
       it stretches to the full square and pins the logo and label to the top,
       leaving the bottom half of every tile empty — very visible once the meta
       line below is hidden. Centre the contents in the square instead. */
    #favorites-list .shortcut-primary,
    #all-tools-list .shortcut-primary {
        justify-content: center;
        min-height: 0;
    }

    /* 72px of logo + 181px of max-width belongs to a 310px card, not a 165px
       one. Scale the whole tile's contents down to match. */
    #favorites-list .shortcut-item-icon,
    #all-tools-list .shortcut-item-icon {
        height: 46px;
        max-height: 46px;
        max-width: 100%;
        margin-bottom: 0.4rem;
    }

    #favorites-list .shortcut-meta,
    #all-tools-list .shortcut-meta {
        margin-top: 0.3rem;
        margin-bottom: 0.4rem;
        font-size: 0.68rem;
    }

    /* On All Tools the meta line ("Personal Tools / Ezee Fiber") repeats the
       category header the tile already sits under, and at two-up it wraps to two
       lines and competes with the tool name for the tile. Dropped here only —
       Pinned Favorites has no section header above it, so there the same line is
       the only thing telling you where a tool came from. */
    #all-tools-list .shortcut-meta {
        display: none;
    }

    #favorites-list .shortcut-link,
    #all-tools-list .shortcut-link {
        font-size: 0.82rem;
        line-height: 1.25;
    }

    /* The category cards' 1.5rem padding on top of the page gutters left the
       grid very little room. */
    .all-tools-category-section {
        padding: 0.9rem 0.75rem;
        border-radius: 16px;
    }

    .category-header {
        font-size: 0.92rem;
        margin-bottom: 0.85rem;
    }

    /* A 36px button with 0.5rem of padding is sized for a 215px desktop tile; on
       a ~169px one it reads as a second piece of primary UI competing with the
       logo. Same target area is kept above the 24px minimum for a fingertip. */
    #favorites-list .pin-button,
    .shortcut-list .pin-button {
        top: 4px;
        right: 4px;
        width: 28px;
        height: 28px;
        padding: 0.25rem;
    }

    #favorites-list .pin-button svg,
    .shortcut-list .pin-button svg {
        width: 15px;
        height: 15px;
    }
}

/* ───────────────────────────────────────────────────────────────────────────
   3b. PINNED FAVORITES — horizontal strip
   ───────────────────────────────────────────────────────────────────────────
   Favorites is a short, ordered, frequently-used set, not something you browse,
   so it reads better as one swipeable row than as a block that pushes every
   other widget down the page. Six favorites in the wrapping grid was 615px of
   home page before Announcements even started; as a strip it's ~150px.

   This is the same shape widget mode already uses on desktop — styles.css sets
   `grid-auto-flow: column` on #favorites-list and `overflow-x: auto` on the
   wrapper — except those rules are scoped to `.widget-active`, which is exactly
   the class a phone never has. So the pattern is re-stated here for the
   off-canvas case rather than invented.

   Deliberately CSS-only. The desktop version sizes tiles from JS
   (updateFavoritesLayout), and driving tile size off a wrapper whose height was
   unbounded is what made this widget grow without limit in the first place. A
   fixed track width has no such feedback path.
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 900px) {

    .favorites-scroll-wrapper {
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        /* Room for the scrollbar so it can't sit on top of the last tile. */
        padding-bottom: 6px;
        scrollbar-width: thin;
        scrollbar-color: rgba(var(--primary-rgb), 0.4) transparent;
    }

    .favorites-scroll-wrapper::-webkit-scrollbar {
        height: 4px;
    }

    .favorites-scroll-wrapper::-webkit-scrollbar-track {
        background: transparent;
    }

    .favorites-scroll-wrapper::-webkit-scrollbar-thumb {
        background: rgba(var(--primary-rgb), 0.4);
        border-radius: 2px;
    }

    /* One row, flowing sideways. `grid-template-columns: none` is required: the
       base rule at styles.css:1246 sets an auto-fill template, and a template
       plus column flow would still wrap into the template's tracks. */
    #favorites-list.shortcut-list {
        display: grid;
        grid-auto-flow: column;
        grid-template-columns: none;
        grid-auto-rows: auto;
        grid-auto-columns: 132px;
        gap: 0.6rem;
    }

    /* 132px leaves roughly two and a half tiles visible at 393px, so the strip
       reads as scrollable without needing a gradient or arrow to say so. The
       explicit width matches grid-auto-columns so a long tool name can't widen
       its own track and make the tiles uneven.

       The border is here because .shortcut-item's background is
       rgba(255,255,255,0.75) and in the New UI the .dashboard-card behind it is
       var(--surface-card) — white on white, so the tiles have no visible edge. That
       goes unnoticed on All Tools, where the tinted .all-tools-category-section sits
       behind them, but a swipe strip whose targets are invisible doesn't read as
       swipeable at all. It uses the New UI's own card border token so it matches the
       surrounding chrome, with a neutral fallback for the classic UI. */
    #favorites-list .shortcut-item {
        width: 132px;
        aspect-ratio: 1 / 1;
        scroll-snap-align: start;
        border: 1px solid var(--border, rgba(0, 0, 0, 0.1));
    }

    body.dark #favorites-list .shortcut-item {
        border-color: var(--border, rgba(255, 255, 255, 0.12));
    }

    /* Same reasoning as All Tools: the meta line wraps to two lines inside a
       132px tile. Here the tool name alone is enough — you pinned it. */
    #favorites-list .shortcut-meta {
        display: none;
    }

    #favorites-list .shortcut-item-icon {
        height: 40px;
        max-height: 40px;
    }

    #favorites-list .shortcut-link {
        font-size: 0.76rem;
    }
}


/* Only for genuinely narrow devices (320px-class phones), where two columns leave
   ~133px per tile and the longer tool names wrap to four lines. Every current
   iPhone is 375px or wider and keeps the two-up tile grid above. Here each tool
   becomes one full-width row and the forced square is dropped, so the row is only
   as tall as its content. Favorites is exempt — a horizontal strip doesn't care
   how narrow the viewport is, and its tiles stay 132px. */
@media (max-width: 360px) {
    #all-tools-list .shortcut-list {
        grid-template-columns: 1fr;
    }

    #all-tools-list .shortcut-item {
        aspect-ratio: auto;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        text-align: left;
        gap: 0.75rem;
        padding: 0.7rem 0.8rem;
    }

    #all-tools-list .shortcut-primary {
        flex-direction: row;
        align-items: center;
        min-height: 0;
        gap: 0.75rem;
        text-align: left;
    }

    #all-tools-list .shortcut-item-icon {
        height: 34px;
        max-height: 34px;
        max-width: 90px;
        margin-bottom: 0;
        flex-shrink: 0;
    }

    #all-tools-list .shortcut-meta {
        margin: 0;
    }

    /* Row layout, so the pin needs to clear the text rather than the corner. */
    #all-tools-list .pin-button {
        top: 50%;
        right: 6px;
        transform: translateY(-50%);
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   4a. NAV — portrait monitor / narrow desktop (1000px)
   ───────────────────────────────────────────────────────────────────────────
   A portrait monitor lands around 750–1000px, and there the banner was eating
   ~160px of sticky chrome in three bands: logo + search, then the date/time and
   icon cluster wrapping to their own line, then the tabs on a third.

   The tabs cannot be recovered into the first row — they need 439px and the
   inline budget at 750px is 129px — so two rows is the floor unless the tabs
   collapse behind a single All Tools link, which costs a click on every
   navigation. Two rows it is.

   Most of that reduction turned out NOT to belong here. The logo anchor had been
   given .page-link for its routing, which carries `width: 100%` and
   `min-height: 42px` — so the logo was inflating both the width and the height of
   the nav row. Removing that class (index.html / script.js) took 750px from ~165px
   to ~100px on its own.

   This block therefore does one thing: swap the wordmark for the compact mark.
   An earlier version also hid the clock, which is now removed — re-measured with
   the logo fixed, hiding it saved 0px at 600–800px and 44px at 900–1000px, which
   is not worth taking a readout away from someone on a portrait monitor at ~750px.
   Net: ~165px → ~98px, two bands, clock intact.
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 1000px) {

    /* Same swap new-ui.css makes at 720px, just brought forward: the full logo
       has a hard 150px minimum and the mark says the same thing in 30px. The
       secondary wordmark is not an option here — that file is solid black and
       vanishes on a dark surface (see new-ui.css:699). */
    body.new-ui .header-logo--light,
    body.new-ui.dark .header-logo--dark {
        display: none;
    }

    body.new-ui .header-logo--mark {
        display: block;
        height: 30px;
        border-radius: 6px;
    }

    body.new-ui .header-logo-group::after {
        margin-left: 8px;
        height: 24px;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   4b. NAV — phone
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {

    /* The logo is now the home button (see index.html), which makes the separate
       home tab a duplicate. Dropping it returns ~44px to the row — the tightest
       space in the whole UI, shared by the search field, the All Tools link, the
       clock, the bell and the avatar. Desktop keeps both: there the explicit tab
       costs nothing.

       The selector has to reach `.top-nav > ul > li` and not just `.nav-tab-home`:
       styles.css sets `.top-nav li { display: flex }`, which is (0,1,2) and beats a
       bare class no matter how late this file loads — load order only breaks ties
       between selectors of *equal* specificity.

       Note this is keyed on width alone, never on `.nav-collapsed`. syncNavStacking()
       decides that class by summing `li.offsetWidth`, so a rule that hid tabs only
       while collapsed would make them measure 0, look like they fit, un-collapse,
       re-measure, and flap forever. A width-only rule just hands the measurement a
       consistently smaller `needed` — which is the point: one fewer tab makes the
       row more likely to stay inline. */
    .top-nav > ul > li.nav-tab-home {
        display: none;
    }

    /* .top-nav > ul > li + li draws a divider on the left of every tab after
       the first. With the home tab gone the next tab is first, so without this
       the rule leaves a stray line at the start of the row. */
    .top-nav > ul > li:first-child {
        border-left: none;
    }

    body.new-ui .header-logo-link {
        cursor: pointer;
    }

    /* (Search keeps its inline spot at this width — see the 500px block. At
       560–700px the pill still gets ~214px of input, which comfortably fits the
       153px placeholder, so giving it a row here only added a third band.) */
}


/* ───────────────────────────────────────────────────────────────────────────
   4c. NAV — search row, 500px
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 500px) {

    /* ── Search gets its own row ───────────────────────────────────────────
       The pill is the only flex item in the row with any give, so it absorbs
       whatever the other three leave — and on a phone they leave almost nothing.
       Measured at 393px: logo group 79px + icon cluster 86px + the All Tools link
       68px, leaving the pill 117px, of which 71px is the input. The placeholder
       ("Search tools & articles…") needs 153px, which is why it rendered as
       "Sea". At 320px the input is down to 18px.

       Shaving pixels off the neighbours doesn't fix this — the row is simply
       over-subscribed at four items — so the search takes a second row and gets
       the full width. That's the same mechanism new-ui.css already uses for
       .nav-stacked: `flex-wrap` on the nav, `flex: 1 0 100%` on the child that
       should break. The order values in play are logo 0, tabs/All-Tools 2, icons
       3, stacked tabs 4; 5 puts the search after all of them.

       500px rather than 720px: at 560–700px the pill still gets ~214px of input,
       which fits the placeholder, so a second row there was pure added height.

       The `.nav-collapsed` selector is not a state-dependent rule — it is the same
       declaration written twice so it wins in both states. new-ui.css's own 720px
       block has `body.new-ui .top-nav.nav-collapsed .banner-search { flex: 1 }` at
       (0,4,1); a single `body.new-ui .top-nav .banner-search` is (0,3,1) and loses
       to it, which left the field 18px wide and still clipped once the tabs
       collapsed. Both selectors carry identical declarations, so syncNavStacking()
       cannot change the outcome by toggling the class — no oscillation. */
    body.new-ui .top-nav {
        flex-wrap: wrap;
        row-gap: 6px;
    }

    body.new-ui .top-nav .banner-search,
    body.new-ui .top-nav.nav-collapsed .banner-search,
    body.new-ui .top-nav.nav-stacked .banner-search {
        order: 5;
        flex: 1 0 100%;
        width: auto;
        min-width: 0;
    }

    /* The results panel is absolutely positioned against .top-nav (the pill is
       `position: static` in the New UI), so it already opens below the whole nav
       and needs no repositioning — it just wants the width to match the field it
       now sits under instead of the 400px it assumes. */
    .banner-search-panel {
        width: 100%;
        left: 0;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   5. PAGE-SPECIFIC GAPS
   ───────────────────────────────────────────────────────────────────────────
   Only the pages whose own inline <style> had no breakpoint covering the
   pattern. The rest already handle themselves and are deliberately absent:
     down-detector, my-evals, qa-evaluation-manager, knowledge-base, lnd,
     lnd-report, org-chart, construction-tracker, dispatch-portal,
     dispatch-requests, Tachus-shenandoah, note-generator, email-templates.
   Every wide table in the portal (.dp-table 980px, .sh-cases-table 820px,
   .cj-wo-table 480px, .excel-row) already sits in an overflow-x: auto
   wrapper, so tables needed nothing here.
   ─────────────────────────────────────────────────────────────────────────── */

@media (max-width: 720px) {

    /* Customer Journey — the contact and reference cards are hard 3- and
       4-column grids. Four columns on a phone is ~75px per field, which
       truncates every value. The page's own @media only covers .sf-grid. */
    #customer-journey-page .sf-contact-card,
    #customer-journey-page .sf-ref-card {
        grid-template-columns: 1fr 1fr;
        padding: 0.7rem 0.8rem;
    }

    /* Salesforce (Tachus) has the same 3-column .sf-contact-card but already
       collapses it in its own @media (max-width: 700px), so it is not repeated
       here. It has no .sf-ref-card at all. */

    /* Jira Tickets — the only page with no breakpoint at all. .jt-table has no
       min-width so it squeezes rather than overflows, but the cells are dense
       enough that it needs to scroll instead. No wrapper element exists to put
       overflow on, so the table becomes its own scroll container. */
    #jira-tickets-page .jt-table {
        display: block;
        overflow-x: auto;
        white-space: nowrap;
    }

    #jira-tickets-page .jt-wrap {
        max-width: 100%;
    }

    #jira-tickets-page .jt-tabs {
        overflow-x: auto;
        padding-bottom: 4px;
    }

    #jira-tickets-page .jt-tabs > * {
        flex-shrink: 0;
    }

    /* Admin Permissions + Management Dashboard — .quick-action-button is
       1rem text in 1.2rem side padding, so two of them overflow the row.
       Full-width stacked buttons instead. */
    #admin-permissions-page .quick-action-button,
    #management-dashboard-page .quick-action-button,
    #directsales-home-page .quick-action-button,
    #sales-order-management-page .quick-action-button {
        width: 100%;
        padding: 0.6rem 0.8rem;
        font-size: 0.9rem;
        text-align: center;
    }

    .iframe-page-actions {
        flex-direction: column;
        align-items: stretch;
    }

    /* Embedded-app pages (TSR GUI, Sales Order Management, Direct Sales) host
       a third-party app we don't control the inside of. All we can do is give
       it the full width and a workable height — the iframe is height: 100% of
       a flex parent, which collapses once .tools-area loses its padding. */
    #tsr-gui-page .management-iframe,
    #sales-order-management-page .management-iframe,
    #directsales-home-page .management-iframe {
        min-height: 70vh;
        border-radius: 10px;
    }

    /* Profile — the accent swatch row and lookup row are unwrapped flex. */
    #profile-page .accent-swatch-row {
        flex-wrap: wrap;
    }

    #profile-page .customer-lookup-row {
        flex-direction: column;
        align-items: stretch;
    }

    /* Announcement History / anywhere hero copy appears: 2rem headings at
       393px wrap to four lines before any content is visible. */
    .dashboard-hero .hero-copy h2,
    .page h1 {
        font-size: 1.25rem;
        line-height: 1.3;
    }

    .card-header h3 {
        font-size: 1rem;
    }
}


/* ───────────────────────────────────────────────────────────────────────────
   6. TOUCH-DEVICE GUARDS — not width-based
   ───────────────────────────────────────────────────────────────────────────
   A large tablet can be wider than 900px and still have no mouse. Hover
   states that only appear on hover are unreachable there, so anything the
   portal hides behind :hover is pinned visible instead. */

@media (hover: none) and (pointer: coarse) {

    /* In widget mode the favourites pin button is opacity: 0 until the tile is
       hovered, so on a touch device it can never be reached and a pinned tool
       can never be unpinned. Widget mode is already off below 900px, so this
       covers the case that remains: a tablet wider than that with no mouse.
       (The pin buttons outside widget mode are always visible — nothing to fix
       there.) */
    .widget-grid.widget-active #favorites-list .shortcut-item .pin-button {
        opacity: 1;
    }
}
