/*
================================================================================
  ML Software, LLC
  Copyright 2026. All rights reserved.

  Life IQ | lifeiq.mlsoftware.com

  assets/css/shell.css

  Platform: IQ Platform
  Version: 1.6.0
  Created: 2026-04-27
  Updated: 2026-07-29

  Description: The structural shell of every IQ product. Topbar full-width
  across the top, sidebar fixed-width on the left below the topbar,
  content area filling the remaining space. Mobile collapses the
  sidebar to zero, surfaces a hamburger toggle in the topbar, and
  slides the sidebar in as a fixed overlay with a tap-to-close
  backdrop.

  DOM contract (rendered by IQ.app._renderShell, consumed by this CSS):

    #iq-root              -- root grid container
      .iq-topbar          -- top bar (#iq-topbar)
        .topbar-left      -- brand area, page title
          #iq-page-title  -- in-app page title (router writes here)
        .topbar-right     -- location switcher, user chip, sign-out
          #iq-loc-label
          #iq-loc-menu
          #iq-user-chip
          #iq-signout
        .btn-menu-toggle  -- hamburger (mobile only)
      .iq-sidebar         -- sidebar (#iq-sidebar)
        #iq-nav           -- nav container (router queries .nav-item[data-route])
      #iq-overlay         -- mobile sidebar overlay (.sidebar-overlay)
      .iq-content         -- content area (#iq-content -- router renders here)

  When showing login (no auth), #iq-root flips from grid to flex
  centering and the topbar/sidebar are hidden -- handled via
  #iq-root:has(.iq-login-wrap).

  Load order: tokens.css -> base.css -> shell.css.

  Version History:
    1.6.0 - 2026-07-29 - Section label goes WHITE, the bar keeps the
                         accent. 1.5.0 had it the other way round and
                         the accent-on-accent read as a link.
                         The bar is var(--accent), which is a theme
                         token - theme.css redefines it per
                         [data-theme], so this follows whatever is
                         picked in Settings rather than being blue.
                         Nothing here is hardcoded.
                         Bar is taller and full-height beside the text
                         so it reads as a marker rather than a stray
                         underline.
    1.5.0 - 2026-07-29 - 1.4.0 was not enough. The label went from
                         --text-dim to --text-secondary and got a rule
                         above it, and it still read as a slightly
                         faded nav item. The problem was never contrast
                         alone - it was that the heading used the same
                         VISUAL LANGUAGE as the things beneath it: same
                         left edge, same colour family, same weight of
                         mark.
                         So it now gets a colour nothing else in the
                         drawer uses - the accent - plus a short accent
                         bar to its left. A nav item can be active and
                         accent-coloured, but it is never accompanied by
                         a bar, and the bar is the thing the eye reads
                         as "this is a heading" before it reads a single
                         word.
    1.4.0 - 2026-07-29 - Drawer section headers were unreadable AS
                         headers. The label was 12px and --text-dim
                         sitting directly above items at 14px and
                         --text-secondary: smaller AND dimmer than its
                         own contents, so the only thing marking it as a
                         header was the uppercase and the letter
                         spacing, and that loses. It read as a
                         de-emphasised nav item.

                         A heading has to be different IN KIND from the
                         things under it, not just quieter. So: a
                         hairline rule above each section to break the
                         list, real space above that rule, and the label
                         itself brought up to --text-secondary so it is
                         no longer the dimmest thing in its own group.
                         Uppercase and letter-spacing stay - together
                         with the rule they now read as structure rather
                         than as a faded option.

                         The first section gets no rule. A divider at
                         the very top of a list separates nothing.
    1.3.0 - 2026-07-27 - #iq-root no longer pads by the top safe-area
                         inset, and row 1 of the grid is sized to include
                         it instead.
                         .iq-topbar in mobile-tabs.css absorbs the inset
                         into its own padding and height so its background
                         runs behind the status bar, which is the native
                         pattern. With the root padding it as well, the
                         inset was counted twice - measured on device the
                         wordmark sat about 155px down, which is 59 + 59 +
                         half the bar.
                         Fixed here rather than by another override in
                         mobile-tabs.css. Six attempts at overriding this
                         rule from the later file never reached the
                         browser, and the rule being overridden lives in
                         this one. One file now decides, and the grid row
                         is sized in the same place as the padding it
                         replaces, so the two cannot disagree.
                         The bottom inset on .iq-sidebar and .iq-content is
                         untouched - the home indicator does overlap.
    1.2.0 - 2026-07-27 - .iq-login-wrap had align-items:center but no
                         height - only max-height:100%. A flex container
                         sized to its own content has nothing to centre
                         within, so the login card sat at the top of the
                         screen. Renewal IQ's equivalent carries
                         height:100vh and centres correctly; this is that,
                         with 100dvh layered on for mobile browser chrome.
                         The rule directly above it,
                         #iq-root:has(.iq-login-wrap), has never matched
                         anything in this product or in Renewal IQ: the
                         login wrap is a SIBLING of #iq-root in index.cfm,
                         not a child. Left in place rather than deleted -
                         it is inherited platform code and removing it is
                         a platform decision, not a product one - but it
                         is not what centres login and never was.
    1.1.0 - 2026-07-25 - Added .iq-sidebar-footer rule (centered, bottom
                         padding). The footer had no rule at all, so the
                         sign-out button sat flush in the corner. User chip
                         removed from the shell markup in app.js.
    1.0.0 - 2026-07-23 - Forked into Life IQ. Platform version 0.1.3
                         at time of fork; product versioning starts
                         at 1.0.0 from here. Platform history below
                         is kept for provenance.
    0.1.3 - 2026-07-23 - Login card styled. .iq-login-wrap and
                         .iq-login-box had no rules at all, so the
                         form ran the full width of the viewport on
                         every screen. The wrap now owns the gutter
                         and the box owns the width, so the card
                         never touches the screen edge.
    0.1.2 - 2026-04-27 - Burgundy color migration. #iq-signout:hover
                         and .iq-init-error h2 changed from
                         var(--red) to var(--red-text) for legibility
                         on dark surfaces. The background red is now
                         burgundy #7a1f24 per kickoff section 5.8 (defined
                         in tokens.css 0.1.2).
    0.1.1 - 2026-04-27 - Session 3 cont'd. Readability and hit-target
                         pass:
                         - .nav-section-label 11px -> 12px
                           (was the smallest text in the platform)
                         - #iq-user-chip 13px -> 14px (Inter body)
                         - .nav-item hit target enforced at 40px
                           desktop / 44px touch via min-height
                         - #iq-signout sized to --touch-target-min
                         - #iq-loc-label sized to --touch-target-min
                         Topbar stays at 64px; the larger controls
                         fit within the existing height.
    0.1.0 - 2026-04-27 - Session 3 initial. Layout grid extracted from
                         JQiq 1.9.7 (which was itself ported from DZIQ).
                         Mobile sidebar slide-in pattern adopted from
                         JQiq lines 1696-1845 (the proven DZIQ pattern
                         that all three apps converged on). Topbar
                         flame-accent strip from JQiq is product-
                         specific; the platform provides a sober
                         border-bottom and products can layer their
                         own ::after if they want a brand strip.
================================================================================
*/

/* ============================================================================
   Root grid: topbar full-width on top, sidebar + content below.
   ============================================================================ */

#iq-root {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  grid-template-rows: var(--topbar-h) 1fr;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/* When showing login, root switches from grid to flex centering. */
#iq-root:has(.iq-login-wrap) {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

/*
  The login card.

  The wrap owns the gutter, the box owns the width. Splitting it that
  way means the card never touches the screen edge on a narrow phone -
  a max-width alone would still run edge to edge below 400px, which is
  most of them.

  overflow-y on the wrap because a small landscape phone with the
  keyboard up has less height than the card needs, and a card that
  cannot scroll traps the submit button off screen.
*/
.iq-login-wrap {
  width: 100%;

  /* An explicit height is what makes align-items:center mean anything.
     max-height alone leaves the box the size of the card inside it, so
     the card was being centred within itself and rendered at the top. */
  height: 100vh;
  height: 100dvh;

  padding: 24px 20px;
  overflow-y: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

.iq-login-box {
  width: 100%;
  max-width: 380px;
  padding: 32px 28px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 14px);
  box-shadow: var(--shadow-modal, 0 16px 48px rgba(0, 0, 0, 0.4));
}

.iq-login-box .form-group {
  margin-bottom: 16px;
}

.iq-login-box .form-input {
  width: 100%;
}

.iq-login-box .btn-block {
  width: 100%;
  margin-top: 8px;
}

/* Roomier on a real screen, tighter on a small one. */
@media (min-width: 480px) {
  .iq-login-box {
    padding: 40px 36px;
  }
}

@media (max-width: 360px) {
  .iq-login-wrap {
    padding: 16px 14px;
  }
  .iq-login-box {
    padding: 26px 20px;
  }
}

/* iOS safe area: push content below the status bar when launched
   from home screen. */
@supports (padding-top: env(safe-area-inset-top)) {
  /* No padding-top on the root grid. The topbar spans the inset itself -
     see the coarse block near the end of this file, where row 1 is
     sized to match. Padding here as well double-counts it. */
  .iq-sidebar {
    padding-bottom: env(safe-area-inset-bottom);
  }
  .iq-content {
    padding-bottom: env(safe-area-inset-bottom);
  }
}


/* ============================================================================
   Topbar
   Full-width across the top, contains brand/title on the left and
   user/account controls on the right.
   ============================================================================ */

.iq-topbar {
  grid-column: 1 / -1;
  grid-row: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 0 20px;
  height: var(--topbar-h);
  background: var(--bg-surface);
  border-bottom: 1px solid var(--border);
  z-index: var(--z-topbar);
}

.topbar-left {
  display: flex;
  align-items: center;
  gap: 16px;
  min-width: 0;
}

.topbar-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

#iq-page-title {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#iq-loc-label {
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  cursor: pointer;
  padding: 6px 14px;
  min-height: var(--touch-target-min);
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-base);
  transition: border-color var(--t-fast), background var(--t-fast);
}

#iq-loc-label:hover {
  border-color: var(--accent-bord);
}

/* Sidebar footer -- sign out only. Centered, with breathing room at
   the bottom so the button is not jammed into the corner. The user
   chip was removed: the email added noise and the account is
   single-user. */
.iq-sidebar-footer {
  display: flex;
  justify-content: center;
  padding: 12px 16px 20px;
}

#iq-user-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 12px;
  min-height: var(--touch-target-min);
  border-radius: 999px;
  background: var(--bg-raised);
  border: 1px solid var(--border);
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 600;
}

#iq-signout {
  background: transparent;
  border: 1px solid var(--border-light);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  font-family: var(--font-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 6px 14px;
  min-height: var(--touch-target-min);
  border-radius: var(--radius);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}

#iq-signout:hover {
  color: var(--red-text);
  border-color: var(--red-text);
}


/* ============================================================================
   Sidebar
   ============================================================================ */

.iq-sidebar {
  grid-column: 1;
  grid-row: 2;
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: var(--bg-surface);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  z-index: var(--z-sidebar);
}

#iq-nav {
  display: flex;
  flex-direction: column;
  padding: 12px 0;
  flex: 1;
}

.nav-section {
  padding: 18px 0 4px;
}

/* The rule is what actually separates the groups. Every section after
   the first gets one; a divider above the first section would separate
   nothing from nothing. */
.nav-section + .nav-section {
  margin-top: 6px;
  border-top: 1px solid var(--border);
  padding-top: 20px;
}

.nav-section-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* White. An ACTIVE nav item is accent-coloured, so an accent label
     sitting above it read as another link. White is used by nothing
     else in the drawer - items are --text-secondary - so the label is
     now the brightest thing in its group, which is what a heading
     should be. */
  color: var(--text-primary);
  padding: 0 20px 8px;
}

/* The bar carries the theme colour. var(--accent) is redefined by
   theme.css under each [data-theme] block, so this tracks whatever is
   chosen in Settings - it is never blue by default and never hardcoded
   to anything. Upright and full-height beside the text so it reads as
   a marker rather than a stray underline. */
.nav-section-label::before {
  content: "";
  flex: 0 0 auto;
  width: 3px;
  height: 14px;
  background: var(--accent);
  border-radius: 999px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 20px;
  min-height: var(--touch-target-min);
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast);
  border-left: 3px solid transparent;
  text-decoration: none;
}

.nav-item:hover {
  background: var(--bg-raised);
  color: var(--text-primary);
}

.nav-item.active {
  background: var(--bg-raised);
  color: var(--accent);
  border-left-color: var(--accent);
  font-weight: 600;
}

.nav-item svg {
  flex-shrink: 0;
}


/* ============================================================================
   Content area
   ============================================================================ */

.iq-content {
  grid-column: 2;
  grid-row: 2;
  background: var(--bg-base);
  overflow-y: auto;
  padding: 24px 28px;
}


/* ============================================================================
   Hamburger toggle (mobile only)
   ============================================================================ */

.btn-menu-toggle {
  display: none;
  background: transparent;
  border: 1px solid var(--border-light);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 22px;
  width: 40px;
  height: 40px;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}


/* ============================================================================
   Sidebar overlay (mobile -- tap outside sidebar to close)
   ============================================================================ */

#iq-overlay,
.sidebar-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: var(--z-overlay);
  -webkit-tap-highlight-color: transparent;
}

#iq-overlay.active,
.sidebar-overlay.active {
  display: block;
}


/* ============================================================================
   Init error stub (rendered when /me fails on boot)
   ============================================================================ */

.iq-init-error {
  max-width: 480px;
  margin: 80px auto;
  padding: 32px;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-align: center;
}

.iq-init-error h2 {
  color: var(--red-text);
  margin-bottom: 12px;
}

.iq-init-error p {
  color: var(--text-secondary);
  margin-bottom: 16px;
}


/* ============================================================================
   Mobile breakpoints (touch devices and narrow screens)

   Pattern adopted from the DZIQ/JQiq/RIQ proven approach: collapse the
   sidebar's grid column to zero on touch devices and reposition the
   sidebar as a fixed-position overlay that slides in from the left.
   The hamburger toggle in the topbar shows the sidebar; the
   #iq-overlay backdrop closes it.
   ============================================================================ */

@media (pointer: coarse) {

  :root {
    --topbar-h: 72px;  /* was 64; gives breathing room for 44px controls */
  }

  #iq-root {
    grid-template-columns: 0 1fr;

    /* Row 1 holds .iq-topbar, which in mobile-tabs.css is
       --topbar-h PLUS the top inset, because its background runs behind
       the status bar. Sizing the row at --topbar-h alone leaves the bar
       overflowing it and painting over the top of .iq-content - that is
       what buried the quick-add bar on the Tasks screen. */
    grid-template-rows:
      calc(var(--topbar-h) + env(safe-area-inset-top, 0px)) 1fr;
  }

  .iq-sidebar {
    position: fixed;
    top: env(safe-area-inset-top, 0);
    left: 0;
    height: calc(100% - env(safe-area-inset-top, 0px));
    width: var(--sidebar-w);
    transform: translateX(-100%);
    transition: transform var(--t-medium);
    z-index: var(--z-topbar);
  }

  .iq-sidebar.open {
    transform: translateX(0);
  }

  .btn-menu-toggle {
    display: flex;
  }

  .iq-content {
    padding: 16px;
  }

  /* Hit-target floor bumps for touch */
  .nav-item    { min-height: var(--touch-target-touch); font-size: 15px; }
  #iq-signout  { min-height: var(--touch-target-touch); font-size: 14px; }
  #iq-loc-label{ min-height: var(--touch-target-touch); font-size: 15px; }
  #iq-user-chip{ min-height: var(--touch-target-touch); font-size: 15px; }
  .nav-section-label { font-size: 13px; letter-spacing: 0.14em; }

}


/* Small phone -- compact topbar, single-column content */
@media (max-width: 480px) {

  .iq-topbar {
    padding: 0 12px;
  }

  #iq-page-title {
    font-size: 16px;
  }

  #iq-user-chip {
    display: none;  /* Save space on small phones */
  }

  .iq-content {
    padding: 12px;
  }
}