/* VysyaFamily.com - mobile shell (112, 113, 114).

   PROGRESSIVE LAYER. Loaded AFTER app.css and it deliberately owns almost
   nothing above 760px: every rule that touches an existing desktop selector
   lives inside `@media (max-width:760px)`. The only things declared at all
   widths are BRAND-NEW components (.sheet, .mtabs, .mtop, .tscroll) that no
   desktop page uses unless it opts in - .mtabs/.mtop are display:none until the
   phone breakpoint, and the sheet is invisible until VF.sheet.open() adds .open.

   This file loads before a page's own {% block head %} styles, so anything a
   feature module sets in its own <style> still wins - intentional, a module
   knows its page better than the shell does. Where a shell offset must survive
   that (the globe stage height under the tab bar) the rule carries extra
   specificity on purpose.
*/

/* ============================================================ bottom sheet
   The phone replacement for a desktop modal (112). Inert until .open, so it
   costs nothing on pages that never call VF.sheet. Drag-to-dismiss writes
   --dy rather than the whole transform, which keeps the desktop centring
   translate(-50%,...) intact while a finger is down. */
.sheet-backdrop{position:fixed;inset:0;z-index:900;background:rgba(4,6,16,.64);
  -webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);
  opacity:0;pointer-events:none;transition:opacity .24s ease}
.sheet-backdrop.open{opacity:1;pointer-events:auto}

.sheet{position:fixed;left:0;right:0;bottom:0;z-index:901;
  display:flex;flex-direction:column;max-height:88vh;
  background:linear-gradient(180deg,var(--panel2) 0%,var(--panel) 38%);
  border:1px solid var(--line);border-bottom:0;border-radius:22px 22px 0 0;
  box-shadow:0 -20px 54px rgba(0,0,0,.62);
  padding-bottom:env(safe-area-inset-bottom,0px);
  transform:translateY(calc(100% + 30px));visibility:hidden;will-change:transform;
  /* spring-ish: overshoots a hair on the way up, then snaps flat */
  transition:transform .36s cubic-bezier(.22,1.16,.36,1),visibility 0s linear .36s}
.sheet.open{transform:translateY(var(--dy,0px));visibility:visible;
  transition:transform .36s cubic-bezier(.22,1.16,.36,1),visibility 0s}
.sheet.dragging{transition:none}

.sheet-grip{flex:none;width:44px;height:4px;margin:9px auto 1px;border-radius:4px;
  background:var(--line)}
.sheet-head{flex:none;display:flex;align-items:center;gap:10px;
  padding:6px 14px 10px;border-bottom:1px solid var(--line);
  touch-action:none;cursor:grab;-webkit-user-select:none;user-select:none}
.sheet-head h2{flex:1;min-width:0;font-size:16px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.sheet-x{flex:none;width:36px;height:36px;border-radius:50%;border:1px solid var(--line);
  background:transparent;color:var(--muted);font:400 20px/1 var(--font);cursor:pointer;
  display:flex;align-items:center;justify-content:center;padding:0}
.sheet-x:hover{color:var(--ink);background:var(--panel2)}
.sheet-body{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;
  overscroll-behavior:contain;padding:14px 15px 24px}
.sheet-body>.wrap{padding:0;max-width:100%}
.sheet-body>*:first-child{margin-top:0}
.sheet-loading{color:var(--muted);font-size:13.5px;padding:26px 4px;text-align:center}
body.sheet-lock{position:fixed;left:0;right:0;width:100%;overflow:hidden}

/* Above the phone breakpoint the same API still works, as a centred dialog -
   nothing on a desktop page changes unless a module opens it on purpose. */
@media (min-width:761px){
  .sheet{left:50%;right:auto;bottom:26px;width:min(560px,92vw);
    border-radius:20px;border-bottom:1px solid var(--line);
    transform:translate(-50%,calc(100% + 60px))}
  .sheet.open{transform:translate(-50%,var(--dy,0px))}
  .sheet-head{cursor:default}
}

/* ================================================= wide-table scroll container
   Built by mobile.js around any table too wide for the viewport. The fades are
   pseudo elements on the wrapper so the scroller itself stays a plain box. */
.tscroll{position:relative}
.tscroll-x{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;
  overscroll-behavior-x:contain}
.tscroll-x>table{min-width:100%;width:auto}
.tscroll::before,.tscroll::after{content:"";position:absolute;top:0;bottom:0;width:34px;
  pointer-events:none;opacity:0;transition:opacity .2s ease;z-index:1}
.tscroll::before{left:0;background:linear-gradient(to right,var(--panel),transparent)}
.tscroll::after{right:0;background:linear-gradient(to left,var(--panel),transparent)}
.tscroll[data-fade~="left"]::before{opacity:1}
.tscroll[data-fade~="right"]::after{opacity:1}

/* ============================================================== shell chrome
   Hidden by default so desktop is untouched; the breakpoint block turns them on. */
.mtabs{display:none}
.mtop{display:none}

/* =============================================================== 760 and down */
@media (max-width:760px){

  /* Room for the fixed tab bar under every page, including .full ones. */
  body{padding-bottom:calc(56px + env(safe-area-inset-bottom,0px))}

  /* ---------------------------------------------------- top bar collapses
     brand + search + avatar. The real .topnav stays in the DOM (hidden) so the
     kernel's unread polling keeps working - mobile.js mirrors its badges onto
     the tab bar rather than polling a second time. */
  .topbar{flex-wrap:nowrap;gap:10px;padding:9px 13px}
  .topbar .topnav{display:none}
  .brand{font-size:17px;white-space:nowrap}
  .mtop{display:flex;align-items:center;gap:9px;margin-left:auto}
  .mtop-btn{width:42px;height:42px;flex:none;border-radius:50%;
    border:1px solid var(--line);background:var(--panel);color:var(--ink);
    display:flex;align-items:center;justify-content:center;cursor:pointer;padding:0;
    -webkit-tap-highlight-color:transparent}
  .mtop-btn svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:1.9;
    stroke-linecap:round}
  .mtop-btn:active{background:var(--panel2)}
  .mtop-av{width:42px;height:42px;flex:none;border-radius:50%;text-decoration:none;
    display:flex;align-items:center;justify-content:center;
    font:650 13px var(--font);color:#241903;
    background:linear-gradient(140deg,var(--gold),#f5cd6a);
    box-shadow:0 0 0 1px rgba(240,180,41,.35),0 4px 14px rgba(240,180,41,.22)}
  .mtop-av:hover{text-decoration:none}
  .mtop .btn.small{min-height:38px;white-space:nowrap}

  /* --------------------------------------------------------- the tab bar */
  .mtabs{display:flex;position:fixed;left:0;right:0;bottom:0;z-index:400;
    background:rgba(11,14,28,.93);
    -webkit-backdrop-filter:blur(16px) saturate(1.25);
    backdrop-filter:blur(16px) saturate(1.25);
    border-top:1px solid var(--line);
    box-shadow:0 -8px 26px rgba(0,0,0,.4);
    padding-bottom:env(safe-area-inset-bottom,0px)}
  .mtab{position:relative;flex:1 1 0;min-width:0;min-height:44px;
    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    padding:8px 2px 7px;color:var(--muted);text-decoration:none;
    font:500 10px/1.1 var(--font);letter-spacing:.02em;text-align:center;
    -webkit-tap-highlight-color:transparent;transition:color .18s ease}
  .mtab:hover{text-decoration:none;color:var(--ink)}
  .mtab:active{color:var(--gold)}
  .mtab:focus-visible{outline:2px solid var(--gold);outline-offset:-3px;border-radius:10px}
  .mtab svg{width:22px;height:22px;flex:none;fill:none;stroke:currentColor;
    stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;transition:transform .2s ease}
  .mtab .mtab-label{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .mtab .mtab-face{width:22px;height:22px;flex:none;border-radius:50%;
    display:flex;align-items:center;justify-content:center;
    font:650 9px var(--font);color:#241903;
    background:linear-gradient(140deg,var(--gold),#f5cd6a)}
  .mtab.on{color:var(--gold)}
  .mtab.on svg{transform:translateY(-1px);filter:drop-shadow(0 0 7px rgba(240,180,41,.5))}
  .mtab.on::before{content:"";position:absolute;top:0;left:50%;transform:translateX(-50%);
    width:26px;height:2.5px;border-radius:0 0 3px 3px;background:var(--gold);
    box-shadow:0 0 12px rgba(240,180,41,.85)}
  .mtab-badge{position:absolute;top:3px;left:calc(50% + 6px);min-width:16px;height:16px;
    padding:0 4px;border-radius:9px;background:var(--gold);color:#241903;
    font:650 10px/16px var(--font);text-align:center;
    box-shadow:0 0 0 2px rgba(11,14,28,.9)}

  /* ------------------------------------------------------- layout reflow */
  .wrap{padding:16px 13px 26px;max-width:100%}
  .card{padding:14px;border-radius:12px}
  .grid{gap:12px}
  .row{gap:8px}
  h1{font-size:21px;line-height:1.22}
  h2{font-size:17px}
  p{line-height:1.58}

  /* Every .field-row becomes one column - two 150px halves on a 360px phone
     read as a form someone has to squint at. */
  .field-row{flex-direction:column;gap:0}
  .field-row>div{flex:1 1 auto;min-width:0;width:100%}

  /* 16px input text is what stops iOS Safari zooming the page on focus. */
  input,select,textarea{font-size:16px;padding:11px 12px}
  label{margin:14px 0 5px}
  textarea{min-height:110px}

  /* 44px touch targets everywhere a finger lands. */
  .btn{min-height:44px;padding:11px 16px}
  .btn.small{min-height:38px;padding:9px 13px}

  /* Wide tables scroll inside their own box instead of pushing the page out.
     mobile.js only wraps the ones that actually overflow. */
  table{font-size:13px}
  th,td{padding:8px 9px}
  .tscroll-x>table{white-space:nowrap}
  .tscroll-x>table td .sub{white-space:normal}

  .foot{flex-direction:column;gap:7px;padding:20px 14px 26px;text-align:left}
  .empty{padding:18px 14px}
  .notice{padding:10px 12px}

  /* ------------------------------------------ compact portrait nodes (23/26)
     Anything that does not hard-code a diameter inherits 70px, so the compact
     garland variant reads clearly at phone size. mobile.js scales down the
     nodes that DO carry an inline --p (VF.nodeEl always sets one) before the
     kernel hydrates them. */
  body{--p:70px}

  /* The globe stage sizes itself off the viewport; give back the tab bar.
     Extra specificity because home.html sets the height in its own <style>. */
  body.home #globe-stage{height:calc(100vh - 58px - 56px - env(safe-area-inset-bottom,0px));
    min-height:430px}

  /* The sheet is the full-bleed phone variant. */
  .sheet{max-height:86vh}
  .sheet-body{padding:14px 14px calc(20px + env(safe-area-inset-bottom,0px))}
}

/* Very narrow phones (iPhone SE and friends). */
@media (max-width:380px){
  .mtab{font-size:9.5px;padding:7px 1px 6px}
  .mtab svg{width:20px;height:20px}
  .wrap{padding:14px 11px 22px}
}

/* ============================================================ reduced motion */
@media (prefers-reduced-motion:reduce){
  .sheet,.sheet-backdrop,.tscroll::before,.tscroll::after,.mtab,.mtab svg{
    transition:none!important}
  .mtab.on svg{filter:none;transform:none}
}
