/*
 * Manifold mobile (PWA) shell styles.
 *
 * Loaded by templates/layouts/mobile.php for the launcher, install onboarding
 * and offline fallback pages. Phase 1 establishes the visual foundation:
 * brand chrome, hero, card, tile-grid, button system, safe-area insets.
 *
 * The 700 px breakpoint defined in docs/mobile_strategy.md is the line
 * between the mobile launcher and the desktop UI; pages using this
 * stylesheet are expected to render below that width on phones, but the
 * styles also degrade cleanly if loaded on a wider viewport.
 */

:root {
    --m-bg: #f3f5f8;
    --m-surface: #ffffff;
    --m-surface-alt: #f8fafc;
    --m-primary: #2E75B6;
    --m-primary-dark: #1B3A5C;
    --m-primary-light: #3a85c9;
    --m-text: #0f172a;
    --m-text-muted: #475569;
    --m-text-soft: #64748b;
    --m-border: #e5e7eb;
    --m-border-strong: #d0d7e2;
    --m-shadow-sm: 0 1px 2px rgba(15, 23, 42, .04);
    --m-shadow-md: 0 1px 2px rgba(15, 23, 42, .04), 0 6px 20px rgba(15, 23, 42, .06);
    --m-shadow-lg: 0 4px 12px rgba(15, 23, 42, .06), 0 20px 40px rgba(15, 23, 42, .10);
    --m-radius: 18px;
    --m-radius-sm: 12px;
    --m-radius-lg: 24px;
    --m-tap: 48px;

    /* iOS safe-area insets — mirrored here so mobile-only pages (which
       don't load app.css) can pad chrome around the iPhone notch +
       home-indicator using the same convention as the rest of the app.
       See CLAUDE.md "iOS safe-area" section. */
    --safe-top:    env(safe-area-inset-top, 0px);
    --safe-right:  env(safe-area-inset-right, 0px);
    --safe-bottom: env(safe-area-inset-bottom, 0px);
    --safe-left:   env(safe-area-inset-left, 0px);
}

* {
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;
}

html {
    height: 100%;
    background: var(--m-primary-dark);
}

body.m-body {
    margin: 0;
    min-height: 100%;
    min-height: 100dvh;
    font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "SF Pro Text",
        "Segoe UI", "Inter", "Helvetica Neue", Arial, sans-serif;
    font-size: 16px;
    line-height: 1.5;
    color: var(--m-text);
    background:
        radial-gradient(at 50% -10%, rgba(46, 117, 182, .35) 0%, rgba(27, 58, 92, 0) 60%),
        var(--m-bg);
    background-attachment: fixed;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-rendering: optimizeLegibility;
    overscroll-behavior-y: contain;
}

a {
    color: var(--m-primary);
    text-decoration: none;
}

a:active { color: var(--m-primary-dark); }

button {
    font: inherit;
    color: inherit;
}

img { display: block; max-width: 100%; }

/* Page container */

.m-app {
    max-width: 720px;
    margin: 0 auto;
    padding:
        calc(env(safe-area-inset-top, 0px) + 16px)
        calc(env(safe-area-inset-right, 0px) + 16px)
        calc(env(safe-area-inset-bottom, 0px) + 32px)
        calc(env(safe-area-inset-left, 0px) + 16px);
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: 100dvh;
}

/* Hero */

.m-hero {
    text-align: center;
    padding: 24px 16px 8px;
}

.m-hero-tight { padding-top: 16px; }

.m-hero-mark {
    display: inline-flex;
    width: 64px;
    height: 64px;
    margin: 0 auto 12px;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 6px 18px rgba(27, 58, 92, .25);
}

.m-hero-mark img {
    width: 100%;
    height: 100%;
    display: block;
}

/* Tenant-logo treatment: unconstrained natural aspect, capped height so
   wide and tall logos both fit the hero band comfortably. No rounded
   square or shadow — the tenant's own brand decides the silhouette. */
.m-hero-tenant-logo {
    display: block;
    text-align: center;
    margin: 0 auto 12px;
}
.m-hero-tenant-logo img {
    display: inline-block;
    max-height: 96px;
    max-width: 240px;
    width: auto;
    height: auto;
}

.m-hero-title {
    margin: 0 0 6px;
    font-size: 24px;
    font-weight: 700;
    color: var(--m-primary-dark);
    letter-spacing: -0.01em;
}

.m-hero-sub {
    margin: 0;
    color: var(--m-text-muted);
    font-size: 15px;
}

.m-hero-greeting {
    margin: 0;
    font-size: 22px;
    font-weight: 600;
    color: var(--m-primary-dark);
    letter-spacing: -0.01em;
}

.m-hero-store {
    margin: 4px 0 0;
    color: var(--m-text-soft);
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    justify-content: center;
}

.m-hero-divider {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--m-text-soft);
    display: inline-block;
}

/* Card */

.m-card {
    background: var(--m-surface);
    border-radius: var(--m-radius);
    padding: 20px;
    box-shadow: var(--m-shadow-md);
    border: 1px solid rgba(15, 23, 42, .04);
}

.m-card-notice {
    background: linear-gradient(180deg, #ffffff 0%, #f7fbff 100%);
    border: 1px solid rgba(46, 117, 182, .14);
}

.m-card-title {
    margin: 0 0 6px;
    font-size: 17px;
    font-weight: 600;
    color: var(--m-primary-dark);
    letter-spacing: -0.01em;
}

.m-card-body {
    margin: 0;
    color: var(--m-text-muted);
    font-size: 15px;
    line-height: 1.55;
}

.m-card-body + .m-install-actions { margin-top: 14px; }

.m-installed {
    background: linear-gradient(180deg, #f0fdf4 0%, #ffffff 100%);
    border-color: rgba(34, 197, 94, .25);
}

.m-installed .m-card-title { color: #166534; }

/* Tile grid */

.m-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin-top: 4px;
}

.m-tile {
    position: relative;
    background: var(--m-surface);
    border-radius: var(--m-radius);
    padding: 18px 16px;
    min-height: 96px;
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
    justify-content: space-between;
    color: var(--m-primary-dark);
    box-shadow: var(--m-shadow-sm);
    border: 1px solid rgba(15, 23, 42, .04);
    transition: transform .15s ease, box-shadow .15s ease;
}

/* An odd tile out takes the full row rather than leaving a hole. */
.m-launcher-grid .m-tile:last-child:nth-child(odd) { grid-column: 1 / -1; }

.m-tile:active {
    transform: scale(.98);
    box-shadow: var(--m-shadow-md);
}

.m-tile-icon {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    background: rgba(46, 117, 182, .10);
    color: var(--m-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.m-tile-icon svg {
    width: 22px;
    height: 22px;
    stroke-width: 2;
}

.m-tile-label {
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.005em;
    line-height: 1.2;
}

.m-tile-muted .m-tile-icon {
    background: rgba(100, 116, 139, .10);
    color: var(--m-text-soft);
}

/* Buttons */

.m-btn {
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    border-radius: 12px;
    padding: 14px 18px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1;
    min-height: var(--m-tap);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    cursor: pointer;
    text-decoration: none;
    transition: transform .12s ease, background .12s ease, box-shadow .12s ease;
}

.m-btn:active { transform: scale(.985); }

.m-btn-primary {
    background: var(--m-primary);
    color: #ffffff;
    box-shadow: 0 1px 2px rgba(15, 23, 42, .06), 0 6px 14px rgba(46, 117, 182, .26);
}

.m-btn-primary:hover { background: var(--m-primary-light); }

.m-btn-primary.m-btn-busy {
    background: var(--m-primary-dark);
    transform: scale(.98);
}

.m-btn-ghost {
    background: transparent;
    color: var(--m-primary);
    border: 1px solid var(--m-border-strong);
}

.m-btn-ghost:active { background: var(--m-surface-alt); }

.m-install-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 14px;
}

.m-install-actions .m-btn { flex: 1 1 auto; }

.m-install-fine {
    margin: 12px 0 0;
    font-size: 13px;
    color: var(--m-text-soft);
    line-height: 1.5;
}

/* Steps (install walkthrough) */

.m-steps {
    list-style: none;
    margin: 4px 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.m-steps li {
    display: flex;
    align-items: flex-start;
    gap: 14px;
    padding: 12px 14px;
    background: var(--m-surface-alt);
    border-radius: 14px;
    border: 1px solid var(--m-border);
}

.m-step-num {
    flex: 0 0 28px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--m-primary);
    color: #fff;
    font-weight: 700;
    font-size: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.m-step-body {
    color: var(--m-text);
    font-size: 15px;
    line-height: 1.5;
}

.m-step-body strong { color: var(--m-primary-dark); }

/* Back link */

.m-back-link {
    text-align: center;
    margin-top: 8px;
}

.m-back-link a {
    display: inline-flex;
    align-items: center;
    padding: 10px 16px;
    font-size: 15px;
    font-weight: 500;
    color: var(--m-primary);
}

/* Footer */

.m-footer {
    margin-top: auto;
    padding-top: 24px;
    text-align: center;
    color: var(--m-text-soft);
    font-size: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
}

.m-footer-sep {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--m-border-strong);
}

.m-footer-attr { font-weight: 500; }

/* Offline page */

.m-offline {
    align-items: center;
    justify-content: center;
    min-height: 100dvh;
}

.m-offline-card {
    background: var(--m-surface);
    border-radius: var(--m-radius-lg);
    padding: 32px 24px;
    text-align: center;
    box-shadow: var(--m-shadow-lg);
    width: 100%;
    max-width: 420px;
    border: 1px solid rgba(15, 23, 42, .04);
}

.m-offline-title {
    margin: 12px 0 8px;
    font-size: 22px;
    font-weight: 700;
    color: var(--m-primary-dark);
    letter-spacing: -0.01em;
}

.m-offline-body {
    margin: 0;
    color: var(--m-text-muted);
    font-size: 15px;
    line-height: 1.55;
}

.m-offline-card .m-install-actions {
    justify-content: center;
}

/* Top bar (launcher) */

.m-topbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: grid;
    grid-template-columns: 40px 1fr 40px;
    align-items: center;
    gap: 12px;
    padding:
        calc(env(safe-area-inset-top, 0px) + 10px)
        calc(env(safe-area-inset-right, 0px) + 16px)
        10px
        calc(env(safe-area-inset-left, 0px) + 16px);
    background: rgba(255, 255, 255, 0.75);
    backdrop-filter: saturate(180%) blur(14px);
    -webkit-backdrop-filter: saturate(180%) blur(14px);
    border-bottom: 1px solid rgba(15, 23, 42, .05);
}
/* When the header includes a search button, swap to a 4-column grid:
   avatar | brand | search | bell. */
.m-topbar.m-topbar-with-search {
    grid-template-columns: 40px 1fr 40px 40px;
}
.m-topbar-search-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--m-primary-dark);
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 0;
    transition: background .12s ease;
}
.m-topbar-search-btn:active { background: rgba(46, 117, 182, .10); }

.m-topbar-avatar {
    display: inline-flex;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    overflow: hidden;
    align-items: center;
    justify-content: center;
}

.m-topbar-avatar-img,
.m-topbar-avatar img {
    width: 40px !important;
    height: 40px !important;
    border-radius: 50% !important;
    display: block;
}

.m-topbar-back {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--m-primary-dark);
    -webkit-tap-highlight-color: transparent;
}
.m-topbar-back:active { background: rgba(46, 117, 182, .10); }

.m-topbar-brand {
    text-align: center;
    font-size: 15px;
    font-weight: 700;
    color: var(--m-primary-dark);
    letter-spacing: -0.005em;
}

.m-topbar-bell {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    color: var(--m-primary-dark);
    background: transparent;
    transition: background .12s ease;
}

.m-topbar-bell:active {
    background: rgba(46, 117, 182, .10);
}

.m-topbar-bell-icon {
    width: 22px;
    height: 22px;
}

/* Badges (top-bar bell + tile corner) */

.m-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: #ef4444;
    color: #ffffff;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
    box-shadow: 0 0 0 2px var(--m-surface);
}

.m-badge[hidden] { display: none; }

.m-badge-bell {
    position: absolute;
    top: 4px;
    right: 4px;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .8);
}

.m-badge-tile {
    position: absolute;
    top: 12px;
    right: 12px;
    background: var(--m-primary);
}

/* Launcher container tweaks */

.m-launcher {
    /* Top bar handles its own top padding; pull the launcher content up
       so the hero sits closer to the bar without doubling the safe-area. */
    padding-top: 12px;
}

.m-launcher-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (min-width: 480px) {
    .m-launcher-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* Secondary action row (install help, open desktop, sign out) */

.m-launcher-secondary {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    margin-top: 8px;
    padding: 8px 12px;
    font-size: 14px;
    color: var(--m-text-soft);
}

.m-secondary-link {
    color: var(--m-primary);
    padding: 6px 4px;
    text-decoration: none;
    font-weight: 500;
}

.m-secondary-link:active { color: var(--m-primary-dark); }

.m-secondary-danger {
    color: #b91c1c;
}

.m-secondary-danger:active { color: #7f1d1d; }

.m-secondary-sep {
    width: 3px;
    height: 3px;
    border-radius: 50%;
    background: var(--m-border-strong);
}

/* Wide-viewport guard: if a mobile page somehow loads above 700 px, scale
   the chrome down so it still looks intentional rather than stretched. */

@media (min-width: 700px) {
    .m-app {
        padding-top: 48px;
        padding-bottom: 48px;
    }
}

/* Persistent clock-strip — appears on every mobile page when the user
   has an open clock-in row.

   Positioning: `position: sticky; bottom: 0` on the strip directly,
   making it a normal child of <body> in document flow. When body
   content is short, the strip sits at body bottom = viewport bottom
   (because body has `min-height: 100dvh`). When content exceeds the
   viewport, the strip sticks to viewport bottom while the user
   scrolls. Sticky uses different positioning math than `position:
   fixed` and avoids the iOS PWA quirks that bit fixed-positioning
   on pages with 100dvh / overflow:hidden inner grid containers
   (chat conversation was the canonical offender).

   Visual: green background = the user is on the clock; red Clock out
   button is the primary action. The pulsing white dot reinforces the
   "active" state — no separate "CLOCKED IN" label needed. */

.m-clock-strip {
    position: sticky;
    bottom: 0;
    z-index: 9000;
    color: #fff;
    box-shadow: 0 -6px 20px rgba(15, 23, 42, 0.18);
    padding: 10px 12px;
    display: flex; align-items: center; gap: 12px;
    -webkit-tap-highlight-color: transparent;
    /* Pushes the strip to the bottom of body's flex column when content
       is shorter than the viewport — the sticky position handles the
       long-content case where body actually scrolls. */
    margin-top: auto;
}
/* Clocked in: green strip + red Clock out action. */
.m-clock-strip-in        { background: #16a34a; }     /* green-600 */
.m-clock-strip-in .m-clock-strip-out { background: #dc2626; }   /* red-600 */
.m-clock-strip-in .m-clock-strip-out:active { background: #b91c1c; }
/* Clocked out: red strip + green Clock in action. */
.m-clock-strip-out-state { background: #dc2626; }     /* red-600 */
.m-clock-strip-out-state .m-clock-strip-in-btn { background: #16a34a; }
.m-clock-strip-out-state .m-clock-strip-in-btn:active { background: #15803d; }

/* When the strip is rendered, convert body to a flex column so the
   strip can be a true flex child at the bottom of body. This is the
   one anchoring strategy that works universally across all mobile
   layouts, including the chat-conv's 100dvh / overflow:hidden grid
   that broke `position: fixed; bottom: 0` on iOS PWA.

   :has() keeps this opt-in to pages where the partial actually
   renders. iOS Safari 15.4+ supports :has() — well within our PWA
   minimum. */
body.m-body:has(.m-clock-strip) {
    display: flex;
    flex-direction: column;
}
body.m-body:has(.m-clock-strip) > main,
body.m-body:has(.m-clock-strip) > .m-app,
body.m-body:has(.m-clock-strip) > .mc-conv,
body.m-body:has(.m-clock-strip) > .mc-shell,
body.m-body:has(.m-clock-strip) > .mb-shell {
    flex: 1;
    min-height: 0;
    /* Override any rigid `height: 100dvh` set on the page's main
       element (chat-conv's .mc-conv being the canonical case) so flex
       sizing dictates instead. */
    height: auto;
}
.m-clock-strip-link {
    flex: 1; min-width: 0;
    display: flex; align-items: center; gap: 12px;
    color: inherit; text-decoration: none;
}
.m-clock-strip-dot {
    width: 10px; height: 10px; border-radius: 50%;
    background: #fff; flex-shrink: 0;
    box-shadow: 0 0 0 0 rgba(255,255,255,0.85);
    animation: m-clock-strip-pulse 1.4s ease-out infinite;
}
/* Static (non-pulsing) dot for the clocked-out red state. */
.m-clock-strip-dot-static {
    animation: none;
    box-shadow: none;
    opacity: 0.85;
}
@keyframes m-clock-strip-pulse {
    0%   { box-shadow: 0 0 0 0   rgba(255,255,255,0.85); }
    70%  { box-shadow: 0 0 0 9px rgba(255,255,255,0); }
    100% { box-shadow: 0 0 0 0   rgba(255,255,255,0); }
}
/* Two-line ID block: WO number on top, customer name below. */
.m-clock-strip-id {
    display: flex; flex-direction: column;
    min-width: 0;
    line-height: 1.15;
}
.m-clock-strip-wo {
    font-size: 14px; font-weight: 700;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.m-clock-strip-veh {
    font-size: 12px; font-weight: 500;
    opacity: 0.92;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    margin-top: 1px;
}
/* Elapsed timer: large + centered between the ID block and the button. */
.m-clock-strip-elapsed {
    flex: 1; text-align: center;
    font-size: 18px; font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.02em;
}
/* Shared action button (Clock out OR Clock in). Color comes from the
   parent state class above (.m-clock-strip-in or .m-clock-strip-out-state). */
.m-clock-strip-action {
    color: #fff;
    border: 0;
    border-radius: 8px;
    padding: 8px 14px;
    font-size: 14px; font-weight: 600;
    cursor: pointer;
    flex-shrink: 0;
    text-decoration: none;
    text-align: center;
    -webkit-tap-highlight-color: transparent;
}
.m-clock-strip-action:disabled { opacity: 0.6; cursor: default; }
.m-clock-strip-label {
    font-size: 14px; font-weight: 600;
    letter-spacing: 0.02em;
}

/* Pages that include the strip get extra bottom padding so their
   tail content isn't hidden behind it. Set on the body when the
   strip exists (JS toggles the class). The strip publishes its own
   measured height as --m-clock-strip-h; we add a small breathing
   margin on top so list content isn't flush against the strip. */
.m-body.has-clock-strip .m-app {
    padding-bottom: calc(var(--m-clock-strip-h, 0px) + 16px);
}

/* Reduced motion */

@media (prefers-reduced-motion: reduce) {
    .m-btn,
    .m-tile {
        transition: none;
    }
    .m-clock-strip-dot { animation: none; }
}
