/*
 * Design tokens for the Saint WhatsApp console.
 *
 * Chrome colours match the other Saint consoles (VocallGatewayGUI) so the tools
 * feel like one suite. WhatsApp's own green is used only where it carries
 * meaning - outbound message bubbles and channel affordances - never as page
 * chrome, which would misrepresent this as a Meta product.
 *
 * Every value below is a custom property. Pages and templates reference the
 * tokens; they must not hard-code colours, radii, or spacing.
 */
:root {
    /* Brand / chrome */
    --primary-color:        #1f6feb;
    --primary-color-text:   #ffffff;

    /* Channel accent - WhatsApp */
    --wa-accent:            #25d366;
    --wa-accent-dark:       #128c7e;
    --wa-bubble-out:        #d9fdd3;
    --wa-bubble-in:         #ffffff;

    /* Surfaces */
    --surface-ground:       #f5f7fa;
    --surface-card:         #ffffff;
    --surface-overlay:      #ffffff;
    --surface-border:       #e5e7eb;

    /* Text */
    --text-color:           #1f2937;
    --text-color-secondary: #6b7280;
    --text-color-muted:     #9ca3af;

    /* Status */
    --status-danger:        #b91c1c;
    --status-success:       #047857;
    --status-warning:       #b45309;

    /* Shape + type */
    --border-radius:        6px;
    --radius-bubble:        10px;
    /*
     * The system UI face, declared honestly. 'Inter' used to head this stack while
     * nothing loaded it - no @font-face, no @import, no stylesheet link - so every
     * page already rendered in system-ui, and the spacing and line-height tokens
     * below were tuned against those metrics rather than Inter's. Naming a face we
     * do not ship also means the console reads differently on a machine that
     * happens to have it installed. To adopt Inter properly, self-host the woff2
     * under resources/fonts/, add the @font-face rules, and re-check this scale.
     */
    --font-family:          system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

    /* Spacing scale */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;

    /* Overlays (emoji picker and any future floating panel) */
    --shadow-overlay: 0 6px 24px rgba(15, 23, 42, 0.18);
    --z-overlay:      1000;

    /* Layout */
    --layout-max-width:     1400px;
    --thread-max-width:     72ch;
    --inbox-list-width:     340px;
    /* The two breakpoints, as the documented contract. @media cannot read a custom
       property, so each block below repeats its literal and names the token it
       must track — but both breakpoints are declared here, and neither is left
       as a bare number with nothing to point at. */
    --breakpoint-tablet:    768px;
    --breakpoint-phone:     480px;
}

html, body {
    height: 100%;
    margin: 0;
    background: var(--surface-ground);
    font-family: var(--font-family);
    color: var(--text-color);
}

.layout-wrapper {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

/* ------------------------------------------------------------------ topbar */
.layout-topbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--primary-color);
    color: var(--primary-color-text);
    padding: var(--space-3) var(--space-5);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    flex-wrap: wrap;
    gap: var(--space-2);
}
.layout-topbar a,
.layout-topbar a:visited {
    color: var(--primary-color-text);
    text-decoration: none;
    margin-right: var(--space-4);
    font-weight: 500;
}
.layout-topbar a:hover { text-decoration: underline; }
.layout-topbar .brand {
    font-weight: 700;
    font-size: 1.1rem;
    margin-right: var(--space-6);
}

.topbar-user {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-left: auto;
}
.topbar-user form { margin: 0; }
.topbar-username { font-weight: 500; }
.topbar-logout {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.5);
    color: var(--primary-color-text);
    cursor: pointer;
    font: inherit;
    padding: var(--space-1) var(--space-3);
    border-radius: 4px;
}
.topbar-logout:hover { background: rgba(255, 255, 255, 0.12); }

/* -------------------------------------------------------------- main/footer */
.layout-main {
    flex: 1;
    padding: var(--space-5);
    max-width: var(--layout-max-width);
    width: 100%;
    margin: 0 auto;
    box-sizing: border-box;
}

.layout-footer {
    padding: var(--space-3) var(--space-5);
    text-align: center;
    color: var(--text-color-secondary);
    font-size: 0.85rem;
    border-top: 1px solid var(--surface-border);
    background: var(--surface-card);
}

.card {
    background: var(--surface-card);
    border: 1px solid var(--surface-border);
    border-radius: var(--border-radius);
    padding: var(--space-5);
    margin-bottom: var(--space-4);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

/* ------------------------------------------------------------------- forms */
.field {
    margin-bottom: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.field label {
    font-size: 0.85rem;
    color: var(--text-color-secondary);
}

.text-input {
    padding: var(--space-2);
    border: 1px solid #d1d5db;
    border-radius: var(--border-radius);
    font: inherit;
}

.btn-primary {
    background: var(--primary-color);
    color: var(--primary-color-text);
    border: none;
    border-radius: var(--border-radius);
    padding: var(--space-2) var(--space-4);
    cursor: pointer;
    font: inherit;
    font-weight: 500;
}
.btn-block { width: 100%; }

.toolbar-actions {
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    margin-bottom: var(--space-3);
}

/* ------------------------------------------------------------------- login */
.login-shell {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}
.login-card { width: 360px; max-width: 100%; }
.login-card h1 { margin: 0 0 var(--space-4) 0; font-size: 1.25rem; }
.login-error {
    color: var(--status-danger);
    margin-bottom: var(--space-3);
    font-size: 0.9rem;
}
.login-notice {
    color: var(--status-success);
    margin-bottom: var(--space-3);
    font-size: 0.9rem;
}

/* ------------------------------------------------------------------- inbox */
/* Two panes: conversation list on the left, thread + composer on the right.
   Sized to the viewport so each pane scrolls internally, not the page. */
.inbox-grid {
    display: grid;
    grid-template-columns: var(--inbox-list-width) 1fr;
    gap: var(--space-4);
    /* dvh, not vh: on mobile browsers vh counts the retracted chrome, which pushes
       the composer under the address bar. */
    height: calc(100dvh - 190px);
    min-height: 420px;
}

/* Desktop keeps both panes visible, so there is nothing to go back to. */
.thread-back { display: none; }

.inbox-list,
.inbox-thread {
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.inbox-list-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--surface-border);
}
.inbox-list-title { font-weight: 600; }
.inbox-list-actions { display: flex; align-items: center; gap: var(--space-1); }

/* compose (new conversation) dialog */
.compose-form { display: flex; flex-direction: column; gap: var(--space-3); min-width: 320px; }
.compose-input { width: 100%; }
.compose-actions { display: flex; justify-content: flex-end; margin-top: var(--space-2); }

.conv-table { flex: 1; min-height: 0; border: none; }
/* Let the rows carry the visual weight, not PrimeFaces' default table chrome. */
.conv-table .ui-datatable-header,
.conv-table th { display: none; }
.conv-table td { padding: 0; }

/* The whole row is one command link filling the cell. */
.conv-link {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--surface-border);
}
.conv-link:hover { background: var(--surface-ground); }
.conv-selected { background: var(--surface-ground); }

.conv-row {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}
.conv-line {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
}
.conv-title {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.conv-time {
    color: var(--text-color-muted);
    font-size: 0.75rem;
    flex-shrink: 0;
}
.conv-preview {
    color: var(--text-color-secondary);
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ------------------------------------------------------------ thread pane */
.inbox-empty {
    margin: auto;
    text-align: center;
    color: var(--text-color-muted);
}
.inbox-empty .pi { font-size: 2.5rem; display: block; margin-bottom: var(--space-2); }

.thread {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}
.thread-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--surface-border);
}
.thread-title { font-weight: 600; margin-right: var(--space-2); }
.thread-waid { color: var(--text-color-secondary); font-size: 0.85rem; }

.thread-messages {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    background: var(--surface-ground);
}

/*
 * p:dataList nests its items three levels deep - ui-datalist > -content > -data -
 * so the bubbles were not flex items of the pane above, which left .msg-bubble's
 * align-self and the pane's gap inert: every bubble rendered left-aligned and
 * flush, outbound included. display:contents lifts the items back into the pane's
 * flex flow, where the in/out alignment below is decided.
 */
.thread-messages .ui-datalist,
.thread-messages .ui-datalist-content,
.thread-messages .ui-datalist-data {
    display: contents;
}

/* "Load earlier messages": the window is bounded, so this is how history arrives. */
.thread-older {
    align-self: center;
    margin-bottom: var(--space-2);
}

.msg-bubble {
    max-width: min(72%, var(--thread-max-width));
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-bubble);
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.06);
    display: flex;
    flex-direction: column;
    gap: 2px;
    word-wrap: break-word;
}
.msg-in {
    align-self: flex-start;
    background: var(--wa-bubble-in);
    border: 1px solid var(--surface-border);
}
.msg-out {
    align-self: flex-end;
    background: var(--wa-bubble-out);
}
.msg-text { white-space: pre-wrap; }
/* media bubbles: keep the player/thumbnail within the bubble width */
.msg-media { margin-bottom: var(--space-1); }
.msg-media-img,
.msg-media-video {
    display: block;
    max-width: 100%;
    max-height: 320px;
    border-radius: var(--border-radius);
}
.msg-media-audio { width: 240px; max-width: 100%; }
.msg-media-doc {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    color: var(--primary-color);
    text-decoration: none;
    font-weight: 500;
}
.msg-media-doc:hover { text-decoration: underline; }
.msg-caption { margin-top: var(--space-1); }
.msg-meta {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-1);
    font-size: 0.7rem;
    color: var(--text-color-secondary);
}
.msg-status { font-size: 0.75rem; }
.msg-status-read { color: var(--primary-color); }
.msg-status-failed { color: var(--status-danger); }

/* --------------------------------------------------------------- composer */
.composer {
    border-top: 1px solid var(--surface-border);
    padding: var(--space-3) var(--space-4);
}
.composer-input {
    display: flex;
    gap: var(--space-2);
    align-items: flex-end;
}
.composer-textarea { flex: 1; }
.composer-textarea .ui-inputtextarea,
.composer-textarea.ui-inputtextarea { width: 100%; resize: none; }
.composer-notice {
    color: var(--text-color-secondary);
    font-size: 0.85rem;
    font-style: italic;
}
.composer-send { flex-shrink: 0; }

/* emoji picker: a themed toggle beside the input, and a floating grid on body */
.composer-emoji {
    flex-shrink: 0;
    width: 2.4rem;
    height: 2.4rem;
    padding: 0;
    border: 1px solid var(--surface-border);
    background: var(--surface-card);
    border-radius: var(--border-radius);
    cursor: pointer;
    font-size: 1.15rem;
    line-height: 1;
}
.composer-emoji::before { content: "🙂"; }
.composer-emoji:hover { background: var(--surface-ground); }

.emoji-panel {
    position: fixed;
    z-index: var(--z-overlay);
    width: 300px;
    max-height: 260px;
    overflow-y: auto;
    padding: var(--space-2);
    background: var(--surface-overlay);
    border: 1px solid var(--surface-border);
    border-radius: var(--border-radius);
    box-shadow: var(--shadow-overlay);
}
.emoji-panel[hidden] { display: none; }
.emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
.emoji-group-label {
    grid-column: 1 / -1;
    padding: var(--space-2) var(--space-1) var(--space-1);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-color-muted);
}
.emoji-cell {
    border: 0;
    background: transparent;
    cursor: pointer;
    padding: var(--space-1);
    border-radius: var(--border-radius);
    font-size: 1.25rem;
    line-height: 1;
}
.emoji-cell:hover { background: var(--surface-ground); }

/* ------------------------------------------------------------- responsive */
/* Tablet and below: a fixed 340px list beside a thread pane overflows the body
   horizontally at these widths and pushes the composer out of reach, so the two
   panes stop being columns and become alternating views instead - the list until
   a conversation is opened, the thread (with a back control) after.

   768px is --breakpoint-tablet, repeated as a literal because @media cannot read
   a custom property. Keep the two in step. */
@media (max-width: 768px) {
    .layout-main { padding: var(--space-3); }

    .inbox-grid {
        grid-template-columns: 1fr;
        /* Each pane sizes itself rather than the grid subtracting a constant:
           the topbar wraps at this width, so a fixed chrome height drifts. */
        height: auto;
        min-height: 0;
    }
    .inbox-list,
    .inbox-thread {
        height: calc(100dvh - 160px);
        min-height: 320px;
    }
    .inbox-grid.thread-open .inbox-list { display: none; }
    .inbox-grid:not(.thread-open) .inbox-thread { display: none; }

    .thread-back { display: inline-flex; }
    /* Room for the back control; the window tag wraps under the title if need be. */
    .thread-header { flex-wrap: wrap; }

    /* Bubbles get more of the line once the pane is full-width. */
    .msg-bubble { max-width: 88%; }
}

/* Phone: the topbar's own padding is the last thing worth reclaiming.
   480px is --breakpoint-phone, repeated as a literal for the same reason. */
@media (max-width: 480px) {
    .layout-topbar { padding: var(--space-2) var(--space-3); }
    .layout-topbar .brand { margin-right: var(--space-3); }
    .layout-main { padding: var(--space-2); }
    .inbox-list,
    .inbox-thread { height: calc(100dvh - 180px); }
}

/* ------------------------------------------------------ management pages */
.page { width: 100%; }
.page-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
}
.page-title { margin: 0; font-size: 1.25rem; }
.page-note { color: var(--text-color-secondary); }

.cell-strong { font-weight: 600; }
/* Hug content and never wrap: short values (a language code, a status tag, a
   count) and their headers. Under the auto table layout below this sizes the
   column to its widest cell instead of clipping it. */
.col-narrow { white-space: nowrap; }

/* PrimeFaces dataTables default to table-layout:fixed, which shares width
   equally and, together with .col-narrow, collapsed those columns to ~45px and
   clipped their headers and tags (overflow is hidden). These management tables
   have no fixed-width requirement, so let the browser size columns to content:
   the long Body/preview column takes the slack, the narrow ones fit exactly.
   !important because the fixed rule is a framework default, not inline. */
.table-fluid table { table-layout: auto !important; }
.col-actions { width: 1%; white-space: nowrap; text-align: right; }

/* create / edit forms on the management pages */
.form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--space-3) var(--space-4);
    margin-bottom: var(--space-3);
}
.field-inline {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    align-self: end;
    padding-bottom: var(--space-2);
}
.edit-panel { border-left: 3px solid var(--primary-color); }
.edit-title { margin: 0 0 var(--space-3) 0; font-size: 1rem; }

/* -------------------------------------------------- out-of-window template composer */
.composer-template { display: flex; flex-direction: column; gap: var(--space-2); }
.composer-template-select { max-width: 340px; }
.template-detail {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin-top: var(--space-2);
}
.template-preview {
    background: var(--surface-ground);
    border: 1px solid var(--surface-border);
    border-radius: var(--border-radius);
    padding: var(--space-2) var(--space-3);
    color: var(--text-color-secondary);
    font-size: 0.9rem;
    white-space: pre-wrap;
}
.template-param-label {
    font-size: 0.8rem;
    color: var(--text-color-secondary);
}
.template-param { max-width: 340px; }

/* ------------------------------------------------------ media attach (composer) */
.composer-media { margin-top: var(--space-2); display: flex; flex-direction: column; gap: var(--space-2); }
.composer-media-ready {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    background: var(--surface-ground);
    border: 1px solid var(--surface-border);
    border-radius: var(--border-radius);
    padding: var(--space-2) var(--space-3);
}
.composer-media-name { font-size: 0.85rem; color: var(--text-color-secondary); }
.composer-media-caption { flex: 1; min-width: 160px; }
