/* ====================================================================
   portal.css — the client portal's shell: auth gate, header, scrolling
   view area and the bottom tab bar. Tokens come from
   /css/tokens.css; module internals live in each module's index.css.

   Phone first. Every width query below adds desktop comfort to a layout
   that already works at 320px, rather than shrinking a desktop one —
   most clients open this on a phone, and the ones who don't are on a
   large screen where a centred column is fine.
   ==================================================================== */

*, *::before, *::after {
    box-sizing: border-box;
}

/* <app-module> is an unknown element to the parser, so it is display:inline
   until told otherwise. An inline box shrink-wraps its content, which lets a
   wide child — the horizontally scrolling status chips are the one that bit —
   set the width of the whole shell and push the page into a horizontal
   scroll. min-width:0 goes with it so the block can shrink below its
   content's min-content width instead of propagating it upward. */
app-module {
    display: block;
    min-width: 0;
}

body {
    margin: 0;
    font-family: var(--font);
    font-size: var(--font-size);
    color: var(--text);
    background: var(--surface-sunken);
    /* iOS Safari: stop a double-tap from zooming the whole page */
    touch-action: manipulation;
    -webkit-text-size-adjust: 100%;
}

.hidden {
    display: none !important;
}

/* --------------------------------------------------------------------
   Auth gate — main.js toggles portal--logged-in / portal--logged-out.
   Neither class is set until the session probe resolves, so a reload of
   an authenticated page shows nothing rather than flashing the login.
   -------------------------------------------------------------------- */

body.portal--logged-out {
    display: grid;
    place-items: center;
    min-height: 100vh;
    min-height: 100dvh; /* excludes the mobile browser chrome */
    padding: var(--sp-4);
}

body.portal--logged-in > app-module[src="/modules/portal-login"] {
    display: none;
}

.portal-authed {
    display: none;
}

body.portal--logged-in .portal-authed {
    display: grid;
}

/* --------------------------------------------------------------------
   Shell: header / scrolling main / tab bar.
   The grid gives main the leftover height so it scrolls on its own and
   the tab bar stays put — a page-level scroll would take the bar with it.
   -------------------------------------------------------------------- */

/* Phone: header on top, content scrolling, tab bar pinned at the bottom.
   minmax(0, …) on both axes because a grid track defaults to min-width/height
   auto, which refuses to shrink below its content and would leak an overlong
   row or a tall list out of the viewport. */
.portal-shell {
    grid-template-areas:
        "header"
        "main"
        "nav";
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) auto;
    height: 100vh;
    height: 100dvh;
}

.portal-shell > app-module[src="/modules/portal-header"] { grid-area: header; }
.portal-shell > app-module[src="/modules/portal-nav"]    { grid-area: nav; }
.portal-main { grid-area: main; }

.portal-main {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: var(--sp-4);
    /* room for the last card above the tab bar + the home indicator */
    padding-bottom: calc(var(--sp-6) + env(safe-area-inset-bottom));
}

/* Tablet and up: more breathing room, still a single column. */
@media (min-width: 48rem) {
    .portal-main {
        padding: var(--sp-5) var(--sp-6);
    }
}

/* --------------------------------------------------------------------
   Desktop: the tab bar becomes a left sidebar.

   A bottom tab bar is a phone idiom — it exists because that is where the
   thumb is. On a 1400px screen it puts navigation as far from the content
   as the geometry allows, so past 64rem the same markup is laid out as a
   sidebar spanning both rows, with the header beside it.
   -------------------------------------------------------------------- */

@media (min-width: 64rem) {
    .portal-shell {
        grid-template-areas:
            "nav header"
            "nav main";
        grid-template-columns: 15rem minmax(0, 1fr);
        grid-template-rows: auto minmax(0, 1fr);
    }

    .portal-main {
        padding: var(--sp-5) var(--sp-6) var(--sp-6);
    }

    /* A readable measure rather than a stretched phone view — but left
       aligned under the header, not centred in the remaining space. */
    .portal-main > app-module {
        max-width: 64rem;
    }
}

/* --------------------------------------------------------------------
   Shared building blocks. These are page-level on purpose: a card and a
   section heading look the same in every view, and duplicating them into
   five module stylesheets is how five slightly different cards happen.
   -------------------------------------------------------------------- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--sp-4);
    margin-bottom: var(--sp-4);
}

.card__title {
    margin: 0 0 var(--sp-3);
    font-size: 0.8125rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted);
}

.muted {
    color: var(--muted);
}

.error-banner {
    background: #fdecea;
    border: 1px solid var(--danger);
    border-radius: var(--radius-sm);
    color: #8a1f1f;
    padding: var(--sp-3);
    margin-bottom: var(--sp-4);
    font-size: 0.9375rem;
}

.empty-state {
    text-align: center;
    color: var(--muted);
    padding: var(--sp-6) var(--sp-4);
}

/* Buttons and inputs are sized for thumbs: 44px is the smallest target
   Apple's HIG considers reliably tappable, and these clients are older. */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sp-2);
    min-height: 2.75rem;
    padding: 0 var(--sp-4);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--primary);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.btn:disabled {
    opacity: 0.5;
    cursor: default;
}

.btn--block {
    width: 100%;
}

.btn--secondary {
    background: transparent;
    border-color: var(--border);
    color: var(--text);
}

.field {
    display: block;
    margin-bottom: var(--sp-3);
}

.field__label {
    display: block;
    margin-bottom: var(--sp-1);
    font-size: 0.875rem;
    font-weight: 600;
}

.field__input {
    width: 100%;
    min-height: 2.75rem;
    padding: 0 var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    /* 16px: iOS Safari zooms the viewport on focus for anything smaller */
    font: inherit;
    font-size: 1rem;
    background: var(--surface);
    color: var(--text);
}

.field__input:focus-visible,
.btn:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* --------------------------------------------------------------------
   Language switch — used on the login screen and the account screen.
   Language names are never translated, so this is styled once here
   rather than in either module.
   -------------------------------------------------------------------- */

.lang-switch {
    display: flex;
    gap: var(--sp-2);
}

.lang-switch__button {
    flex: 1;
    min-height: 2.5rem;
    padding: 0 var(--sp-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: 0.875rem;
    cursor: pointer;
}

.lang-switch__button--active {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
    font-weight: 600;
}

.lang-switch__button:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

/* Reduced motion is respected globally rather than per module — the
   portal has no animation that carries meaning. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}
