/* =====================================================================
   PRAXIS APP HEADER — the single, global app-header component.

   One definition of the top app bar, consumed by both the record page and
   the workspace so the header is literally the same component everywhere.
   Faithfully carries the record page's styling (the canonical look).

   Scope note: this file owns the header's VISUAL treatment (bar fill, brand,
   search pill, Mazlan pill, avatar, icon buttons) but deliberately does NOT
   set the bar's positioning — each page's shell keeps that (the record page
   uses a relative bar inside a flex column; the workspace uses a fixed bar
   with a .page top margin). Loaded LAST on each page so it is authoritative.
   ===================================================================== */

/* Bar fill + spacing (Praxis). Position/height stay in each page's shell. */
body[data-variant="praxis"] .appbar{
  background:var(--px-page); color:var(--praxis-color-text-primary);
  gap:var(--praxis-space-16); padding:0 var(--praxis-space-16);
}

/* Brand + logo */
.appbar__brand{display:flex;align-items:center;flex-shrink:0;text-decoration:none;}
.appbar__brand:hover{text-decoration:none;}
.appbar__logo-img{height:26px;width:auto;display:block;}
.appbar__logo-img--onlight{display:none;}
.appbar__logo-img--ondark{display:block;}
body[data-variant="praxis"] .appbar__logo-img--onlight{display:block;}
body[data-variant="praxis"] .appbar__logo-img--ondark{display:none;}
body[data-variant="praxis"][data-theme="dark"] .appbar__logo-img--onlight{display:none;}
body[data-variant="praxis"][data-theme="dark"] .appbar__logo-img--ondark{display:block;}

/* Search — Miramar base: white boxed field with module divider + teal button */
/* min(), not a fixed 840: the pill is absolutely positioned and centred on the
   viewport, so nothing stops it running under the Mazlan button. The 1024
   breakpoint was catching the tablet range but the band just above it was
   unguarded — at 1025 the pill overlapped Mazlan by 73px, clearing only at
   ~1200. The same 420px reserve the narrower rules use now applies from the
   top down. */
.appbar__search{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:min(840px, calc(100vw - 420px));margin:0;
  display:flex;align-items:center;height:48px;border-radius:var(--praxis-radius-md);overflow:hidden;background:var(--praxis-color-white);}
.appbar__module{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;width:256px;height:100%;padding:0 12px;
  background:var(--praxis-color-neutral-05);color:var(--praxis-color-text-secondary);font-size:.8125rem;font-weight:600;white-space:nowrap;
  border:0;border-right:1px solid var(--praxis-color-border-default);font-family:inherit;cursor:pointer;}
/* text-overflow applies to the placeholder as well as typed text, so the
   prompt truncates instead of being cut mid-glyph once the pill shrinks. */
.appbar__search input{flex:1;min-width:0;text-overflow:ellipsis;border:0;outline:0;height:100%;padding:0 14px;font-family:inherit;font-size:.875rem;font-weight:600;
  background:transparent;color:var(--praxis-color-text-primary);min-width:0;}
.appbar__search-btn{width:40px;height:100%;border:0;background:var(--praxis-color-interactive-default);color:var(--praxis-color-white);
  display:flex;align-items:center;justify-content:center;cursor:pointer;}
.appbar__search-btn:hover{background:var(--praxis-color-interactive-hover);}
/* Praxis: fully-rounded floating pill; module + magnifier are borderless */
body[data-variant="praxis"] .appbar__search{height:44px;border-radius:var(--praxis-radius-full);overflow:visible;
  background:var(--praxis-color-surface-default);padding:0 6px 0 4px;box-shadow:0 0 0 1px rgba(16,36,58,.08),0 1px 2px rgba(16,36,58,.05);}
/* Dark: give the whole search pill the workspace components' elevation +
   border (the card treatment) instead of a flat ring, and lift the
   placeholder (neutral-40) + magnifier (neutral-20) out of the murk. */
body[data-variant="praxis"][data-theme="dark"] .appbar__search{box-shadow:var(--praxis-elevation-card);}
body[data-variant="praxis"][data-theme="dark"] .appbar__search > input::placeholder{color:var(--praxis-color-neutral-40);}
body[data-variant="praxis"][data-theme="dark"] .appbar__search-btn{color:#c8cfd7;}
body[data-variant="praxis"] .appbar__module{justify-content:flex-start;gap:6px;width:auto;height:56%;padding:0 16px 0 14px;
  background:transparent;border-right:1px solid var(--praxis-color-border-default);}
body[data-variant="praxis"] .appbar__search-btn{background:transparent;color:var(--praxis-color-text-secondary);border-radius:var(--praxis-radius-full);}
body[data-variant="praxis"] .appbar__search-btn:hover{background:transparent;color:var(--praxis-color-text-primary);}

/* Right-side cluster */
/* margin-right adds a 16px inset on top of the bar's 16px padding, so the
   Mazlan trigger + avatar sit 32px in from the page edge on every page. */
.appbar__right{display:flex;align-items:center;gap:var(--praxis-space-8);margin-left:auto;margin-right:var(--praxis-space-16);}
.appbar__ai{position:relative;}

/* Mazlan pill (branded four-dot mark + label) */
.appbar__mazlan{display:inline-flex;align-items:center;gap:var(--praxis-space-8);height:36px;padding:0 var(--praxis-space-12);
  background:rgba(255,255,255,.12);color:var(--praxis-color-text-inverse);border:1px solid rgba(255,255,255,.16);
  border-radius:999px;font-family:inherit;font-size:var(--praxis-type-size-sm);font-weight:600;cursor:pointer;flex-shrink:0;
  transition:background .15s,border-color .15s;}
.appbar__mazlan:hover{background:rgba(255,255,255,.2);}
/* Light neutral pill — same lit-edge surface convention as the nav-rail tools
   and the search pill. The four-dot mark keeps its teal→pink signature (its
   dark-slate dot reads on the light surface, so no white-dot override needed). */
body[data-variant="praxis"] .appbar__mazlan{
  background:var(--px-surface); color:var(--praxis-color-text-secondary); border:0;
  box-shadow:0 0 0 .5px rgba(16,36,58,.06),0 1px 2px rgba(16,36,58,.05);
}
body[data-variant="praxis"] .appbar__mazlan:hover{
  filter:none; color:var(--praxis-color-text-primary);
  box-shadow:0 0 0 .5px rgba(16,36,58,.09),0 2px 6px -1px rgba(16,36,58,.14);
}
body[data-variant="praxis"][data-theme="dark"] .appbar__mazlan{
  background:var(--px-surface-2,#232c3b); color:var(--praxis-color-text-secondary); border:0;
  box-shadow:var(--praxis-elevation-card);
}
body[data-variant="praxis"][data-theme="dark"] .appbar__mazlan:hover{
  background:var(--px-surface-2,#232c3b); color:var(--praxis-color-white);
  box-shadow:0 0 0 .5px rgba(255,255,255,.12),0 6px 18px -6px rgba(0,0,0,.6),inset 0 .5px 0 rgba(255,255,255,.08);
}

/* Avatar */
.appbar__avatar{width:34px;height:34px;border-radius:50%;background:var(--praxis-color-teal-60) center/cover no-repeat;color:var(--praxis-color-white);
  border:2px solid rgba(255,255,255,.35);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.8125rem;overflow:hidden;}
body[data-variant="praxis"] .appbar__avatar{border-color:rgba(16,36,58,.12);}
body[data-variant="praxis"][data-theme="dark"] .appbar__avatar{border-color:rgba(255,255,255,.22);}

/* Icon buttons */
.appbar__iconbtn{width:40px;height:40px;border:0;background:transparent;color:rgba(255,255,255,.85);border-radius:var(--praxis-radius-md);
  display:flex;align-items:center;justify-content:center;transition:background var(--praxis-motion-fast),color var(--praxis-motion-fast);}
.appbar__iconbtn:hover{background:rgba(255,255,255,.12);color:var(--praxis-color-white);}
body[data-variant="praxis"] .appbar__iconbtn{color:var(--praxis-color-text-secondary);}
body[data-variant="praxis"] .appbar__iconbtn:hover{background:rgba(16,36,58,.06);color:var(--praxis-color-text-primary);}
body[data-variant="praxis"][data-theme="dark"] .appbar__iconbtn:hover{background:rgba(255,255,255,.10);}

/* =====================================================================
   RESPONSIVE — app-wide breakpoints (used consistently across the app):
     lg  ≤1024px  tablet landscape / small laptop
     md  ≤768px   tablet portrait / large phone — the bar compresses and the
                  centered search pill stops floating and flows inline
     sm  ≤480px   phone — tightest spacing
   The 840px absolutely-centered search pill is the main thing that must adapt;
   below md it becomes an in-flow flex child that takes the remaining width.
   ===================================================================== */
/* The centred pill is absolutely positioned, so it can't know what sits beside
   it — the reserve is the only thing keeping it off the Mazlan button and the
   avatar. 340px wasn't enough anywhere in this band: 10px of clearance at 950
   and 4px at 834. 420px holds ~45px clear all the way down to 769, where the
   pill goes in-flow and the reserve stops mattering. */
@media (max-width:1024px){
  .appbar__search{ width:min(600px, calc(100vw - 420px)); }
}
/* ---- The magnifier that replaces the pill below md ------------------------
   Hidden by default and only shown inside the ≤768px block, so a bar that never
   narrows never renders it. praxis-appbar-search.js injects the element; a page
   that wants to place it itself authors [data-appbar-search-toggle] and the
   script adopts that instead.

   Sized and painted as .appbar__iconbtn, but NOT by borrowing that class: the
   toggle is injected, and pointing it at another component's class would make
   this behaviour break the next time that component is retuned. Same values,
   own selector. */
.appbar__searchtoggle{
  display:none; width:40px; height:40px; flex-shrink:0;
  align-items:center; justify-content:center;
  border:0; border-radius:var(--praxis-radius-full);
  background:transparent; color:inherit; cursor:pointer;
  font-family:inherit; padding:0;
}
.appbar__searchtoggle:hover{ background:rgba(255,255,255,.12); }
body[data-variant="praxis"] .appbar__searchtoggle{ color:var(--praxis-color-text-secondary); }
body[data-variant="praxis"] .appbar__searchtoggle:hover{
  background:rgba(16,36,58,.06); color:var(--praxis-color-text-primary);
}
body[data-variant="praxis"][data-theme="dark"] .appbar__searchtoggle:hover{
  background:rgba(255,255,255,.10);
}

@media (max-width:768px){
  /* ---- Pill → magnifier + stacked panel ---------------------------------
     The bar has room for ONE of the two search controls at this width, and the
     previous answer was to keep the input and hide the module selector — which
     left the scope unreachable on a phone while still silently filtering. So
     neither stays in the bar: the whole pill moves into a panel under it,
     behind the magnifier, where both controls get a full row.

     top:100% off the same containing block the centred pill already resolves
     against above this breakpoint. Praxis deliberately does NOT set the bar's
     position (each page's shell owns it — see the header of this file), so this
     inherits exactly the assumption the absolutely-centred pill has always
     made, rather than introducing a new one.

     The panel is display:none rather than a height/opacity transition: it
     contains the module selector, whose menu is position:fixed and positioned
     in JS FROM this element, so a collapsed-but-present panel would anchor that
     menu to a zero-height box. */
  .appbar__searchtoggle{ display:flex; }

  .appbar__search{
    display:none;
    position:absolute; left:0; right:0; top:100%; transform:none;
    width:auto; margin:0; z-index:20;
    height:auto; overflow:visible; border-radius:0;
    padding:var(--praxis-space-12) var(--px-gutter, var(--praxis-space-16));
    background:var(--px-page);
    box-shadow:0 1px 2px rgba(16,36,58,.06), 0 12px 24px -12px rgba(16,36,58,.18);
    /* Two rows out of three children, without a wrapper the markup does not
       have: wrap, and let the module selector claim a full basis. Anything the
       host adds beside the input (an Attachments switch, a scope chip) lands on
       the second row with it instead of being positioned by name.
       row-gap only — the input and its button are one joined field, so the
       column gap has to stay 0. */
    flex-wrap:wrap; align-items:center;
    row-gap:var(--praxis-space-8); column-gap:0;
  }
  body[data-variant="praxis"] .appbar__search{
    width:auto; height:auto; border-radius:0; padding:var(--praxis-space-12) var(--px-gutter, var(--praxis-space-16));
    background:var(--px-page); box-shadow:0 1px 2px rgba(16,36,58,.06), 0 12px 24px -12px rgba(16,36,58,.18);
  }
  body[data-appbar-search="open"] .appbar__search{ display:flex; }

  /* Row 1 — the module selector, whichever of the two forms the host used:
     .msel (the typeable scope field) or .appbar__module (the plain button). */
  .appbar__search > .msel,
  .appbar__search > .appbar__module,
  body[data-variant="praxis"] .appbar__search > .msel,
  body[data-variant="praxis"] .appbar__search > .appbar__module{
    flex:0 0 100%; width:100%; height:44px; box-sizing:border-box;
    /* praxis-module-selector.css clamps .msel to max-width:132px at this
       breakpoint (96px at ≤480px) — the old "compact scope chip", sized to share
       a narrow bar with the term input. It owns a full row here, so the clamp has
       to be released explicitly: this selector outranks it and would otherwise
       set a width the max-width silently overrides. */
    max-width:none; min-width:0;
    padding:0 var(--praxis-space-12); justify-content:space-between;
    background:var(--px-surface); color:var(--praxis-color-text-primary);
    border:0; border-radius:var(--praxis-radius-md);
    box-shadow:0 0 0 1px rgba(16,36,58,.08);
  }
  /* The hairline that divided scope from term inside the pill has nothing left
     to divide once they are on separate rows. */
  .appbar__search > .msel::after{ display:none; }

  /* Row 2 — term input and its button, joined into one field. Radii meet at the
     seam so the pair reads as a single control rather than two adjacent ones.

     The edge is a BORDER here, not the `0 0 0 1px` spread ring row 1 uses, and
     each half drops the side it shares with the other. A ring is drawn around
     every element that carries one, so two adjacent rings painted a hairline
     down the middle of a field that is meant to read as ONE — the seam was
     visible on every phone and tablet. A border can be removed per side, so the
     pair gets a single continuous edge and nothing down the middle. The two
     shared corners are already square, so no radius is lost with them.

     box-sizing is declared rather than assumed: praxis-reset.css is optional for
     consumers, and without border-box a 1px border would make these two 46px
     tall in a 44px row. */
  .appbar__search > input{
    flex:1 1 auto; min-width:0; height:44px; box-sizing:border-box;
    padding:0 var(--praxis-space-12);
    background:var(--px-surface); color:var(--praxis-color-text-primary);
    border-radius:var(--praxis-radius-md) 0 0 var(--praxis-radius-md);
    border:1px solid rgba(16,36,58,.08); border-right:0;
    box-shadow:none;
  }
  .appbar__search .appbar__search-btn{
    flex-shrink:0; width:48px; height:44px; box-sizing:border-box;
    border-radius:0 var(--praxis-radius-md) var(--praxis-radius-md) 0;
  }
  body[data-variant="praxis"] .appbar__search .appbar__search-btn{
    border-radius:0 var(--praxis-radius-md) var(--praxis-radius-md) 0;
    background:var(--px-surface);
    border:1px solid rgba(16,36,58,.08); border-left:0;
    box-shadow:none;
  }
  /* Dark: the 1px light-mode edge is invisible on a dark surface, so the fields
     take the shared edge token instead — as a ring on row 1, which still has
     one, and as a border colour on the joined pair. */
  body[data-theme="dark"] .appbar__search > .msel,
  body[data-theme="dark"] .appbar__search > .appbar__module{
    box-shadow:0 0 0 1px var(--px-edge);
  }
  body[data-theme="dark"] .appbar__search > input,
  body[data-theme="dark"] .appbar__search .appbar__search-btn{
    border-color:var(--px-edge);
  }

  /* ---- No suggestion popup inside the panel -----------------------------
     .ss-pop opens on the term input's focus — and opening the panel focuses
     that input, so the single gesture that reveals the search field also buried
     the page under a "Recent searches" list nobody asked for. Above this
     breakpoint the pill is always in the bar and focusing it is a separate,
     deliberate act; here it is not, so the surface is suppressed rather than
     re-timed. The drivers only toggle [hidden], never an inline display, so
     this rule is the whole fix and needs no !important.

     Scoped to the bar's own popup: a page may use .ss-pop elsewhere, and that
     is not this component's business. */
  .appbar__search .ss-pop{ display:none; }

  /* Mazlan pill is too wide for a phone bar — drop it (still reachable via
     the nav rail / profile menu) so the bar keeps room. */
  .appbar__mazlan{ display:none; }
  /* NOTE: the two rules that used to live here — hiding .msel off the Search
     page, and hiding .appbar__right .iconbtn-ghost on it — were both there to
     buy horizontal room for a pill that no longer sits in the bar. Removed
     rather than kept: with the pill behind the magnifier the bar has room for
     the secondary icon buttons again, and hiding the module selector is the
     exact problem this panel exists to fix. */
}
@media (max-width:480px){
  /* Extra squeeze: shorten the page switcher so brand + switcher don't crowd
     out the search field on the narrowest phones. */
  .appswitch__trigger{ max-width:104px; padding:0 4px 0 6px; }
  .appswitch__trigger span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
}
@media (max-width:480px){
  /* Keep the gap squeeze, but NOT the padding: the horizontal inset is the
     shared --px-gutter now, so the bar lines up with the page header and the
     content. (This file loads after praxis-core.css, so an 8px padding here
     would win and reintroduce the mismatch.) */
  body[data-variant="praxis"] .appbar{ gap:8px; }
  .appbar__logo-img{ height:22px; }
  .appbar__avatar{ width:30px; height:30px; }
}
