@charset "UTF-8";
/*******************************************************************************
 * Copyright 2026 - Raul Herreros - Amtiri SpA
 *
 * The responsive layer: the phone shell's own components, and what the desktop
 * workspace has to become when the window is too narrow to hold it.
 *
 * Loaded after site-overrides.css and before the deployment theme, so a branded
 * instance can still retune anything here by cascade:
 *
 *     tokens.css -> j2w.css -> fx2web.css -> workspace.css
 *                -> site-overrides.css -> this file -> application.theme
 *
 * Nothing here uses !important. The layers below this one state that contract
 * and this file keeps it.
 *
 * @author Raul Herreros
 ******************************************************************************/

/* =========================================
   BREAKPOINTS

   The first ones in this product. Nothing upstream defines a breakpoint, a
   container query or a width token, so the two tiers below are a convention
   this file introduces rather than one it inherits - and they are written as
   literals because a custom property cannot be used in a media query.

       <= 1024px   narrow: a workspace that no longer fits side by side
       <=  640px   phone: the tier the mobile shell is drawn for

   640px is above every phone in portrait and below every tablet in landscape,
   which is the line the routing in ClientDevice already draws. 1024px catches
   a tablet and a half-width desktop window, where the workspace is still the
   right interface but its header is not.
   ========================================= */

/* =========================================
   THE PHONE SHELL

   PaneMobileLogin, PanelMobile and PanelDashboardMobile. These are full-page
   roots rather than panes inside a frame, so each one owns the whole viewport
   and the scrolling happens in exactly one place inside it.
   ========================================= */
.site-mobile-shell,
.site-mobile-login {
    background-color: var(--j2w-bg);
    /* Resolves to 0px until the viewport meta carries viewport-fit=cover, which
       is built in J2Web's HTML head and not reachable from here. Declared now so
       the notch is handled the day that ships, rather than needing a second pass. */
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
    padding-bottom: env(safe-area-inset-bottom);
}

/*
 * The rule that makes any of this fit.
 *
 * FX2Web emits a VBox as a grid with explicit rows and no explicit columns, so the
 * single column is implicit and 'auto' - sized by its widest content and grown, but
 * never shrunk, by the 'justify-content: stretch' it carries. On a phone that is the
 * difference between a layout and a card hanging off the right edge: a 512px logo
 * sets the track to 512px and the viewport is 390px, so everything below it inherits
 * a column wider than the screen and the page, which clips at the body, simply cuts
 * it off - there is not even a scrollbar to reveal what was lost.
 *
 * minmax(0, 1fr) is the same thing j2w.css does to the body for the same reason: the
 * 0 floor lets the track shrink below its content, and the 1fr pins it to the width
 * it was given rather than the width it would like.
 */
.site-mobile-shell,
.site-mobile-login,
.site-mobile-card,
.site-mobile-body > vbox {
    grid-template-columns: minmax(0, 1fr);
}

/* The bar that carries the mark and the way out. It does not scroll with the
   list: on a phone the only global actions there are live here, and hunting for
   them by scrolling back to the top is the thing a sticky header exists to
   prevent. */
.site-mobile-header {
    background-color: var(--j2w-surface);
    border-bottom: 1px solid var(--j2w-border);
    box-shadow: var(--j2w-shadow-1);
}

.site-mobile-logo {
    height: 32px;
    width: auto;
    max-width: 45%;
}

.site-mobile-eyebrow {
    font-size: var(--j2w-text-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--j2w-text-muted);
    line-height: 1.2;
}

.site-mobile-title {
    font-size: var(--j2w-text-lg);
    font-weight: 700;
    color: var(--j2w-text);
    line-height: 1.2;
    /* A dashboard name is written for a desktop tab and can be long. One line that
       ends in an ellipsis beats a header that grows to three. */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    /* A grid item's automatic minimum size is its content, so without this the title
       refuses to shrink and pushes the header wider than the screen instead of
       ellipsing - the ellipsis above never gets the chance to apply. */
    min-width: 0;
}

/* A square target for a header action, sized like the workspace's own header
   chips rather than like a text button. */
.site-mobile-action {
    width: var(--j2w-control-height);
    min-width: var(--j2w-control-height);
    padding: 0;
}

.site-mobile-body {
    background-color: transparent;
}

.site-mobile-section {
    font-size: var(--j2w-text-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--j2w-text-muted);
}

.site-mobile-empty {
    padding: var(--j2w-space-6) var(--j2w-space-4);
    text-align: center;
    color: var(--j2w-text-muted);
    font-size: var(--j2w-text-md);
}

/* =========================================
   THE DASHBOARD LIST

   Rows, not buttons that happen to be wide. The base button rule centres its
   content and gives it the control height; a list row wants its content packed
   to the leading edge and a height set by what is in it.
   ========================================= */
.site-mobile-tile {
    width: 100%;
    padding: var(--j2w-space-3);
    background-color: var(--j2w-surface);
    border: 1px solid var(--j2w-border);
    border-radius: var(--j2w-radius-lg);
    /*
     * A button is a grid of max-content columns centred as a group, which is right
     * for a button with a word in it and wrong for a row. Named tracks instead: the
     * name takes the slack and, allowed to shrink below its content by the 0 floor,
     * ellipses rather than pushing the chevron off the screen.
     */
    grid-template-columns: max-content minmax(0, 1fr) max-content;
    justify-content: stretch;
    justify-items: start;
    align-items: center;
    gap: var(--j2w-space-3);
    text-align: left;
    transition: background-color var(--j2w-duration-base) var(--j2w-ease),
                border-color var(--j2w-duration-base) var(--j2w-ease);
}

.site-mobile-tile-icon {
    color: var(--j2w-accent);
}

.site-mobile-tile-name {
    min-width: 0;
    font-size: var(--j2w-text-lg);
    font-weight: 600;
    color: var(--j2w-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.site-mobile-tile-chevron {
    color: var(--j2w-text-muted);
    justify-self: end;
}

/*
 * Touch has no hover. A finger produces :active for the length of the press and
 * then, on iOS, leaves :hover stuck on the last thing tapped - so the press state
 * is what actually gives feedback here and the hover is only for a mouse on a
 * narrow window.
 */
.site-mobile-tile:hover {
    border-color: var(--j2w-border-strong);
}

.site-mobile-tile:active {
    background-color: var(--j2w-accent-subtle);
    border-color: var(--j2w-accent);
}

/* =========================================
   THE SIGN-IN CARD
   ========================================= */
.site-mobile-card {
    width: 100%;
    /* Full width on a phone, and a card again on anything wider - the same pane
       serves a 320px handset and a tablet held in landscape.
       min() rather than a bare 420px: the root centres its children, and a centred
       grid item is sized by its content, so a plain max-width lets the card settle
       at 420px on a 390px screen and hang off the right edge. */
    max-width: min(420px, 100%);
}

.site-mobile-login-logo {
    width: 100%;
    max-width: 260px;
    height: auto;
}

.site-mobile-centered {
    text-align: center;
}

.site-mobile-submit {
    width: 100%;
    justify-content: center;
}

/* A provider that signs in elsewhere - single sign-on - as wide as the sign-in
   button above it, and quieter than it. */
.site-mobile-provider {
    width: 100%;
    justify-content: center;
}

/* Pushes the Amtiri mark to the bottom of a tall screen without pinning it there
   on a short one, where it simply follows the card. */
.site-mobile-spacer {
    min-height: var(--j2w-space-4);
}

/* The crossing to the other shell: present, but never competing with the sign-in
   button or a dashboard for attention. */
.site-mobile-switch {
    font-size: var(--j2w-text-sm);
    color: var(--j2w-text-secondary);
    border-color: transparent;
    background-color: transparent;
}

/* =========================================
   THE DASHBOARD ON A PHONE

   DashboardView.setFitToWidth already makes the canvas scale, so what is left
   is to stop the desktop chrome from eating the width it needs.
   ========================================= */
.site-mobile-canvas {
    overflow: auto;
    /* Momentum scrolling, and no rubber-banding of the page behind the canvas. */
    overscroll-behavior: contain;
}

/* The zoom rail is four 34px buttons in a permanent column - roughly an eighth of
   a phone's width spent offering what pinch already does. */
.site-mobile-canvas .site-dashboard > vbox:last-child {
    display: none;
}

/* =========================================
   THE PHONE TIER

   Everything above describes the mobile shell at any width. This is what changes
   because the viewport is a phone.
   ========================================= */
@media (max-width: 640px) {
    :root {
        /*
         * The sanctioned lever, per the comment on the token upstream: one height
         * for everything that shares a row, retuned by the application rather than
         * hand-sized per control. 30px is a mouse target; 44px is the smallest
         * thing a finger hits reliably.
         */
        --j2w-control-height: 44px;
    }

    /* No hover state exists to preview a tap, so the tap must never be ambiguous. */
    button,
    .j2w-clickable {
        -webkit-tap-highlight-color: transparent;
        touch-action: manipulation;
    }

    .site-mobile-logo {
        height: 28px;
    }

    .site-mobile-title {
        font-size: var(--j2w-text-md);
    }
}

/* =========================================
   THE WORKSPACE ON A NARROW WINDOW

   The desktop shell is not replaced below 1024px - a tablet still wants it - but
   its header is drawn for a wide window: a 176px mark, a 1.5rem title and a
   right-aligned identity block that together need more room than they get.

   The library already has exactly the right narrow treatment in
   .wks-header-compact, which it applies when the operator collapses the menu.
   These rules reuse that treatment by width instead of by click. They restate it
   rather than adding the class, because the class is applied from Java and a
   stylesheet cannot reach it - and restating it here keeps the change inside this
   application, where com.amtiri:workspace is a published dependency shared with
   seven other products.
   ========================================= */
@media (max-width: 1024px) {
    .wks-header {
        padding-top: var(--j2w-space-1);
        padding-bottom: var(--j2w-space-1);
    }

    .wks-header-brand,
    .wks-header-subtitle {
        display: none;
    }

    .wks-header-title {
        font-size: var(--j2w-text-md);
        font-weight: 600;
        letter-spacing: 0;
    }

    .wks-header-rule {
        height: 20px;
    }

    .wks-avatar {
        width: 24px;
        height: 24px;
    }

    /*
     * The desktop sign-in card, on a window too narrow for the layout it was drawn
     * for. The library's Login.fxml is a 741px grid with two 10% spacer columns, and
     * FX2Web writes that floor out as 'min-width: 741px' on the grid element - so on
     * a 390px window the card is simply off the right-hand side, unreachable, with
     * the page clipping rather than scrolling.
     *
     * '!important' is required, not decorative: the floor is an inline style
     * attribute and an inline declaration outranks every selector in a stylesheet.
     * It is the same exception, for the same reason, that site-overrides.css takes
     * when it repaints an inline --icon. The class it hangs off is added in
     * SiteLogin.of, because the element carries none of its own.
     */
    /*
     * The mark is sized server-side into a fixed box - 400x200 on the login card,
     * 176x40 in the header - and the box is what overflows, not the picture: the
     * image is letterboxed inside it, so the page looks right while the element
     * still sticks 27px off the edge of a 390px screen and takes the layout with it.
     * max-width outranks the inline width without needing !important.
     */
    .site-logo {
        max-width: 100%;
    }

    .site-desktop-login > grid {
        grid-template-columns: 0 minmax(0, 1fr) 0 !important;
    }

    .wks-login-card {
        width: 100%;
        max-width: min(420px, 100%);
    }
}
